Revision
16308
Author
anthm
Date
2010-01-14 10:02:46 -0600 (Thu, 14 Jan 2010)

Log Message

switch to conditional broadcast mode on slow kernels

Modified Paths

Diff

Modified: freeswitch/trunk/src/include/private/switch_core_pvt.h (16307 => 16308)


--- freeswitch/trunk/src/include/private/switch_core_pvt.h	2010-01-14 14:39:57 UTC (rev 16307)
+++ freeswitch/trunk/src/include/private/switch_core_pvt.h	2010-01-14 16:02:46 UTC (rev 16308)
@@ -215,6 +215,7 @@
 	char *odbc_pass;
 	uint32_t debug_level;
 	uint32_t runlevel;
+	uint32_t tipping_point;
 };
 
 extern struct switch_runtime runtime;

Modified: freeswitch/trunk/src/include/switch_core.h (16307 => 16308)


--- freeswitch/trunk/src/include/switch_core.h	2010-01-14 14:39:57 UTC (rev 16307)
+++ freeswitch/trunk/src/include/switch_core.h	2010-01-14 16:02:46 UTC (rev 16308)
@@ -1238,6 +1238,8 @@
 SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, const char *timer_name, int interval, int samples,
 													   switch_memory_pool_t *pool);
 
+SWITCH_DECLARE(void) switch_time_calibrate_clock(void);
+
 /*! 
   \brief Wait for one cycle on an existing timer
   \param timer the timer to wait on

Modified: freeswitch/trunk/src/include/switch_types.h (16307 => 16308)


--- freeswitch/trunk/src/include/switch_types.h	2010-01-14 14:39:57 UTC (rev 16307)
+++ freeswitch/trunk/src/include/switch_types.h	2010-01-14 16:02:46 UTC (rev 16308)
@@ -1436,7 +1436,8 @@
 	SCSC_SEND_SIGHUP,
 	SCSC_DEBUG_LEVEL,
 	SCSC_FLUSH_DB_HANDLES,
-	SCSC_SHUTDOWN_NOW
+	SCSC_SHUTDOWN_NOW,
+	SCSC_CALIBRATE_CLOCK
 } switch_session_ctl_t;
 
 typedef enum {

Modified: freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c (16307 => 16308)


--- freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	2010-01-14 14:39:57 UTC (rev 16307)
+++ freeswitch/trunk/src/mod/applications/mod_commands/mod_commands.c	2010-01-14 16:02:46 UTC (rev 16308)
@@ -1470,6 +1470,8 @@
 			arg = 0;
 			switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg);
 			stream->write_function(stream, "+OK\n");
+		} else if (!strcasecmp(argv[0], "calibrate_clock")) {
+			switch_core_session_ctl(SCSC_CALIBRATE_CLOCK, NULL);
 		} else if (!strcasecmp(argv[0], "shutdown")) {
 			switch_session_ctl_t command = SCSC_SHUTDOWN;
 			int x = 0;

Modified: freeswitch/trunk/src/switch_core.c (16307 => 16308)


--- freeswitch/trunk/src/switch_core.c	2010-01-14 14:39:57 UTC (rev 16307)
+++ freeswitch/trunk/src/switch_core.c	2010-01-14 16:02:46 UTC (rev 16308)
@@ -1301,7 +1301,7 @@
 	switch_rtp_init(runtime.memory_pool);
 
 	runtime.running = 1;
-
+	runtime.tipping_point = 1000;
 	runtime.initiated = switch_time_now();
 
 	switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
@@ -1442,6 +1442,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, "tipping-point") && !zstr(val)) {
+					runtime.tipping_point = atoi(val);
 				} else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
 					switch_rtp_set_start_port((switch_port_t) atoi(val));
 				} else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
@@ -1605,6 +1607,9 @@
 	}
 
 	switch (cmd) {
+	case SCSC_CALIBRATE_CLOCK:
+		switch_time_calibrate_clock();
+		break;
 	case SCSC_FLUSH_DB_HANDLES:
 		switch_cache_db_flush_handles();
 		break;

Modified: freeswitch/trunk/src/switch_time.c (16307 => 16308)


--- freeswitch/trunk/src/switch_time.c	2010-01-14 14:39:57 UTC (rev 16307)
+++ freeswitch/trunk/src/switch_time.c	2010-01-14 16:02:46 UTC (rev 16308)
@@ -177,7 +177,7 @@
 }
 
 #define calc_step() if (step > 11) step -= 10; else if (step > 1) step--
-static void calibrate_clock(void)
+SWITCH_DECLARE(void) switch_time_calibrate_clock(void)
 {
 	int x;
 	switch_interval_time_t avg, val = 1000, want = 1000;
@@ -188,15 +188,18 @@
 	clock_getres(CLOCK_MONOTONIC, &ts);
 	if (ts.tv_nsec / 1000 > 1500) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
-						"Timer resolution of %ld microseconds detected!\n"
-						"Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", ts.tv_nsec / 1000);
-		sleep(5);
+						  "Timer resolution of %ld microseconds detected!\n"
+						  "Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", ts.tv_nsec / 1000);
+		do_sleep(5000000);
+		switch_time_set_cond_yield(SWITCH_TRUE);
 		return;
 	}
 #endif
 
+	OFFSET = 0;
+	
 	for (x = 0; x < 500; x++) {
-		avg = average_time(val, 100);
+		avg = average_time(val, 50);
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Test: %ld Average: %ld Step: %d\n", (long)val, (long)avg, step);
 
 		diff = abs((int)(want - avg));
@@ -204,11 +207,8 @@
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
 							  "Abnormally large timer gap %d detected!\n"
 							  "Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", diff);
-#ifdef WIN32
-			Sleep(5*1000);
-#else
-			sleep(5);
-#endif
+			do_sleep(5000000);
+			switch_time_set_cond_yield(SWITCH_TRUE);
 			return;
 		}
 
@@ -220,12 +220,12 @@
 			}
 		} else if (avg > want) {
 			if (under) {calc_step();}
-			under = 0;
+			under = good = 0;
 			val -= step;
 			over++;
 		} else if (avg < want) {
 			if (over) {calc_step();}
-			over = 0;
+			over = good = 0;
 			val += step;
 			under++;
 		}
@@ -261,15 +261,6 @@
 SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable)
 {
 	MATRIX = enable ? 1 : 0;
-	if (MATRIX) {
-		STEP_MS = 1;
-		STEP_MIC = 1000;
-		TICK_PER_SEC = 10000;
-	} else {
-		STEP_MS = 10;
-		STEP_MIC = 10000;
-		TICK_PER_SEC = 1000;
-	}
 	switch_time_sync();
 }
 
@@ -286,6 +277,7 @@
 	if (COND) {
 		MATRIX = 1;
 	}
+	switch_time_sync();
 }
 
 static switch_time_t time_now(int64_t offset)
@@ -498,15 +490,15 @@
 	while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
 		check_roll();
 		
-		if (globals.use_cond_yield == 1) {
-			switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
-			if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
-				switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex);	
-			}
-			switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
+		if (session_manager.session_count > runtime.tipping_point) {
+			os_yield();
 		} else {
-			if (session_manager.session_count > 1000) {
-				os_yield();
+			if (globals.use_cond_yield == 1) {
+				switch_mutex_lock(TIMER_MATRIX[cond_index].mutex);
+				if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
+					switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex);	
+				}
+				switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
 			} else {
 				do_sleep(1000);
 			}
@@ -640,10 +632,10 @@
 				rev_errs = 0;
 			}
 
-			if (session_manager.session_count > 1000) {
+			if (session_manager.session_count > runtime.tipping_point) {
 				os_yield();
 			} else {
-				do_sleep(STEP_MIC);
+				do_sleep(1000);
 			}
 
 			last = ts;
@@ -952,7 +944,7 @@
 	timer_interface->timer_destroy = timer_destroy;
 
 	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
-	calibrate_clock();
+	switch_time_calibrate_clock();
 
 	/* indicate that the module should continue to be loaded */
 	return SWITCH_STATUS_SUCCESS;