mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-06-01 19:20:05 +00:00
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
This commit is contained in:
parent
1e1b011675
commit
f80a9bd02a
@ -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);
|
|||||||
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)
|
|||||||
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_
|
|||||||
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
|
|||||||
#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 {
|
|||||||
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];
|
|||||||
|
|
||||||
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;
|
|||||||
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)
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
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)
|
|||||||
} 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)
|
|||||||
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)
|
|||||||
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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user