\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);
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);
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);
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")) {
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;
}
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.
*/
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)
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)
{
}
+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)
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;
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;