]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FSCORE-626 Add alternate timing method support for Windows XP and 2003 - must be...
authorJeff Lenk <jeff@jefflenk.com>
Thu, 15 Jul 2010 13:50:45 +0000 (08:50 -0500)
committerJeff Lenk <jeff@jefflenk.com>
Thu, 15 Jul 2010 14:03:14 +0000 (09:03 -0500)
src/include/switch_core.h
src/mod/applications/mod_commands/mod_commands.c
src/switch_time.c

index 3cd9d46d7fb925a5223dd6fdd2fb5a011c911e35..650ffc15fbbfb027d0ba883b26533399a54da63e 100644 (file)
@@ -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
index 800923fcc55b014498d9b08c1aa4c4dc51a81d3b..c7d3df28439b438715c335dd97bd0f8df262fdcd 100644 (file)
@@ -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);
 
index 2d74e6059495604347cad751d434889dcf9218ad..5e93d59261c65738da4c41851fd3970f74b15b3c 100644 (file)
 #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) {