From b1ae97466d95ff68abdf8b84216dcecbdb3cbcc8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 3 Jul 2012 17:15:14 -0500 Subject: [PATCH] add enable-use-system-time param to switch.conf.xml use at your own risk, someone with windows could verify it works ok --- src/include/private/switch_core_pvt.h | 2 ++ src/include/switch_core.h | 2 ++ src/switch_core.c | 5 +++- src/switch_time.c | 42 ++++++++++++++++++++++++--- 4 files changed, 46 insertions(+), 5 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index 0005008252..6d36bae008 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -213,6 +213,8 @@ typedef enum { struct switch_runtime { switch_time_t initiated; + switch_time_t mono_initiated; + switch_time_t mono_reference; switch_time_t reference; int64_t offset; switch_event_t *global_vars; diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 179361dc96..d7e899e6e7 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2107,6 +2107,7 @@ SWITCH_DECLARE(void *) switch_loadable_module_create_interface(switch_loadable_m \return the current epoch time in microseconds */ SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void); +SWITCH_DECLARE(switch_time_t) switch_mono_micro_time_now(void); SWITCH_DECLARE(void) switch_core_memory_reclaim(void); SWITCH_DECLARE(void) switch_core_memory_reclaim_events(void); SWITCH_DECLARE(void) switch_core_memory_reclaim_logger(void); @@ -2130,6 +2131,7 @@ 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); +SWITCH_DECLARE(void) switch_time_set_use_system_time(switch_bool_t enable); 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(double) switch_core_min_idle_cpu(double new_limit); diff --git a/src/switch_core.c b/src/switch_core.c index 1ad1c1756e..357f7d09cf 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -1560,6 +1560,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc runtime.running = 1; runtime.initiated = switch_time_now(); + runtime.mono_initiated = switch_mono_micro_time_now(); switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); @@ -1779,6 +1780,8 @@ static void switch_load_core_config(const char *file) if (tmp > 0) { switch_core_default_dtmf_duration((uint32_t) tmp); } + } else if (!strcasecmp(var, "enable-use-system-time")) { + switch_time_set_use_system_time(switch_true(val)); } else if (!strcasecmp(var, "enable-monotonic-timing")) { switch_time_set_monotonic(switch_true(val)); } else if (!strcasecmp(var, "enable-softtimer-timerfd")) { @@ -1990,7 +1993,7 @@ SWITCH_DECLARE(void) switch_core_measure_time(switch_time_t total_ms, switch_cor SWITCH_DECLARE(switch_time_t) switch_core_uptime(void) { - return switch_micro_time_now() - runtime.initiated; + return switch_mono_micro_time_now() - runtime.mono_initiated; } diff --git a/src/switch_time.c b/src/switch_time.c index d4f5454d3b..7cb47822d2 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -70,6 +70,9 @@ static int MONO = 1; static int MONO = 0; #endif + +static int SYSTEM_TIME = 0; + /* clock_nanosleep works badly on some kernels but really well on others. timerfd seems to work well as long as it exists so if you have timerfd we'll also enable clock_nanosleep by default. */ @@ -140,6 +143,8 @@ typedef struct timer_matrix timer_matrix_t; static timer_matrix_t TIMER_MATRIX[MAX_ELEMENTS + 1]; +static switch_time_t time_now(int64_t offset); + SWITCH_DECLARE(void) switch_os_yield(void) { #if defined(WIN32) @@ -313,6 +318,11 @@ SWITCH_DECLARE(switch_time_t) switch_micro_time_now(void) return (globals.RUNNING == 1 && runtime.timestamp) ? runtime.timestamp : switch_time_now(); } +SWITCH_DECLARE(switch_time_t) switch_mono_micro_time_now(void) +{ + return time_now(-1); +} + SWITCH_DECLARE(time_t) switch_epoch_time_now(time_t *t) { @@ -334,6 +344,12 @@ SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable) } +SWITCH_DECLARE(void) switch_time_set_use_system_time(switch_bool_t enable) +{ + SYSTEM_TIME = enable; +} + + SWITCH_DECLARE(void) switch_time_set_timerfd(switch_bool_t enable) { #if defined(HAVE_TIMERFD_CREATE) @@ -376,9 +392,15 @@ static switch_time_t time_now(int64_t offset) if (MONO) { #ifndef WIN32 struct timespec ts; - clock_gettime(CLOCK_MONOTONIC, &ts); + clock_gettime(offset ? CLOCK_MONOTONIC : CLOCK_REALTIME, &ts); + if (offset < 0) offset = 0; now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset; #else + if (offset == 0) { + return switch_time_now(); + } else if (offset < 0) offset = 0; + + if (win32_use_qpc) { /* Use QueryPerformanceCounter */ uint64_t count = 0; @@ -431,10 +453,22 @@ SWITCH_DECLARE(void) switch_time_sync(void) runtime.reference = switch_time_now(); - runtime.offset = runtime.reference - time_now(0); - runtime.reference = time_now(runtime.offset); + if (SYSTEM_TIME) { + runtime.reference = time_now(0); + runtime.mono_reference = time_now(-1); + runtime.offset = 0; + } else { + runtime.offset = runtime.reference - time_now(0); + runtime.reference = time_now(runtime.offset); + } + + if (runtime.reference - last_time > 1000000 || last_time == 0) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock synchronized to system time.\n"); + if (SYSTEM_TIME) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock is already configured to always report system time.\n"); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock synchronized to system time.\n"); + } } last_time = runtime.reference;