mirror of
https://github.com/signalwire/freeswitch.git
synced 2025-04-14 16:15:04 +00:00
FS-3782 --resolve soft timer
This commit is contained in:
parent
8c794acbcc
commit
4276680181
@ -260,6 +260,7 @@ struct switch_runtime {
|
|||||||
uint32_t max_db_handles;
|
uint32_t max_db_handles;
|
||||||
uint32_t db_handle_timeout;
|
uint32_t db_handle_timeout;
|
||||||
int cpu_count;
|
int cpu_count;
|
||||||
|
uint32_t time_sync;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct switch_runtime runtime;
|
extern struct switch_runtime runtime;
|
||||||
|
@ -546,24 +546,19 @@ SWITCH_STANDARD_API(timer_test_function)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer Test: samplecount after init: %d\n", timer.samplecount);
|
switch_core_timer_next(&timer); /* Step timer once before testing results below, to get first timestamp as accurate as possible */
|
||||||
|
|
||||||
/* Step timer once before testing results below, to get first timestamp as accurate as possible */
|
start = then = switch_time_ref();
|
||||||
switch_core_timer_next(&timer);
|
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer Test: samplecount after first step: %d\n", timer.samplecount);
|
|
||||||
|
|
||||||
start = switch_time_ref();
|
|
||||||
for (x = 1; x <= max; x++) {
|
for (x = 1; x <= max; x++) {
|
||||||
then = switch_time_ref();
|
|
||||||
switch_core_timer_next(&timer);
|
switch_core_timer_next(&timer);
|
||||||
now = switch_time_ref();
|
now = switch_time_ref();
|
||||||
diff = (int) (now - then);
|
diff = (int) (now - then);
|
||||||
//stream->write_function(stream, "test %d sleep %ld %d\n", x, mss, diff);
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer Test: %d sleep %d %d\n", x, mss, diff);
|
|
||||||
total += diff;
|
total += diff;
|
||||||
|
then = now;
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Timer Test: %d sleep %d %d\n", x, mss, diff);
|
||||||
}
|
}
|
||||||
end = switch_time_ref();
|
end = then;
|
||||||
|
|
||||||
switch_yield(250000);
|
switch_yield(250000);
|
||||||
|
|
||||||
|
@ -59,9 +59,10 @@
|
|||||||
#define MAX_ELEMENTS 3600
|
#define MAX_ELEMENTS 3600
|
||||||
#define IDLE_SPEED 100
|
#define IDLE_SPEED 100
|
||||||
|
|
||||||
/* In Windows, enable the montonic timer for better timer accuracy on Windows 2003 Server, XP and older */
|
/* In Windows, enable the montonic timer for better timer accuracy,
|
||||||
/* GetSystemTimeAsFileTime does not update on timeBeginPeriod on these OS. */
|
* GetSystemTimeAsFileTime does not update on timeBeginPeriod on these OS.
|
||||||
/* Flag SCF_USE_WIN32_MONOTONIC must be enabled to activate it (start parameter -monotonic-clock) */
|
* Flag SCF_USE_WIN32_MONOTONIC must be enabled to activate it (start parameter -monotonic-clock).
|
||||||
|
*/
|
||||||
|
|
||||||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
||||||
static int MONO = 1;
|
static int MONO = 1;
|
||||||
@ -91,9 +92,12 @@ static int COND = 1;
|
|||||||
static int MATRIX = 1;
|
static int MATRIX = 1;
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
|
static CRITICAL_SECTION timer_section;
|
||||||
static switch_time_t win32_tick_time_since_start = -1;
|
static switch_time_t win32_tick_time_since_start = -1;
|
||||||
static DWORD win32_last_get_time_tick = 0;
|
static DWORD win32_last_get_time_tick = 0;
|
||||||
CRITICAL_SECTION timer_section;
|
|
||||||
|
static uint8_t win32_use_qpc = 0;
|
||||||
|
static uint64_t win32_qpc_freq = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static switch_memory_pool_t *module_pool = NULL;
|
static switch_memory_pool_t *module_pool = NULL;
|
||||||
@ -321,7 +325,7 @@ SWITCH_DECLARE(time_t) switch_epoch_time_now(time_t *t)
|
|||||||
|
|
||||||
SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
|
SWITCH_DECLARE(void) switch_time_set_monotonic(switch_bool_t enable)
|
||||||
{
|
{
|
||||||
#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)
|
#if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32)
|
||||||
MONO = enable ? 1 : 0;
|
MONO = enable ? 1 : 0;
|
||||||
switch_time_sync();
|
switch_time_sync();
|
||||||
#else
|
#else
|
||||||
@ -375,24 +379,32 @@ static switch_time_t time_now(int64_t offset)
|
|||||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||||
now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset;
|
now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset;
|
||||||
#else
|
#else
|
||||||
DWORD tick_now;
|
if (win32_use_qpc) {
|
||||||
DWORD tick_diff;
|
/* Use QueryPerformanceCounter */
|
||||||
|
uint64_t count = 0;
|
||||||
tick_now = timeGetTime();
|
QueryPerformanceCounter((LARGE_INTEGER*)&count);
|
||||||
if (win32_tick_time_since_start != -1) {
|
now = ((count * 1000000) / win32_qpc_freq) + offset;
|
||||||
EnterCriticalSection(&timer_section);
|
|
||||||
/* just add diff (to make it work more than 50 days). */
|
|
||||||
tick_diff = tick_now - win32_last_get_time_tick;
|
|
||||||
win32_tick_time_since_start += tick_diff;
|
|
||||||
|
|
||||||
win32_last_get_time_tick = tick_now;
|
|
||||||
now = (win32_tick_time_since_start * 1000) + offset;
|
|
||||||
LeaveCriticalSection(&timer_section);
|
|
||||||
} else {
|
} else {
|
||||||
/* If someone is calling us before timer is initialized,
|
/* Use good old timeGetTime() */
|
||||||
* return the current tick + offset
|
DWORD tick_now;
|
||||||
*/
|
DWORD tick_diff;
|
||||||
now = (tick_now * 1000) + offset;
|
|
||||||
|
tick_now = timeGetTime();
|
||||||
|
if (win32_tick_time_since_start != -1) {
|
||||||
|
EnterCriticalSection(&timer_section);
|
||||||
|
/* just add diff (to make it work more than 50 days). */
|
||||||
|
tick_diff = tick_now - win32_last_get_time_tick;
|
||||||
|
win32_tick_time_since_start += tick_diff;
|
||||||
|
|
||||||
|
win32_last_get_time_tick = tick_now;
|
||||||
|
now = (win32_tick_time_since_start * 1000) + offset;
|
||||||
|
LeaveCriticalSection(&timer_section);
|
||||||
|
} else {
|
||||||
|
/* If someone is calling us before timer is initialized,
|
||||||
|
* return the current tick + offset
|
||||||
|
*/
|
||||||
|
now = (tick_now * 1000) + offset;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
@ -415,6 +427,8 @@ static switch_time_t last_time = 0;
|
|||||||
|
|
||||||
SWITCH_DECLARE(void) switch_time_sync(void)
|
SWITCH_DECLARE(void) switch_time_sync(void)
|
||||||
{
|
{
|
||||||
|
runtime.time_sync++; /* Indicate that we are syncing time right now */
|
||||||
|
|
||||||
runtime.reference = switch_time_now();
|
runtime.reference = switch_time_now();
|
||||||
|
|
||||||
runtime.offset = runtime.reference - time_now(0);
|
runtime.offset = runtime.reference - time_now(0);
|
||||||
@ -423,6 +437,8 @@ SWITCH_DECLARE(void) switch_time_sync(void)
|
|||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock synchronized to system time.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Clock synchronized to system time.\n");
|
||||||
}
|
}
|
||||||
last_time = runtime.reference;
|
last_time = runtime.reference;
|
||||||
|
|
||||||
|
runtime.time_sync++; /* Indicate that we are finished syncing time */
|
||||||
}
|
}
|
||||||
|
|
||||||
SWITCH_DECLARE(void) switch_micro_sleep(switch_interval_time_t t)
|
SWITCH_DECLARE(void) switch_micro_sleep(switch_interval_time_t t)
|
||||||
@ -546,6 +562,7 @@ static switch_status_t timer_init(switch_timer_t *timer)
|
|||||||
#define check_roll() if (private_info->roll < TIMER_MATRIX[timer->interval].roll) { \
|
#define check_roll() if (private_info->roll < TIMER_MATRIX[timer->interval].roll) { \
|
||||||
private_info->roll++; \
|
private_info->roll++; \
|
||||||
private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick; \
|
private_info->reference = private_info->start = TIMER_MATRIX[timer->interval].tick; \
|
||||||
|
private_info->start--; /* Must have a diff */ \
|
||||||
} \
|
} \
|
||||||
|
|
||||||
|
|
||||||
@ -562,7 +579,7 @@ static switch_status_t timer_step(switch_timer_t *timer)
|
|||||||
samples = timer->samples * (private_info->reference - private_info->start);
|
samples = timer->samples * (private_info->reference - private_info->start);
|
||||||
|
|
||||||
if (samples > UINT32_MAX) {
|
if (samples > UINT32_MAX) {
|
||||||
private_info->start = private_info->reference;
|
private_info->start = private_info->reference - 1; /* Must have a diff */
|
||||||
samples = timer->samples;
|
samples = timer->samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -691,6 +708,55 @@ static switch_status_t timer_destroy(switch_timer_t *timer)
|
|||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void win32_init_timers(void)
|
||||||
|
{
|
||||||
|
#ifdef WIN32
|
||||||
|
OSVERSIONINFOEX version_info; /* Used to fetch current OS version from Windows */
|
||||||
|
|
||||||
|
EnterCriticalSection(&timer_section);
|
||||||
|
|
||||||
|
ZeroMemory(&version_info, sizeof(OSVERSIONINFOEX));
|
||||||
|
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
|
||||||
|
|
||||||
|
/* Check if we should use timeGetTime() (pre-Vista) or QueryPerformanceCounter() (Vista and later) */
|
||||||
|
|
||||||
|
if (GetVersionEx((OSVERSIONINFO*) &version_info)) {
|
||||||
|
if (version_info.dwPlatformId == VER_PLATFORM_WIN32_NT && version_info.dwMajorVersion >= 6) {
|
||||||
|
if (QueryPerformanceFrequency((LARGE_INTEGER*)&win32_qpc_freq) && win32_qpc_freq > 0) {
|
||||||
|
/* At least Vista, and QueryPerformanceFrequency() suceeded, enable qpc */
|
||||||
|
win32_use_qpc = 1;
|
||||||
|
} else {
|
||||||
|
/* At least Vista, but QueryPerformanceFrequency() failed, disable qpc */
|
||||||
|
win32_use_qpc = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Older then Vista, disable qpc */
|
||||||
|
win32_use_qpc = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Unknown version - we want at least Vista, disable qpc */
|
||||||
|
win32_use_qpc = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (win32_use_qpc) {
|
||||||
|
uint64_t count = 0;
|
||||||
|
|
||||||
|
if (!QueryPerformanceCounter((LARGE_INTEGER*)&count) || count == 0) {
|
||||||
|
/* Call to QueryPerformanceCounter() failed, disable qpc again */
|
||||||
|
win32_use_qpc = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!win32_use_qpc) {
|
||||||
|
/* This will enable timeGetTime() instead, qpc init failed */
|
||||||
|
win32_last_get_time_tick = timeGetTime();
|
||||||
|
win32_tick_time_since_start = win32_last_get_time_tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&timer_section);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
||||||
{
|
{
|
||||||
switch_time_t too_late = runtime.microseconds_per_tick * 1000;
|
switch_time_t too_late = runtime.microseconds_per_tick * 1000;
|
||||||
@ -700,6 +766,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
int fwd_errs = 0, rev_errs = 0;
|
int fwd_errs = 0, rev_errs = 0;
|
||||||
int profile_tick = 0;
|
int profile_tick = 0;
|
||||||
int tfd = -1;
|
int tfd = -1;
|
||||||
|
uint32_t time_sync = runtime.time_sync;
|
||||||
|
|
||||||
#ifdef HAVE_TIMERFD_CREATE
|
#ifdef HAVE_TIMERFD_CREATE
|
||||||
int last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
|
int last_MICROSECONDS_PER_TICK = runtime.microseconds_per_tick;
|
||||||
@ -738,6 +805,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
switch_time_sync();
|
switch_time_sync();
|
||||||
|
time_sync = runtime.time_sync;
|
||||||
|
|
||||||
globals.STARTED = globals.RUNNING = 1;
|
globals.STARTED = globals.RUNNING = 1;
|
||||||
switch_mutex_lock(runtime.throttle_mutex);
|
switch_mutex_lock(runtime.throttle_mutex);
|
||||||
@ -775,6 +843,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
|
|
||||||
|
|
||||||
switch_time_sync();
|
switch_time_sync();
|
||||||
|
time_sync = runtime.time_sync;
|
||||||
|
|
||||||
globals.use_cond_yield = COND;
|
globals.use_cond_yield = COND;
|
||||||
globals.RUNNING = 1;
|
globals.RUNNING = 1;
|
||||||
@ -795,8 +864,12 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
while (((ts = time_now(runtime.offset)) + 100) < runtime.reference) {
|
while (((ts = time_now(runtime.offset)) + 100) < runtime.reference) {
|
||||||
if (ts < last) {
|
if (ts < last) {
|
||||||
if (MONO) {
|
if (MONO) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
|
if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
|
||||||
switch_time_sync();
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
|
||||||
|
win32_init_timers(); /* Make sure to reinit timers on WIN32 */
|
||||||
|
switch_time_sync();
|
||||||
|
time_sync = runtime.time_sync;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
int64_t diff = (int64_t) (ts - last);
|
int64_t diff = (int64_t) (ts - last);
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Reverse Clock Skew Detected!\n");
|
||||||
@ -807,9 +880,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
rev_errs++;
|
rev_errs++;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
|
if (!MONO || time_sync == runtime.time_sync) {
|
||||||
"If you see this message many times try setting the param enable-clock-nanosleep to true in switch.conf.xml or consider a nicer machine to run me on. I AM *FREE* afterall.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
|
||||||
|
"If you see this message many times try setting the param enable-clock-nanosleep to true in switch.conf.xml or consider a nicer machine to run me on. I AM *FREE* afterall.\n");
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
rev_errs = 0;
|
rev_errs = 0;
|
||||||
}
|
}
|
||||||
@ -823,7 +897,19 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
r = read(tfd, &exp, sizeof(exp));
|
r = read(tfd, &exp, sizeof(exp));
|
||||||
r++;
|
r++;
|
||||||
} else {
|
} else {
|
||||||
do_sleep(runtime.microseconds_per_tick);
|
switch_time_t timediff = runtime.reference - ts;
|
||||||
|
|
||||||
|
if (runtime.microseconds_per_tick < timediff) {
|
||||||
|
/* Only sleep for runtime.microseconds_per_tick if this value is lower then the actual time diff we need to sleep */
|
||||||
|
do_sleep(runtime.microseconds_per_tick);
|
||||||
|
} else {
|
||||||
|
#ifdef WIN32
|
||||||
|
/* Windows only sleeps in ms precision, try to round the usec value as good as possible */
|
||||||
|
do_sleep((switch_interval_time_t)floor((timediff / 1000.0) + 0.5) * 1000);
|
||||||
|
#else
|
||||||
|
do_sleep(timediff);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -832,13 +918,15 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
|
|
||||||
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");
|
if (time_sync == runtime.time_sync) { /* Only resync if not in the middle of switch_time_sync() already */
|
||||||
switch_time_sync();
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Virtual Migration Detected! Syncing Clock\n");
|
||||||
|
win32_init_timers(); /* Make sure to reinit timers on WIN32 */
|
||||||
|
switch_time_sync();
|
||||||
|
time_sync = runtime.time_sync;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_time_t diff = ts - runtime.reference - runtime.microseconds_per_tick;
|
switch_time_t diff = ts - runtime.reference - runtime.microseconds_per_tick;
|
||||||
#ifndef WIN32
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Forward Clock Skew Detected!\n");
|
||||||
#endif
|
|
||||||
fwd_errs++;
|
fwd_errs++;
|
||||||
runtime.reference = switch_time_now();
|
runtime.reference = switch_time_now();
|
||||||
current_ms = 0;
|
current_ms = 0;
|
||||||
@ -852,6 +940,7 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
if (fwd_errs > 9 || rev_errs > 9) {
|
if (fwd_errs > 9 || rev_errs > 9) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Auto Re-Syncing clock.\n");
|
||||||
switch_time_sync();
|
switch_time_sync();
|
||||||
|
time_sync = runtime.time_sync;
|
||||||
fwd_errs = rev_errs = 0;
|
fwd_errs = rev_errs = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -859,6 +948,10 @@ SWITCH_MODULE_RUNTIME_FUNCTION(softtimer_runtime)
|
|||||||
current_ms += (runtime.microseconds_per_tick / 1000);
|
current_ms += (runtime.microseconds_per_tick / 1000);
|
||||||
tick += (runtime.microseconds_per_tick / 1000);
|
tick += (runtime.microseconds_per_tick / 1000);
|
||||||
|
|
||||||
|
if (time_sync < runtime.time_sync) {
|
||||||
|
time_sync++; /* Only step once for each loop, we want to make sure to keep this thread safe */
|
||||||
|
}
|
||||||
|
|
||||||
if (tick >= (1000000 / runtime.microseconds_per_tick)) {
|
if (tick >= (1000000 / runtime.microseconds_per_tick)) {
|
||||||
if (++profile_tick == 1) {
|
if (++profile_tick == 1) {
|
||||||
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
|
switch_get_system_idle_time(runtime.profile_timer, &runtime.profile_time);
|
||||||
@ -1117,11 +1210,12 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
|
|||||||
switch_timer_interface_t *timer_interface;
|
switch_timer_interface_t *timer_interface;
|
||||||
module_pool = pool;
|
module_pool = pool;
|
||||||
|
|
||||||
#if defined(WIN32)
|
#ifdef WIN32
|
||||||
timeBeginPeriod(1);
|
timeBeginPeriod(1);
|
||||||
|
|
||||||
InitializeCriticalSection(&timer_section);
|
InitializeCriticalSection(&timer_section);
|
||||||
win32_last_get_time_tick = timeGetTime();
|
|
||||||
win32_tick_time_since_start = win32_last_get_time_tick;
|
win32_init_timers(); /* Init timers for Windows, if we should use timeGetTime() or QueryPerformanceCounters() */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memset(&globals, 0, sizeof(globals));
|
memset(&globals, 0, sizeof(globals));
|
||||||
@ -1155,6 +1249,21 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
|
|||||||
switch_clear_flag((&runtime), SCF_CALIBRATE_CLOCK);
|
switch_clear_flag((&runtime), SCF_CALIBRATE_CLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef WIN32
|
||||||
|
if (switch_test_flag((&runtime), SCF_USE_WIN32_MONOTONIC)) {
|
||||||
|
MONO = 1;
|
||||||
|
|
||||||
|
if (win32_use_qpc) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using QueryPerformanceCounter()\n");
|
||||||
|
} else {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Enabled Windows monotonic clock, using timeGetTime()\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No need to calibrate clock in Win32, we will only sleep ms anyway, it's just not accurate enough */
|
||||||
|
switch_clear_flag((&runtime), SCF_CALIBRATE_CLOCK);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (switch_test_flag((&runtime), SCF_CALIBRATE_CLOCK)) {
|
if (switch_test_flag((&runtime), SCF_CALIBRATE_CLOCK)) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Calibrating timer, please wait...\n");
|
||||||
switch_time_calibrate_clock();
|
switch_time_calibrate_clock();
|
||||||
@ -1162,10 +1271,6 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load)
|
|||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Clock calibration disabled.\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_test_flag((&runtime), SCF_USE_WIN32_MONOTONIC)) {
|
|
||||||
MONO = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* indicate that the module should continue to be loaded */
|
/* indicate that the module should continue to be loaded */
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user