* include/vlc_common.h: fixed the I64C() macro for mingw.
authorGildas Bazin <gbazin@videolan.org>
Thu, 5 Jun 2003 11:52:19 +0000 (11:52 +0000)
committerGildas Bazin <gbazin@videolan.org>
Thu, 5 Jun 2003 11:52:19 +0000 (11:52 +0000)
* src/misc/mtime.c: implemented the heuristic described in http://www.cs.man.ac.uk/fellowsd-bin/TIP/7.html to test whether the win32 performance counter is reliable. That should fix the clock problems that a few users reported on win32.

include/vlc_common.h
src/misc/mtime.c

index 838d584..463b1bb 100644 (file)
@@ -3,7 +3,7 @@
  * Collection of useful common types and macros definitions
  *****************************************************************************
  * Copyright (C) 1998, 1999, 2000 VideoLAN
- * $Id: vlc_common.h,v 1.66 2003/05/27 01:48:50 hartman Exp $
+ * $Id: vlc_common.h,v 1.67 2003/06/05 11:52:19 gbazin Exp $
  *
  * Authors: Samuel Hocevar <sam@via.ecp.fr>
  *          Vincent Seguin <seguin@via.ecp.fr>
@@ -581,7 +581,7 @@ static inline uint64_t U64_AT( void * _p )
 #endif /* defined(WIN32)||defined(UNDER_CE) */
 
 /* 64 bits integer constant suffix */
-#if !defined(WIN32) && !defined(UNDER_CE)
+#if defined( __MINGW32__ ) || (!defined(WIN32) && !defined(UNDER_CE))
 #   define I64C(x)         x##LL
 #else
 #   define I64C(x)         x##i64
index 6dfa582..2f5a87f 100644 (file)
@@ -3,7 +3,7 @@
  * Functions are prototyped in mtime.h.
  *****************************************************************************
  * Copyright (C) 1998-2001 VideoLAN
- * $Id: mtime.c,v 1.35 2002/11/11 14:39:12 sam Exp $
+ * $Id: mtime.c,v 1.36 2003/06/05 11:52:19 gbazin Exp $
  *
  * Authors: Vincent Seguin <seguin@via.ecp.fr>
  *
@@ -96,19 +96,44 @@ mtime_t mdate( void )
     return( real_time_clock_usecs() );
 
 #elif defined( WIN32 ) || defined( UNDER_CE )
-    /* We don't get the real date, just the value of a high precision timer.
-     * this is because the usual time functions have at best only a milisecond
-     * resolution */
-    mtime_t freq, usec_time;
+    /* We don't need the real date, just the value of a high precision timer */
+    static mtime_t freq = I64C(-1);
+    mtime_t usec_time;
 
-    if( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) )
+    if( freq == I64C(-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.
+         */
+
+        freq = ( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) &&
+                 (freq == I64C(1193182) || freq == I64C(3579545) ) )
+               ? freq : 0;
+    }
+
+    if( freq != 0 )
     {
         /* Microsecond resolution */
         QueryPerformanceCounter( (LARGE_INTEGER *)&usec_time );
         return ( usec_time * 1000000 ) / freq;
     }
 
-    /* Milisecond resolution */
+    /* Milisecond resolution (actually, best case is about 10 ms resolution) */
     return 1000 * GetTickCount();
 
 #else