Revision
16962
Author
anthm
Date
2010-03-10 14:21:34 -0600 (Wed, 10 Mar 2010)

Log Message

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

Modified Paths

Diff

Modified: freeswitch/trunk/Makefile.am (16961 => 16962)


--- freeswitch/trunk/Makefile.am	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/Makefile.am	2010-03-10 20:21:34 UTC (rev 16962)
@@ -228,6 +228,7 @@
 	src/switch_odbc.c \
 	src/g711.c \
 	src/switch_pcm.c \
+	src/switch_profile.c\
 	libs/stfu/stfu.c \
 	libs/libteletone/src/libteletone_detect.c \
 	libs/libteletone/src/libteletone_generate.c \

Modified: freeswitch/trunk/src/include/private/switch_core_pvt.h (16961 => 16962)


--- freeswitch/trunk/src/include/private/switch_core_pvt.h	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/include/private/switch_core_pvt.h	2010-03-10 20:21:34 UTC (rev 16962)
@@ -31,6 +31,9 @@
  * this file does not exist!!!!
  *
  */
+
+#include "switch_profile.h"
+
 #ifndef WIN32
 #include <switch_private.h>
 #endif
@@ -220,6 +223,9 @@
 	uint32_t runlevel;
 	uint32_t tipping_point;
 	int32_t timer_affinity;
+	switch_profile_timer_t *profile_timer;
+	double profile_time;
+	double min_idle_time;
 };
 
 extern struct switch_runtime runtime;

Modified: freeswitch/trunk/src/include/switch_core.h (16961 => 16962)


--- freeswitch/trunk/src/include/switch_core.h	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/include/switch_core.h	2010-03-10 20:21:34 UTC (rev 16962)
@@ -1901,7 +1901,7 @@
   \param val the command arguement (if needed)
   \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
@@ -1970,6 +1970,8 @@
 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_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(switch_status_t) switch_console_set_complete(const char *string);
 SWITCH_DECLARE(switch_status_t) switch_console_set_alias(const char *string);

Modified: freeswitch/trunk/src/include/switch_types.h (16961 => 16962)


--- freeswitch/trunk/src/include/switch_types.h	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/include/switch_types.h	2010-03-10 20:21:34 UTC (rev 16962)
@@ -1458,7 +1458,8 @@
 	SCSC_SHUTDOWN_NOW,
 	SCSC_CALIBRATE_CLOCK,
 	SCSC_SAVE_HISTORY,
-	SCSC_CRASH
+	SCSC_CRASH,
+	SCSC_MIN_IDLE_CPU
 } switch_session_ctl_t;
 
 typedef enum {

Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c (16961 => 16962)


--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	2010-03-10 20:21:34 UTC (rev 16962)
@@ -1439,6 +1439,7 @@
 	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) 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) {
 		stream->write_function(stream, "</b>\n");
@@ -1535,7 +1536,23 @@
 				arg = atoi(argv[1]);
 			}
 			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")) {
 			if (argc > 1) {
 				arg = atoi(argv[1]);

Modified: freeswitch/trunk/src/switch_core.c (16961 => 16962)


--- freeswitch/trunk/src/switch_core.c	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/switch_core.c	2010-03-10 20:21:34 UTC (rev 16962)
@@ -82,6 +82,7 @@
 		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-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);
 	}
 }
@@ -1442,6 +1443,8 @@
 					switch_time_set_matrix(switch_true(var));
 				} else if (!strcasecmp(var, "max-sessions") && !zstr(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)) {
 					runtime.tipping_point = atoi(val);
 				} else if (!strcasecmp(var, "timer-affinity") && !zstr(val)) {
@@ -1628,8 +1631,10 @@
 }
 
 
-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)) {
 		return -1;
 	}
@@ -1646,10 +1651,10 @@
 		break;
 	case SCSC_SYNC_CLOCK:
 		switch_time_sync();
-		*val = 0;
+		*intval = 0;
 		break;
 	case SCSC_PAUSE_INBOUND:
-		if (*val) {
+		if (*intval) {
 			switch_set_flag((&runtime), SCF_NO_NEW_SESSIONS);
 		} else {
 			switch_clear_flag((&runtime), SCF_NO_NEW_SESSIONS);
@@ -1700,7 +1705,7 @@
 				win_shutdown();
 #endif
 
-				if (*val) {
+				if (*intval) {
 					switch_set_flag((&runtime), SCF_RESTART);
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
 				} else {
@@ -1722,7 +1727,7 @@
 		win_shutdown();
 #endif
 
-		if (*val) {
+		if (*intval) {
 			switch_set_flag((&runtime), SCF_RESTART);
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Restarting\n");
 		} else {
@@ -1734,53 +1739,59 @@
 		runtime.running = 0;
 		break;
 	case SCSC_CHECK_RUNNING:
-		*val = runtime.running;
+		*intval = runtime.running;
 		break;
 	case SCSC_LOGLEVEL:
-		if (*val > -1) {
-			runtime.hard_log_level = *val;
+		if (*intval > -1) {
+			runtime.hard_log_level = *intval;
 		}
 
 		if (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;
 	case SCSC_DEBUG_LEVEL:
-		if (*val > -1) {
-			if (*val > 10)
-				*val = 10;
-			runtime.debug_level = *val;
+		if (*intval > -1) {
+			if (*intval > 10)
+				*intval = 10;
+			runtime.debug_level = *intval;
 		}
-		*val = runtime.debug_level;
+		*intval = runtime.debug_level;
 		break;
+	case SCSC_MIN_IDLE_CPU:
+		{
+			double *dval = (double *) val;
+			*dval = switch_core_min_idle_cpu(*dval);
+		}
+		break;
 	case SCSC_MAX_SESSIONS:
-		*val = switch_core_session_limit(*val);
+		*intval = switch_core_session_limit(*intval);
 		break;
 	case SCSC_LAST_SPS:
-		*val = runtime.sps_last;
+		*intval = runtime.sps_last;
 		break;
 	case SCSC_MAX_DTMF_DURATION:
-		*val = switch_core_max_dtmf_duration(*val);
+		*intval = switch_core_max_dtmf_duration(*intval);
 		break;
 	case SCSC_MIN_DTMF_DURATION:
-		*val = switch_core_min_dtmf_duration(*val);
+		*intval = switch_core_min_dtmf_duration(*intval);
 		break;
 	case SCSC_DEFAULT_DTMF_DURATION:
-		*val = switch_core_default_dtmf_duration(*val);
+		*intval = switch_core_default_dtmf_duration(*intval);
 		break;
 	case SCSC_SPS:
 		switch_mutex_lock(runtime.throttle_mutex);
-		if (*val > 0) {
-			runtime.sps_total = *val;
+		if (*intval > 0) {
+			runtime.sps_total = *intval;
 		}
-		*val = runtime.sps_total;
+		*intval = runtime.sps_total;
 		switch_mutex_unlock(runtime.throttle_mutex);
 		break;
 
 	case SCSC_RECLAIM:
 		switch_core_memory_reclaim_all();
-		*val = 0;
+		*intval = 0;
 		break;
 	}
 

Modified: freeswitch/trunk/src/switch_core_session.c (16961 => 16962)


--- freeswitch/trunk/src/switch_core_session.c	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/switch_core_session.c	2010-03-10 20:21:34 UTC (rev 16962)
@@ -1485,6 +1485,10 @@
 		return NULL;
 	}
 
+	if (runtime.min_idle_time > 0 && runtime.profile_time < runtime.min_idle_time) {
+		return NULL;
+	}
+
 	PROTECT_INTERFACE(endpoint_interface);
 
 	switch_mutex_lock(runtime.throttle_mutex);
@@ -1640,6 +1644,21 @@
 	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)
 {
 	if (new_limit) {

Modified: freeswitch/trunk/src/switch_time.c (16961 => 16962)


--- freeswitch/trunk/src/switch_time.c	2010-03-10 17:04:00 UTC (rev 16961)
+++ freeswitch/trunk/src/switch_time.c	2010-03-10 20:21:34 UTC (rev 16962)
@@ -630,7 +630,11 @@
 	uint32_t x, tick = 0;
 	switch_time_t ts = 0, last = 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
 	if (runtime.timer_affinity > -1) {
 		cpu_set_t set;
@@ -741,6 +745,11 @@
 		tick += STEP_MS;
 
 		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) {
 				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Rate of %d!\n", runtime.sps_total);
 			}
@@ -803,6 +812,8 @@
 	globals.RUNNING = 0;
 	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");
 
 	return SWITCH_STATUS_TERM;