From 428b82796705988239c4c7f09dc6a89c22a8e615 Mon Sep 17 00:00:00 2001 From: james Date: Thu, 13 Apr 2006 09:48:11 +0000 Subject: Temporarily backed out time backtrack handling code due to issues on Windows. Rewrote gettimeofday function for Windows to be simpler and more efficient. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@1005 e7ae566f-a301-0410-adde-c780ea21d3b5 --- otime.c | 146 ++++++++++++++++++++++++++++++---------------------------------- 1 file changed, 68 insertions(+), 78 deletions(-) (limited to 'otime.c') diff --git a/otime.c b/otime.c index fbef02d..e172805 100644 --- a/otime.c +++ b/otime.c @@ -36,51 +36,10 @@ time_t now = 0; /* GLOBAL */ -#if TIME_BACKTRACK_PROTECTION - -static time_t now_adj = 0; /* GLOBAL */ - -/* - * Try to filter out time instability caused by the system - * clock backtracking or jumping forward. - */ - -void -update_now (const time_t system_time) -{ - const int threshold = 86400; /* threshold at which to dampen forward jumps */ - time_t real_time = system_time + now_adj; - if (real_time > now) - { - const time_t overshoot = real_time - now - 1; - if (overshoot > threshold && now_adj >= overshoot) - { - now_adj -= overshoot; - real_time -= overshoot; - } - now = real_time; - } - else if (real_time < now) - { - now_adj += (now - real_time); - } -} - #ifdef HAVE_GETTIMEOFDAY time_t now_usec = 0; /* GLOBAL */ -void -update_now_usec (struct timeval *tv) -{ - const time_t last = now; - update_now (tv->tv_sec); - if (now > last || tv->tv_usec > now_usec) - now_usec = tv->tv_usec; -} - -#endif - #endif /* @@ -193,53 +152,84 @@ frequency_limit_event_allowed (struct frequency_limit *f) #ifdef WIN32 -static double counterPerMicrosecond = -1.0; /* GLOBAL */ -static unsigned __int64 frequency = 0; /* GLOBAL */ -static unsigned __int64 timeSecOffset = 0; /* GLOBAL */ -static unsigned __int64 startPerformanceCounter = 0; /* GLOBAL */ +static time_t gtc_base = 0; +static DWORD gtc_last = 0; +static time_t last_sec = 0; +static unsigned int last_msec = 0; +static bool bt_last = false; -/* - * gettimeofday for windows - * - * CounterPerMicrosecond is the number of counts per microsecond. - * Double is required if we have less than 1 counter per microsecond. This has not been tested. - * On a PIII 700, I get about 3.579545. This is guaranteed not to change while the processor is running. - * We really don't need to check for loop detection. On my machine it would take about 59645564 days to loop. - * (2^64) / frequency / 60 / 60 / 24. - * - */ -int -gettimeofday(struct timeval *tv, void *tz) +static void +gettimeofday_calibrate (void) { - unsigned __int64 counter; - - QueryPerformanceCounter((LARGE_INTEGER *) &counter); - - if (counter < startPerformanceCounter || counterPerMicrosecond == -1.0) - { - time_t t; - mutex_lock (L_GETTIMEOFDAY); - - QueryPerformanceFrequency((LARGE_INTEGER *) &frequency); - - counterPerMicrosecond = (double) ((__int64) frequency) / 1000000.0f; + const time_t t = time(NULL); + const DWORD gtc = GetTickCount(); + gtc_base = t - gtc/1000; + gtc_last = gtc; +} - time(&t); - QueryPerformanceCounter((LARGE_INTEGER *) &counter); - startPerformanceCounter = counter; +int +gettimeofday (struct timeval *tv, void *tz) +{ + const DWORD gtc = GetTickCount(); + bool bt = false; + time_t sec; + unsigned int msec; + const int backtrack_hold_seconds = 10; - counter /= frequency; + if (!gtc_base || gtc < gtc_last) + gettimeofday_calibrate (); + gtc_last = gtc; - timeSecOffset = t - counter; + sec = gtc_base + gtc / 1000; + msec = gtc % 1000; - mutex_unlock (L_GETTIMEOFDAY); - QueryPerformanceCounter((LARGE_INTEGER *) &counter); + if (sec == last_sec) + { + if (msec < last_msec) + { + msec = last_msec; + bt = true; + } + } + else if (sec < last_sec) + { + if (sec > last_sec - backtrack_hold_seconds) + { + sec = last_sec; + msec = last_msec; + } + bt = true; } - tv->tv_sec = (counter / frequency) + timeSecOffset; - tv->tv_usec = ((__int64) (((__int64) counter) / counterPerMicrosecond) % 1000000); + tv->tv_sec = last_sec = sec; + tv->tv_usec = (last_msec = msec) * 1000; + + if (bt && !bt_last) + gettimeofday_calibrate (); + bt_last = bt; return 0; } #endif /* WIN32 */ + +#ifdef TIME_TEST +void +time_test (void) +{ + struct timeval tv; + time_t t; + int i; + for (i = 0; i < 10000; ++i) + { + t = time(NULL); + gettimeofday (&tv, NULL); +#if 1 + msg (M_INFO, "t=%u s=%u us=%u", + (unsigned int)t, + (unsigned int)tv.tv_sec, + (unsigned int)tv.tv_usec); +#endif + } +} +#endif -- cgit v1.2.3