[vlc-commits] commit: Revert "Win32: always use the performance timers (fix #3918)" ( =?UTF-8?Q?R=C3=A9mi=20Denis=2DCourmont=20?=)
git at videolan.org
git at videolan.org
Mon Jan 17 17:58:27 CET 2011
vlc/vlc-1.1 | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Mon Jan 17 18:56:12 2011 +0200| [4f6082b6e13f7087f7397f617162fdab0fdb5fb3] | committer: Rémi Denis-Courmont
Revert "Win32: always use the performance timers (fix #3918)"
This reverts commit 6e0595fd66e7fe7b915467449ffcac74db274b03.
> http://git.videolan.org/gitweb.cgi/vlc/vlc-1.1.git/?a=commit;h=4f6082b6e13f7087f7397f617162fdab0fdb5fb3
---
src/misc/mtime.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++++----
1 files changed, 101 insertions(+), 9 deletions(-)
diff --git a/src/misc/mtime.c b/src/misc/mtime.c
index 940505d..b85c7ef 100644
--- a/src/misc/mtime.c
+++ b/src/misc/mtime.c
@@ -221,20 +221,112 @@ mtime_t mdate( void )
/* Convert to microseconds */
res = date / 1000;
-
#elif defined( WIN32 ) || defined( UNDER_CE )
/* We don't need the real date, just the value of a high precision timer */
- LARGE_INTEGER counter, freq;
- if (!QueryPerformanceCounter (&counter)
- || !QueryPerformanceFrequency (&freq))
- abort();
+ static mtime_t freq = INT64_C(-1);
- /* Convert to from (1/freq) to microsecond resolution */
- /* We need to split the division to avoid 63-bits overflow */
- lldiv_t d = lldiv (counter.QuadPart, freq.QuadPart);
+ if( freq == INT64_C(-1) )
+ {
+ /* Extract from the Tcl source code:
+ * (http://www.cs.man.ac.uk/fellowsd-bin/TIP/7.html)
+ *
+ * Some hardware abstraction layers use the CPU clock
+ * in place of the real-time clock as a performance counter
+ * reference. This results in:
+ * - inconsistent results among the processors on
+ * multi-processor systems.
+ * - unpredictable changes in performance counter frequency
+ * on "gearshift" processors such as Transmeta and
+ * SpeedStep.
+ * There seems to be no way to test whether the performance
+ * counter is reliable, but a useful heuristic is that
+ * if its frequency is 1.193182 MHz or 3.579545 MHz, it's
+ * derived from a colorburst crystal and is therefore
+ * the RTC rather than the TSC. If it's anything else, we
+ * presume that the performance counter is unreliable.
+ */
+ LARGE_INTEGER buf;
+
+ freq = ( QueryPerformanceFrequency( &buf ) &&
+ (buf.QuadPart == INT64_C(1193182) || buf.QuadPart == INT64_C(3579545) ) )
+ ? buf.QuadPart : 0;
+
+#if defined( WIN32 )
+ /* on windows 2000, XP and Vista detect if there are two
+ cores there - that makes QueryPerformanceFrequency in
+ any case not trustable?
+ (may also be true, for single cores with adaptive
+ CPU frequency and active power management?)
+ */
+ HINSTANCE h_Kernel32 = LoadLibrary(_T("kernel32.dll"));
+ if(h_Kernel32)
+ {
+ void WINAPI (*pf_GetSystemInfo)(LPSYSTEM_INFO);
+ pf_GetSystemInfo = (void WINAPI (*)(LPSYSTEM_INFO))
+ GetProcAddress(h_Kernel32, _T("GetSystemInfo"));
+ if(pf_GetSystemInfo)
+ {
+ SYSTEM_INFO system_info;
+ pf_GetSystemInfo(&system_info);
+ if(system_info.dwNumberOfProcessors > 1)
+ freq = 0;
+ }
+ FreeLibrary(h_Kernel32);
+ }
+#endif
+ }
- res = (d.quot * 1000000) + ((d.rem * 1000000) / freq.QuadPart);
+ if( freq != 0 )
+ {
+ LARGE_INTEGER counter;
+ QueryPerformanceCounter (&counter);
+
+ /* Convert to from (1/freq) to microsecond resolution */
+ /* We need to split the division to avoid 63-bits overflow */
+ lldiv_t d = lldiv (counter.QuadPart, freq);
+ res = (d.quot * 1000000) + ((d.rem * 1000000) / freq);
+ }
+ else
+ {
+ /* Fallback on timeGetTime() which has a millisecond resolution
+ * (actually, best case is about 5 ms resolution)
+ * timeGetTime() only returns a DWORD thus will wrap after
+ * about 49.7 days so we try to detect the wrapping. */
+
+ static CRITICAL_SECTION date_lock;
+ static mtime_t i_previous_time = INT64_C(-1);
+ static int i_wrap_counts = -1;
+
+ if( i_wrap_counts == -1 )
+ {
+ /* Initialization */
+#if defined( WIN32 )
+ i_previous_time = INT64_C(1000) * timeGetTime();
+#else
+ i_previous_time = INT64_C(1000) * GetTickCount();
+#endif
+ InitializeCriticalSection( &date_lock );
+ i_wrap_counts = 0;
+ }
+
+ EnterCriticalSection( &date_lock );
+#if defined( WIN32 )
+ res = INT64_C(1000) *
+ (i_wrap_counts * INT64_C(0x100000000) + timeGetTime());
+#else
+ res = INT64_C(1000) *
+ (i_wrap_counts * INT64_C(0x100000000) + GetTickCount());
+#endif
+ if( i_previous_time > res )
+ {
+ /* Counter wrapped */
+ i_wrap_counts++;
+ res += INT64_C(0x100000000) * 1000;
+ }
+ i_previous_time = res;
+ LeaveCriticalSection( &date_lock );
+ }
#elif defined(USE_APPLE_MACH)
/* The version that should be used, if it was cancelable */
pthread_once(&mtime_timebase_info_once, mtime_init_timebase);
More information about the vlc-commits
mailing list