add fsctl min_idle_cpu and min-idle-cpu feature to refuse calls after the system fallse below a certian percentage of idle cpu

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16962 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Anthony Minessale 2010-03-10 20:21:34 +00:00
parent 869c221f3a
commit b1ddb70cf1
8 changed files with 94 additions and 26 deletions

View File

@ -228,6 +228,7 @@ libfreeswitch_la_SOURCES = \
src/switch_odbc.c \ src/switch_odbc.c \
src/g711.c \ src/g711.c \
src/switch_pcm.c \ src/switch_pcm.c \
src/switch_profile.c\
libs/stfu/stfu.c \ libs/stfu/stfu.c \
libs/libteletone/src/libteletone_detect.c \ libs/libteletone/src/libteletone_detect.c \
libs/libteletone/src/libteletone_generate.c \ libs/libteletone/src/libteletone_generate.c \

View File

@ -31,6 +31,9 @@
* this file does not exist!!!! * this file does not exist!!!!
* *
*/ */
#include "switch_profile.h"
#ifndef WIN32 #ifndef WIN32
#include <switch_private.h> #include <switch_private.h>
#endif #endif
@ -220,6 +223,9 @@ struct switch_runtime {
uint32_t runlevel; uint32_t runlevel;
uint32_t tipping_point; uint32_t tipping_point;
int32_t timer_affinity; int32_t timer_affinity;
switch_profile_timer_t *profile_timer;
double profile_time;
double min_idle_time;
}; };
extern struct switch_runtime runtime; extern struct switch_runtime runtime;

View File

@ -1901,7 +1901,7 @@ SWITCH_DECLARE(switch_time_t) switch_core_uptime(void);
\param val the command arguement (if needed) \param val the command arguement (if needed)
\return 0 on success nonzero on error \return 0 on success nonzero on error
*/ */
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_t *val); SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val);
/*! /*!
\brief Get the output console \brief Get the output console
@ -1970,6 +1970,8 @@ SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable);
SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable); SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable);
SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration); SWITCH_DECLARE(uint32_t) switch_core_min_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration); SWITCH_DECLARE(uint32_t) switch_core_max_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit);
SWITCH_DECLARE(double) switch_core_idle_cpu(void);
SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration); SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration);
SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string); SWITCH_DECLARE(switch_status_t) switch_console_set_complete(const char *string);
SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string); SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string);

View File

@ -1458,7 +1458,8 @@ typedef enum {
SCSC_SHUTDOWN_NOW, SCSC_SHUTDOWN_NOW,
SCSC_CALIBRATE_CLOCK, SCSC_CALIBRATE_CLOCK,
SCSC_SAVE_HISTORY, SCSC_SAVE_HISTORY,
SCSC_CRASH SCSC_CRASH,
SCSC_MIN_IDLE_CPU
} switch_session_ctl_t; } switch_session_ctl_t;
typedef enum { typedef enum {

View File

@ -1439,6 +1439,7 @@ SWITCH_STANDARD_API(status_function)
switch_core_session_ctl(SCSC_SPS, &sps); switch_core_session_ctl(SCSC_SPS, &sps);
stream->write_function(stream, "%d session(s) %d/%d\n", switch_core_session_count(), last_sps, sps); stream->write_function(stream, "%d session(s) %d/%d\n", switch_core_session_count(), last_sps, sps);
stream->write_function(stream, "%d session(s) max\n", switch_core_session_limit(0)); stream->write_function(stream, "%d session(s) max\n", switch_core_session_limit(0));
stream->write_function(stream, "min idle cpu %0.2f/%0.2f\n", switch_core_min_idle_cpu(-1.0), switch_core_idle_cpu());
if (html) { if (html) {
stream->write_function(stream, "</b>\n"); stream->write_function(stream, "</b>\n");
@ -1535,7 +1536,23 @@ SWITCH_STANDARD_API(ctl_function)
arg = atoi(argv[1]); arg = atoi(argv[1]);
} }
switch_core_session_ctl(SCSC_MAX_SESSIONS, &arg); switch_core_session_ctl(SCSC_MAX_SESSIONS, &arg);
stream->write_function(stream, "+OK max sessions: %d\n", arg); stream->write_function(stream, "+OK max sessions: %f\n", arg);
} else if (!strcasecmp(argv[0], "min_idle_cpu")) {
double d = -1;
if (argc > 1) {
d = atof(argv[1]);
}
switch_core_session_ctl(SCSC_MIN_IDLE_CPU, &d);
if (d) {
stream->write_function(stream, "+OK min idle cpu: %0.2f%\n", d);
} else {
stream->write_function(stream, "+OK min idle cpu: DISABLED\n", d);
}
} else if (!strcasecmp(argv[0], "max_dtmf_duration")) { } else if (!strcasecmp(argv[0], "max_dtmf_duration")) {
if (argc > 1) { if (argc > 1) {
arg = atoi(argv[1]); arg = atoi(argv[1]);

View File

@ -82,6 +82,7 @@ static void send_heartbeat(void)
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count()); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Count", "%u", switch_core_session_count());
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Per-Sec", "%u", runtime.sps);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Session-Since-Startup", "%" SWITCH_SIZE_T_FMT, switch_core_session_id() - 1);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Idle-CPU", "%f", switch_core_idle_cpu());
switch_event_fire(&event); switch_event_fire(&event);
} }
} }
@ -1442,6 +1443,8 @@ static void switch_load_core_config(const char *file)
switch_time_set_matrix(switch_true(var)); switch_time_set_matrix(switch_true(var));
} else if (!strcasecmp(var, "max-sessions") && !zstr(val)) { } else if (!strcasecmp(var, "max-sessions") && !zstr(val)) {
switch_core_session_limit(atoi(val)); switch_core_session_limit(atoi(val));
} else if (!strcasecmp(var, "min-idle-cpu") && !zstr(val)) {
switch_core_min_idle_cpu(atof(val));
} else if (!strcasecmp(var, "tipping-point") && !zstr(val)) { } else if (!strcasecmp(var, "tipping-point") && !zstr(val)) {
runtime.tipping_point = atoi(val); runtime.tipping_point = atoi(val);
} else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) { } else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
@ -1628,8 +1631,10 @@ SWITCH_DECLARE(uint32_t) switch_core_debug_level(void)
} }
SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_t *val) SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, void *val)
{ {
int *intval = (int *) val;
if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) { if (switch_test_flag((&runtime), SCF_SHUTTING_DOWN)) {
return -1; return -1;
} }
@ -1646,10 +1651,10 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
break; break;
case SCSC_SYNC_CLOCK: case SCSC_SYNC_CLOCK:
switch_time_sync(); switch_time_sync();
*val = 0; *intval = 0;
break; break;
case SCSC_PAUSE_INBOUND: case SCSC_PAUSE_INBOUND:
if (*val) { if (*intval) {
switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS); switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
} else { } else {
switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS); switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
@ -1700,7 +1705,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
win_shutdown(); win_shutdown();
#endif #endif
if (*val) { if (*intval) {
switch_set_flag((&runtime), SCF_RESTART); switch_set_flag((&runtime), SCF_RESTART);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
} else { } else {
@ -1722,7 +1727,7 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
win_shutdown(); win_shutdown();
#endif #endif
if (*val) { if (*intval) {
switch_set_flag((&runtime), SCF_RESTART); switch_set_flag((&runtime), SCF_RESTART);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
} else { } else {
@ -1734,53 +1739,59 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
runtime.running = 0; runtime.running = 0;
break; break;
case SCSC_CHECK_RUNNING: case SCSC_CHECK_RUNNING:
*val = runtime.running; *intval = runtime.running;
break; break;
case SCSC_LOGLEVEL: case SCSC_LOGLEVEL:
if (*val > -1) { if (*intval > -1) {
runtime.hard_log_level = *val; runtime.hard_log_level = *intval;
} }
if (runtime.hard_log_level > SWITCH_LOG_DEBUG) { if (runtime.hard_log_level > SWITCH_LOG_DEBUG) {
runtime.hard_log_level = SWITCH_LOG_DEBUG; runtime.hard_log_level = SWITCH_LOG_DEBUG;
} }
*val = runtime.hard_log_level; *intval = runtime.hard_log_level;
break; break;
case SCSC_DEBUG_LEVEL: case SCSC_DEBUG_LEVEL:
if (*val > -1) { if (*intval > -1) {
if (*val > 10) if (*intval > 10)
*val = 10; *intval = 10;
runtime.debug_level = *val; runtime.debug_level = *intval;
}
*intval = runtime.debug_level;
break;
case SCSC_MIN_IDLE_CPU:
{
double *dval = (double *) val;
*dval = switch_core_min_idle_cpu(*dval);
} }
*val = runtime.debug_level;
break; break;
case SCSC_MAX_SESSIONS: case SCSC_MAX_SESSIONS:
*val = switch_core_session_limit(*val); *intval = switch_core_session_limit(*intval);
break; break;
case SCSC_LAST_SPS: case SCSC_LAST_SPS:
*val = runtime.sps_last; *intval = runtime.sps_last;
break; break;
case SCSC_MAX_DTMF_DURATION: case SCSC_MAX_DTMF_DURATION:
*val = switch_core_max_dtmf_duration(*val); *intval = switch_core_max_dtmf_duration(*intval);
break; break;
case SCSC_MIN_DTMF_DURATION: case SCSC_MIN_DTMF_DURATION:
*val = switch_core_min_dtmf_duration(*val); *intval = switch_core_min_dtmf_duration(*intval);
break; break;
case SCSC_DEFAULT_DTMF_DURATION: case SCSC_DEFAULT_DTMF_DURATION:
*val = switch_core_default_dtmf_duration(*val); *intval = switch_core_default_dtmf_duration(*intval);
break; break;
case SCSC_SPS: case SCSC_SPS:
switch_mutex_lock(runtime.throttle_mutex); switch_mutex_lock(runtime.throttle_mutex);
if (*val > 0) { if (*intval > 0) {
runtime.sps_total = *val; runtime.sps_total = *intval;
} }
*val = runtime.sps_total; *intval = runtime.sps_total;
switch_mutex_unlock(runtime.throttle_mutex); switch_mutex_unlock(runtime.throttle_mutex);
break; break;
case SCSC_RECLAIM: case SCSC_RECLAIM:
switch_core_memory_reclaim_all(); switch_core_memory_reclaim_all();
*val = 0; *intval = 0;
break; break;
} }

View File

@ -1485,6 +1485,10 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
return NULL; return NULL;
} }
if (runtime.min_idle_time > 0 && runtime.profile_time < runtime.min_idle_time) {
return NULL;
}
PROTECT_INTERFACE(endpoint_interface); PROTECT_INTERFACE(endpoint_interface);
switch_mutex_lock(runtime.throttle_mutex); switch_mutex_lock(runtime.throttle_mutex);
@ -1640,6 +1644,21 @@ SWITCH_DECLARE(uint32_t) switch_core_session_limit(uint32_t new_limit)
return session_manager.session_limit; return session_manager.session_limit;
} }
SWITCH_DECLARE(double) switch_core_min_idle_cpu(double new_limit)
{
if (new_limit >= 0) {
runtime.min_idle_time = new_limit;
}
return runtime.min_idle_time;
}
SWITCH_DECLARE(double) switch_core_idle_cpu(void)
{
return runtime.profile_time;
}
SWITCH_DECLARE(uint32_t) switch_core_sessions_per_second(uint32_t new_limit) SWITCH_DECLARE(uint32_t) switch_core_sessions_per_second(uint32_t new_limit)
{ {
if (new_limit) { if (new_limit) {

View File

@ -630,6 +630,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
uint32_t x, tick = 0; uint32_t x, tick = 0;
switch_time_t ts = 0, last = 0; switch_time_t ts = 0, last = 0;
int fwd_errs = 0, rev_errs = 0; int fwd_errs = 0, rev_errs = 0;
int profile_tick = 0;
runtime.profile_timer = switch_new_profile_timer();
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
#ifdef HAVE_CPU_SET_MACROS #ifdef HAVE_CPU_SET_MACROS
if (runtime.timer_affinity > -1) { if (runtime.timer_affinity > -1) {
@ -741,6 +745,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
tick += STEP_MS; tick += STEP_MS;
if (tick >= TICK_PER_SEC) { if (tick >= TICK_PER_SEC) {
if (++profile_tick == 1) {
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
profile_tick = 0;
}
if (runtime.sps <= 0) { if (runtime.sps <= 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
} }
@ -803,6 +812,8 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
globals.RUNNING = 0; globals.RUNNING = 0;
switch_mutex_unlock(globals.mutex); switch_mutex_unlock(globals.mutex);
switch_delete_profile_timer(&runtime.profile_timer);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Soft timer thread exiting.\n");
return SWITCH_STATUS_TERM; return SWITCH_STATUS_TERM;