From 30d2e7fda2f76c5ec1b89df2df6fc0051f2801e9 Mon Sep 17 00:00:00 2001 From: Jeff Lenk Date: Thu, 15 Jul 2010 08:50:45 -0500 Subject: [PATCH] FSCORE-626 Add alternate timing method support for Windows XP and 2003 - must be conditionally compiled(default is original timing) --- src/include/switch_core.h | 1 + .../applications/mod_commands/mod_commands.c | 12 ++--- src/switch_time.c | 51 +++++++++++++++++-- 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 3cd9d46d7f..650ffc15fb 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1979,6 +1979,7 @@ SWITCH_DECLARE(void) switch_core_memory_reclaim_events(void); SWITCH_DECLARE(void) switch_core_memory_reclaim_logger(void); SWITCH_DECLARE(void) switch_core_memory_reclaim_all(void); SWITCH_DECLARE(void) switch_core_setrlimits(void); +SWITCH_DECLARE(switch_time_t) switch_time_ref(void); SWITCH_DECLARE(void) switch_time_sync(void); /*! \brief Get the current epoch time diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 800923fcc5..c7d3df2843 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -235,9 +235,9 @@ SWITCH_STANDARD_API(time_test_function) } for (x = 1; x <= max; x++) { - then = switch_time_now(); + then = switch_time_ref(); switch_yield(mss); - now = switch_time_now(); + now = switch_time_ref(); diff = (int) (now - then); stream->write_function(stream, "test %d sleep %ld %d\n", x, mss, diff); total += diff; @@ -299,17 +299,17 @@ SWITCH_STANDARD_API(timer_test_function) goto end; } - start = switch_time_now(); + start = switch_time_ref(); for (x = 1; x <= max; x++) { - then = switch_time_now(); + then = switch_time_ref(); switch_core_timer_next(&timer); - now = switch_time_now(); + now = switch_time_ref(); 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; } - end = switch_time_now(); + end = switch_time_ref(); switch_yield(250000); diff --git a/src/switch_time.c b/src/switch_time.c index 2d74e60594..5e93d59261 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -48,7 +48,10 @@ #define MAX_ELEMENTS 3600 #define IDLE_SPEED 100 -#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) +/* For now enable WIN32_MONOTONIC on Windows 2003 Server and Windows XP systems for improved timer support */ +/* GetSystemTimeAsFileTime does not update on timeBeginPeriod on these OS */ +/* we leave the normal timer support as the default for now */ +#if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32_MONOTONIC) static int MONO = 1; #else static int MONO = 0; @@ -67,6 +70,12 @@ static int COND = 1; static int MATRIX = 1; +#ifdef WIN32 +static switch_time_t win32_tick_time_since_start = -1; +static DWORD win32_last_get_time_tick = 0; +CRITICAL_SECTION timer_section; +#endif + #define ONEMS #ifdef ONEMS static int STEP_MS = 1; @@ -174,9 +183,9 @@ static switch_interval_time_t average_time(switch_interval_time_t t, int reps) switch_time_t start, stop, sum = 0; for (x = 0; x < reps; x++) { - start = switch_time_now(); + start = switch_time_ref(); do_sleep(t); - stop = switch_time_now(); + stop = switch_time_ref(); sum += (stop - start); } @@ -335,22 +344,49 @@ static switch_time_t time_now(int64_t offset) { switch_time_t now; -#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) +#if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32_MONOTONIC) if (MONO) { +#ifndef WIN32 struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); now = ts.tv_sec * APR_USEC_PER_SEC + (ts.tv_nsec / 1000) + offset; +#else + DWORD tick_now; + DWORD tick_diff; + + 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 } else { #endif now = switch_time_now(); -#if defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC) +#if (defined(HAVE_CLOCK_GETTIME) && defined(CLOCK_MONOTONIC)) || defined(WIN32_MONOTONIC) } #endif return now; } +SWITCH_DECLARE(switch_time_t) switch_time_ref(void) +{ + return time_now(0); +} + SWITCH_DECLARE(void) switch_time_sync(void) { runtime.reference = switch_time_now(); @@ -999,6 +1035,9 @@ SWITCH_MODULE_LOAD_FUNCTION(softtimer_load) #if defined(WIN32) timeBeginPeriod(1); + InitializeCriticalSection(&timer_section); + win32_last_get_time_tick = timeGetTime(); + win32_tick_time_since_start = win32_last_get_time_tick; #endif memset(&globals, 0, sizeof(globals)); @@ -1054,6 +1093,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(softtimer_shutdown) } #if defined(WIN32) timeEndPeriod(1); + win32_tick_time_since_start = -1; /* we are not initialized anymore */ + DeleteCriticalSection(&timer_section); #endif if (TIMEZONES_LIST.hash) {