add timerfd support to the core for now you must enable it in switch.conf.xml with the param enable-softtimer-timerfd=true later if it proves to work well we can make it on by default, please test if you have a new kernel that supports this option kernel >= 2.6.25 and libc >= 2.8

This commit is contained in:
Anthony Minessale 2011-03-21 20:49:39 -05:00
parent e4e879affb
commit 10174ea6d5
4 changed files with 64 additions and 13 deletions

View File

@ -461,7 +461,7 @@ AC_PROG_GCC_TRADITIONAL
AC_FUNC_MALLOC
AC_TYPE_SIGNAL
AC_FUNC_STRFTIME
AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs])
AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create])
AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups])
AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp])

View File

@ -2050,6 +2050,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);
#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_timerfd(switch_bool_t enable);
SWITCH_DECLARE(void) switch_time_set_nanosleep(switch_bool_t enable);
SWITCH_DECLARE(void) switch_time_set_matrix(switch_bool_t enable);
SWITCH_DECLARE(void) switch_time_set_cond_yield(switch_bool_t enable);

View File

@ -1635,6 +1635,8 @@ static void switch_load_core_config(const char *file)
}
} else if (!strcasecmp(var, "enable-monotonic-timing")) {
switch_time_set_monotonic(switch_true(var));
} else if (!strcasecmp(var, "enable-softtimer-timerfd")) {
switch_time_set_timerfd(switch_true(var));
} else if (!strcasecmp(var, "enable-clock-nanosleep")) {
switch_time_set_nanosleep(switch_true(var));
} else if (!strcasecmp(var, "enable-cond-yield")) {

View File

@ -34,6 +34,9 @@
#include <switch.h>
#include <stdio.h>
#include "private/switch_core_pvt.h"
#ifdef HAVE_TIMERFD_CREATE
#include <sys/timerfd.h>
#endif
//#if defined(DARWIN)
#define DISABLE_1MS_COND
@ -58,6 +61,13 @@ static int MONO = 1;
static int MONO = 0;
#endif
#if defined(HAVE_TIMERFD_CREATE)
// We'll default this to 1 after we have had some positive feedback that it works well
static int TFD = 0;
#else
static int TFD = 0;
#endif
static int NANO = 0;
static int OFFSET = 0;
@ -72,18 +82,10 @@ static DWORD win32_last_get_time_tick = 0;
CRITICAL_SECTION timer_section;
#endif
#define ONEMS
#ifdef ONEMS
static int STEP_MS = 1;
static int STEP_MIC = 1000;
static uint32_t TICK_PER_SEC = 1000;
static int MS_PER_TICK = 10;
#else
static int STEP_MS = 10;
static int STEP_MIC = 10000;
static uint32_t TICK_PER_SEC = 1000;
static int MS_PER_TICK = 10;
#endif
static switch_memory_pool_t *module_pool = NULL;
@ -310,8 +312,23 @@ SWITCH_DECLARE(time_t) switch_epoch_time_now(time_t *t)
SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
{
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
MONO = enable ? 1 : 0;
switch_time_sync();
#else
MONO = 0;
#endif
}
SWITCH_DECLARE(void) switch_time_set_timerfd(switch_bool_t enable)
{
#if defined(HAVE_TIMERFD_CREATE)
TFD = enable ? 1 : 0;
switch_time_sync();
#else
TFD = 0;
#endif
}
@ -487,9 +504,6 @@ static switch_status_t timer_init(switch_timer_t *timer)
if (timer->interval > 0 && timer->interval < MS_PER_TICK) {
MS_PER_TICK = timer->interval;
STEP_MS = 1;
STEP_MIC = 1000;
TICK_PER_SEC = 10000;
switch_time_sync();
}
@ -662,6 +676,29 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
switch_time_t ts = 0, last = 0;
int fwd_errs = 0, rev_errs = 0;
int profile_tick = 0;
int tfd = -1;
#ifdef HAVE_TIMERFD_CREATE
struct itimerspec spec = { { 0 } };
if (MONO && TFD) {
tfd = timerfd_create(CLOCK_MONOTONIC, 0);
if (tfd > -1) {
spec.it_interval.tv_sec = 0;
spec.it_interval.tv_nsec = 1000000;
spec.it_value.tv_sec = spec.it_interval.tv_sec;
spec.it_value.tv_nsec = spec.it_interval.tv_nsec;
if (timerfd_settime(tfd, TFD_TIMER_ABSTIME, &spec, NULL)) {
close(tfd);
tfd = -1;
}
}
}
#else
tfd = -1;
#endif
runtime.profile_timer = switch_new_profile_timer();
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
@ -740,7 +777,13 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
if (globals.timer_count >= runtime.tipping_point) {
os_yield();
} else {
do_sleep(1000);
if (tfd > -1 && globals.RUNNING == 1) {
uint64_t exp;
int r;
r = read(tfd, &exp, sizeof(exp));
} else {
do_sleep(1000);
}
}
last = ts;
@ -838,6 +881,11 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
}
}
if (tfd > -1) {
close(tfd);
tfd = -1;
}
switch_mutex_lock(globals.mutex);
globals.RUNNING = 0;