提交 abd11682 authored 作者: Anthony Minessale's avatar Anthony Minessale

switch to conditional broadcast mode on slow kernels

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16308 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 0d2d07d0
...@@ -215,6 +215,7 @@ struct switch_runtime { ...@@ -215,6 +215,7 @@ struct switch_runtime {
char *odbc_pass; char *odbc_pass;
uint32_t debug_level; uint32_t debug_level;
uint32_t runlevel; uint32_t runlevel;
uint32_t tipping_point;
}; };
extern struct switch_runtime runtime; extern struct switch_runtime runtime;
......
...@@ -1238,6 +1238,8 @@ SWITCH_DECLARE(void) switch_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptr ...@@ -1238,6 +1238,8 @@ SWITCH_DECLARE(void) switch_hash_this(_In_ switch_hash_index_t *hi, _Out_opt_ptr
SWITCH_DECLARE(switch_status_t) switch_core_timer_init(switch_timer_t *timer, const char *timer_name, int interval, int samples, 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_memory_pool_t *pool);
SWITCH_DECLARE(void) switch_time_calibrate_clock(void);
/*! /*!
\brief Wait for one cycle on an existing timer \brief Wait for one cycle on an existing timer
\param timer the timer to wait on \param timer the timer to wait on
......
...@@ -1436,7 +1436,8 @@ typedef enum { ...@@ -1436,7 +1436,8 @@ typedef enum {
SCSC_SEND_SIGHUP, SCSC_SEND_SIGHUP,
SCSC_DEBUG_LEVEL, SCSC_DEBUG_LEVEL,
SCSC_FLUSH_DB_HANDLES, SCSC_FLUSH_DB_HANDLES,
SCSC_SHUTDOWN_NOW SCSC_SHUTDOWN_NOW,
SCSC_CALIBRATE_CLOCK
} switch_session_ctl_t; } switch_session_ctl_t;
typedef enum { typedef enum {
......
...@@ -1470,6 +1470,8 @@ SWITCH_STANDARD_API(ctl_function) ...@@ -1470,6 +1470,8 @@ SWITCH_STANDARD_API(ctl_function)
arg = 0; arg = 0;
switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg); switch_core_session_ctl(SCSC_PAUSE_INBOUND, &arg);
stream->write_function(stream, "+OK\n"); 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")) { } else if (!strcasecmp(argv[0], "shutdown")) {
switch_session_ctl_t command = SCSC_SHUTDOWN; switch_session_ctl_t command = SCSC_SHUTDOWN;
int x = 0; int x = 0;
......
...@@ -1301,7 +1301,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc ...@@ -1301,7 +1301,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc
switch_rtp_init(runtime.memory_pool); switch_rtp_init(runtime.memory_pool);
runtime.running = 1; runtime.running = 1;
runtime.tipping_point = 1000;
runtime.initiated = switch_time_now(); 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); switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL);
...@@ -1442,6 +1442,8 @@ static void switch_load_core_config(const char *file) ...@@ -1442,6 +1442,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, "tipping-point") && !zstr(val)) {
runtime.tipping_point = atoi(val);
} else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) { } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
switch_rtp_set_start_port((switch_port_t) atoi(val)); switch_rtp_set_start_port((switch_port_t) atoi(val));
} else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) { } else if (!strcasecmp(var, "rtp-end-port") && !zstr(val)) {
...@@ -1605,6 +1607,9 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_ ...@@ -1605,6 +1607,9 @@ SWITCH_DECLARE(int32_t) switch_core_session_ctl(switch_session_ctl_t cmd, int32_
} }
switch (cmd) { switch (cmd) {
case SCSC_CALIBRATE_CLOCK:
switch_time_calibrate_clock();
break;
case SCSC_FLUSH_DB_HANDLES: case SCSC_FLUSH_DB_HANDLES:
switch_cache_db_flush_handles(); switch_cache_db_flush_handles();
break; break;
......
...@@ -177,7 +177,7 @@ static switch_interval_time_t average_time(switch_interval_time_t t, int reps) ...@@ -177,7 +177,7 @@ static switch_interval_time_t average_time(switch_interval_time_t t, int reps)
} }
#define calc_step() if (step > 11) step -= 10; else if (step > 1) step-- #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; int x;
switch_interval_time_t avg, val = 1000, want = 1000; switch_interval_time_t avg, val = 1000, want = 1000;
...@@ -188,15 +188,18 @@ static void calibrate_clock(void) ...@@ -188,15 +188,18 @@ static void calibrate_clock(void)
clock_getres(CLOCK_MONOTONIC, &ts); clock_getres(CLOCK_MONOTONIC, &ts);
if (ts.tv_nsec / 1000 > 1500) { if (ts.tv_nsec / 1000 > 1500) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Timer resolution of %ld microseconds detected!\n" "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 you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", ts.tv_nsec / 1000);
sleep(5); do_sleep(5000000);
switch_time_set_cond_yield(SWITCH_TRUE);
return; return;
} }
#endif #endif
OFFSET = 0;
for (x = 0; x < 500; x++) { 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); 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)); diff = abs((int)(want - avg));
...@@ -204,11 +207,8 @@ static void calibrate_clock(void) ...@@ -204,11 +207,8 @@ static void calibrate_clock(void)
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
"Abnormally large timer gap %d detected!\n" "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); "Do you have your kernel timer set to higher than 1khz? You may experience audio problems.\n", diff);
#ifdef WIN32 do_sleep(5000000);
Sleep(5*1000); switch_time_set_cond_yield(SWITCH_TRUE);
#else
sleep(5);
#endif
return; return;
} }
...@@ -220,12 +220,12 @@ static void calibrate_clock(void) ...@@ -220,12 +220,12 @@ static void calibrate_clock(void)
} }
} else if (avg > want) { } else if (avg > want) {
if (under) {calc_step();} if (under) {calc_step();}
under = 0; under = good = 0;
val -= step; val -= step;
over++; over++;
} else if (avg < want) { } else if (avg < want) {
if (over) {calc_step();} if (over) {calc_step();}
over = 0; over = good = 0;
val += step; val += step;
under++; under++;
} }
...@@ -261,15 +261,6 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable) ...@@ -261,15 +261,6 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable) SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable)
{ {
MATRIX = enable ? 1 : 0; 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(); switch_time_sync();
} }
...@@ -286,6 +277,7 @@ SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable) ...@@ -286,6 +277,7 @@ SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable)
if (COND) { if (COND) {
MATRIX = 1; MATRIX = 1;
} }
switch_time_sync();
} }
static switch_time_t time_now(int64_t offset) static switch_time_t time_now(int64_t offset)
...@@ -498,15 +490,15 @@ static switch_status_t timer_next(switch_timer_t *timer) ...@@ -498,15 +490,15 @@ static switch_status_t timer_next(switch_timer_t *timer)
while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) { while (globals.RUNNING == 1 && private_info->ready && TIMER_MATRIX[timer->interval].tick < private_info->reference) {
check_roll(); check_roll();
if (globals.use_cond_yield == 1) { if (session_manager.session_count > runtime.tipping_point) {
switch_mutex_lock(TIMER_MATRIX[cond_index].mutex); os_yield();
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 { } else {
if (session_manager.session_count > 1000) { if (globals.use_cond_yield == 1) {
os_yield(); 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 { } else {
do_sleep(1000); do_sleep(1000);
} }
...@@ -640,10 +632,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -640,10 +632,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
rev_errs = 0; rev_errs = 0;
} }
if (session_manager.session_count > 1000) { if (session_manager.session_count > runtime.tipping_point) {
os_yield(); os_yield();
} else { } else {
do_sleep(STEP_MIC); do_sleep(1000);
} }
last = ts; last = ts;
...@@ -952,7 +944,7 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load) ...@@ -952,7 +944,7 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
timer_interface->timer_destroy = timer_destroy; timer_interface->timer_destroy = timer_destroy;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n"); 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 */ /* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论