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

trade some max call count for more accurate timing in full media situations,…

trade some max call count for more accurate timing in full media situations, hint: use 30ms ptime for drastic reduction in resources

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@16081 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 1e1b0116
...@@ -399,7 +399,7 @@ AC_FUNC_MALLOC ...@@ -399,7 +399,7 @@ AC_FUNC_MALLOC
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_FUNC_STRFTIME AC_FUNC_STRFTIME
AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs]) AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs])
AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups]) AC_CHECK_FUNCS([sched_setscheduler sched_setaffinity setpriority setrlimit setgroups initgroups])
AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp]) AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])
AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])]) AC_CHECK_LIB(rt, clock_gettime, [AC_DEFINE(HAVE_CLOCK_GETTIME, 1, [Define if you have clock_gettime()])])
......
...@@ -1941,6 +1941,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload); ...@@ -1941,6 +1941,7 @@ SWITCH_DECLARE(void) switch_load_network_lists(switch_bool_t reload);
SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token); SWITCH_DECLARE(switch_bool_t) switch_check_network_list_ip_token(const char *ip_str, const char *list_name, const char **token);
#define switch_check_network_list_ip(_ip_str, _list_name) switch_check_network_list_ip_token(_ip_str, _list_name, NULL) #define switch_check_network_list_ip(_ip_str, _list_name) switch_check_network_list_ip_token(_ip_str, _list_name, NULL)
SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable); SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable);
SWITCH_DECLARE(void) switch_time_set_nanosleep(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(uint32_t) switch_core_default_dtmf_duration(uint32_t duration); SWITCH_DECLARE(uint32_t) switch_core_default_dtmf_duration(uint32_t duration);
......
...@@ -1409,8 +1409,10 @@ static void switch_load_core_config(const char *file) ...@@ -1409,8 +1409,10 @@ static void switch_load_core_config(const char *file)
if (tmp > 0) { if (tmp > 0) {
switch_core_default_dtmf_duration((uint32_t) tmp); switch_core_default_dtmf_duration((uint32_t) tmp);
} }
} else if (!strcasecmp(var, "disable-monotonic-timing")) { } else if (!strcasecmp(var, "enable-monotonic-timing")) {
switch_time_set_monotonic(SWITCH_FALSE); switch_time_set_monotonic(switch_true(var));
} else if (!strcasecmp(var, "enable-clock-nanosleep")) {
switch_time_set_nanosleep(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, "rtp-start-port") && !zstr(val)) { } else if (!strcasecmp(var, "rtp-start-port") && !zstr(val)) {
......
...@@ -1281,13 +1281,13 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_ ...@@ -1281,13 +1281,13 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_session_request_uuid(switch_
switch_mutex_unlock(runtime.throttle_mutex); switch_mutex_unlock(runtime.throttle_mutex);
if (sps <= 0) { if (sps <= 0) {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error! %d\n", session_manager.session_count);
UNPROTECT_INTERFACE(endpoint_interface); UNPROTECT_INTERFACE(endpoint_interface);
return NULL; return NULL;
} }
if ((count + 1) > session_manager.session_limit) { if ((count + 1) > session_manager.session_limit) {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit! %d\n", session_manager.session_limit);
UNPROTECT_INTERFACE(endpoint_interface); UNPROTECT_INTERFACE(endpoint_interface);
return NULL; return NULL;
} }
......
...@@ -70,6 +70,7 @@ SWITCH_MODULE_DEFINITION(CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdo ...@@ -70,6 +70,7 @@ SWITCH_MODULE_DEFINITION(CORE_SOFTTIMER_MODULE, softtimer_load, softtimer_shutdo
#define IDLE_SPEED 100 #define IDLE_SPEED 100
#define STEP_MS 1 #define STEP_MS 1
#define STEP_MIC 1000 #define STEP_MIC 1000
#define TICK_PER_SEC 1000
struct timer_private { struct timer_private {
switch_size_t reference; switch_size_t reference;
...@@ -85,6 +86,7 @@ struct timer_matrix { ...@@ -85,6 +86,7 @@ struct timer_matrix {
uint32_t roll; uint32_t roll;
switch_mutex_t *mutex; switch_mutex_t *mutex;
switch_thread_cond_t *cond; switch_thread_cond_t *cond;
switch_thread_rwlock_t *rwlock;
}; };
typedef struct timer_matrix timer_matrix_t; typedef struct timer_matrix timer_matrix_t;
...@@ -92,23 +94,39 @@ static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1]; ...@@ -92,23 +94,39 @@ static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1];
static void do_sleep(switch_interval_time_t t) static void do_sleep(switch_interval_time_t t)
{ {
#if defined(HAVE_CLOCK_NANOSLEEP) || defined(DARWIN)
struct timespec ts;
#endif
#if defined(WIN32) #if defined(WIN32)
if (t < 1000) { if (t < 1000) {
t = 1000; t = 1000;
} }
#endif #endif
#if defined(DARWIN) #if !defined(DARWIN)
struct timespec ts; if (t > 100000) {
apr_sleep(t);
}
#endif
#if defined(HAVE_CLOCK_NANOSLEEP)
ts.tv_sec = t / APR_USEC_PER_SEC;
ts.tv_nsec = ((t % APR_USEC_PER_SEC) * 1000) - 1000000;
clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, NULL);
#elif defined(DARWIN)
ts.tv_sec = t / APR_USEC_PER_SEC; ts.tv_sec = t / APR_USEC_PER_SEC;
ts.tv_nsec = (t % APR_USEC_PER_SEC) * 1000; ts.tv_nsec = (t % APR_USEC_PER_SEC) * 1000;
nanosleep(&ts, NULL); nanosleep(&ts, NULL);
sched_yield();
#else #else
apr_sleep(t); apr_sleep(t);
#endif #endif
#if defined(DARWIN)
sched_yield();
#endif
} }
SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void) SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void)
...@@ -132,6 +150,12 @@ static int MONO = 1; ...@@ -132,6 +150,12 @@ static int MONO = 1;
static int MONO = 0; static int MONO = 0;
#endif #endif
#if defined(HAVE_CLOCK_NANOSLEEP)
static int NANO = 1;
#else
static int NANO = 0;
#endif
SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable) SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
{ {
...@@ -139,6 +163,11 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable) ...@@ -139,6 +163,11 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
switch_time_sync(); switch_time_sync();
} }
SWITCH_DECLARE(void) switch_time_set_nanosleep(switch_bool_t enable)
{
NANO = enable ? 1 : 0;
}
static switch_time_t time_now(int64_t offset) static switch_time_t time_now(int64_t offset)
{ {
switch_time_t now; switch_time_t now;
...@@ -334,17 +363,26 @@ static switch_status_t timer_next(switch_timer_t *timer) ...@@ -334,17 +363,26 @@ 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 (NANO) {
do_sleep(1000 * timer->interval);
continue;
}
if (globals.use_cond_yield == 1) { if (globals.use_cond_yield == 1) {
switch_mutex_lock(TIMER_MATRIX[cond_index].mutex); if (switch_mutex_lock(TIMER_MATRIX[cond_index].mutex) == SWITCH_STATUS_SUCCESS) {
if (TIMER_MATRIX[timer->interval].tick < private_info->reference) { if (TIMER_MATRIX[timer->interval].tick < private_info->reference) {
switch_thread_cond_wait(TIMER_MATRIX[cond_index].cond, TIMER_MATRIX[cond_index].mutex); 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);
} }
switch_mutex_unlock(TIMER_MATRIX[cond_index].mutex);
} else { } else {
do_sleep(1000); do_sleep(1000);
} }
} }
if (globals.RUNNING == 1) { if (globals.RUNNING == 1) {
return SWITCH_STATUS_SUCCESS; return SWITCH_STATUS_SUCCESS;
} }
...@@ -406,6 +444,13 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -406,6 +444,13 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
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;
#ifdef HAVE_SCHED_SETAFFINITY
cpu_set_t set;
CPU_ZERO(&set);
CPU_SET(0, &set);
sched_setaffinity(0, sizeof(set), &set);
#endif
switch_time_sync(); switch_time_sync();
globals.STARTED = globals.RUNNING = 1; globals.STARTED = globals.RUNNING = 1;
...@@ -421,6 +466,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -421,6 +466,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
if (ts == last) { if (ts == last) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Broken MONOTONIC Clock Detected!, Support Disabled.\n");
MONO = 0; MONO = 0;
NANO = 0;
runtime.reference = switch_time_now(); runtime.reference = switch_time_now();
runtime.initiated = runtime.reference; runtime.initiated = runtime.reference;
break; break;
...@@ -435,15 +481,16 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -435,15 +481,16 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
fwd_errs = rev_errs = 0; fwd_errs = rev_errs = 0;
#ifndef DISABLE_1MS_COND #ifndef DISABLE_1MS_COND
switch_mutex_init(&TIMER_MATRIX[1].mutex, SWITCH_MUTEX_NESTED, module_pool); if (!NANO) {
switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool); switch_mutex_init(&TIMER_MATRIX[1].mutex, SWITCH_MUTEX_NESTED, module_pool);
switch_thread_cond_create(&TIMER_MATRIX[1].cond, module_pool);
}
#endif #endif
globals.use_cond_yield = globals.RUNNING == 1; globals.use_cond_yield = globals.RUNNING = 1;
while (globals.RUNNING == 1) { while (globals.RUNNING == 1) {
runtime.reference += STEP_MIC; runtime.reference += STEP_MIC;
while ((ts = time_now(runtime.offset)) < runtime.reference) { while ((ts = time_now(runtime.offset)) < runtime.reference) {
if (ts < last) { if (ts < last) {
if (MONO) { if (MONO) {
...@@ -461,11 +508,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -461,11 +508,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
} else { } else {
rev_errs = 0; rev_errs = 0;
} }
do_sleep(STEP_MIC); do_sleep(STEP_MIC);
last = ts; last = ts;
} }
if (ts > (runtime.reference + too_late)) { if (ts > (runtime.reference + too_late)) {
if (MONO) { if (MONO) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n"); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
...@@ -495,7 +541,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -495,7 +541,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
current_ms += STEP_MS; current_ms += STEP_MS;
tick += STEP_MS; tick += STEP_MS;
if (tick >= 1000) { if (tick >= TICK_PER_SEC) {
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);
} }
...@@ -525,9 +571,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime) ...@@ -525,9 +571,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
if (TIMER_MATRIX[x].count) { if (TIMER_MATRIX[x].count) {
TIMER_MATRIX[x].tick++; TIMER_MATRIX[x].tick++;
#ifdef DISABLE_1MS_COND #ifdef DISABLE_1MS_COND
if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) { if (!NANO) {
switch_thread_cond_broadcast(TIMER_MATRIX[x].cond); if (TIMER_MATRIX[x].mutex && switch_mutex_trylock(TIMER_MATRIX[x].mutex) == SWITCH_STATUS_SUCCESS) {
switch_mutex_unlock(TIMER_MATRIX[x].mutex); switch_thread_cond_broadcast(TIMER_MATRIX[x].cond);
switch_mutex_unlock(TIMER_MATRIX[x].mutex);
}
} }
#endif #endif
if (TIMER_MATRIX[x].tick == MAX_TICK) { if (TIMER_MATRIX[x].tick == MAX_TICK) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论