* Preamble
*****************************************************************************/
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
#include <vlc/vlc.h>
#include <time.h> /* clock_gettime(), clock_nanosleep() */
#include <assert.h>
#include <errno.h>
-
-#if defined( PTH_INIT_IN_PTH_H ) /* GNU Pth */
-# include <pth.h>
-#endif
-
#ifdef HAVE_UNISTD_H
# include <unistd.h> /* select() */
#endif
#if defined( WIN32 ) || defined( UNDER_CE )
# include <windows.h>
+# include <mmsystem.h>
#endif
+
+#if defined( UNDER_CE )
+# include <windows.h>
+#endif
+
#if defined(HAVE_SYS_TIME_H)
# include <sys/time.h>
#endif
int nanosleep(struct timespec *, struct timespec *);
#endif
+#if !defined (_POSIX_CLOCK_SELECTION)
+# define _POSIX_CLOCK_SELECTION (-1)
+#endif
+
+# if (_POSIX_CLOCK_SELECTION < 0)
+/*
+ * We cannot use the monotonic clock is clock selection is not available,
+ * as it would screw vlc_cond_timedwait() completely. Instead, we have to
+ * stick to the realtime clock. Nevermind it screws everything when ntpdate
+ * warps the wall clock.
+ */
+# undef CLOCK_MONOTONIC
+# define CLOCK_MONOTONIC CLOCK_REALTIME
+#elif !defined (HAVE_CLOCK_NANOSLEEP)
+/* Clock selection without clock in the first place, I don't think so. */
+# error We have quite a situation here! Fix me if it ever happens.
+#endif
+
/**
* Return a date in a readable format
*
*/
char *secstotimestr( char *psz_buffer, int i_seconds )
{
- snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%d:%2.2d:%2.2d",
- (int) (i_seconds / (60 *60)),
- (int) ((i_seconds / 60) % 60),
- (int) (i_seconds % 60) );
+ int i_hours, i_mins;
+ i_mins = i_seconds / 60;
+ i_hours = i_mins / 60 ;
+ if( i_hours )
+ {
+ snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%d:%2.2d:%2.2d",
+ (int) i_hours,
+ (int) (i_mins % 60),
+ (int) (i_seconds % 60) );
+ }
+ else
+ {
+ snprintf( psz_buffer, MSTRTIME_MAX_SIZE, "%2.2d:%2.2d",
+ (int) i_mins ,
+ (int) (i_seconds % 60) );
+ }
return( psz_buffer );
}
static unsigned prec = 0;
static volatile mtime_t cached_time = 0;
-#if defined( HAVE_CLOCK_NANOSLEEP )
-# if (_POSIX_MONOTONIC_CLOCK - 0 < 0)
-# define CLOCK_MONOTONIC CLOCK_REALTIME
-# endif
-#endif
/**
* Return high precision date
*
- * Uses the gettimeofday() function when possible (1 MHz resolution) or the
- * ftime() function (1 kHz resolution).
+ * Use a 1 MHz clock when possible, or 1 kHz
+ *
+ * Beware ! It doesn't reflect the actual date (since epoch), but can be the machine's uptime or anything (when monotonic clock is used)
*/
mtime_t mdate( void )
{
freq = ( QueryPerformanceFrequency( &buf ) &&
(buf.QuadPart == I64C(1193182) || buf.QuadPart == I64C(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
}
if( freq != 0 )
}
else
{
- /* Fallback on GetTickCount() which has a milisecond resolution
- * (actually, best case is about 10 ms resolution)
- * GetTickCount() only returns a DWORD thus will wrap after
+ /* Fallback on timeGetTime() which has a milisecond 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;
if( i_wrap_counts == -1 )
{
/* Initialization */
+#if defined( WIN32 )
+ i_previous_time = I64C(1000) * timeGetTime();
+#else
i_previous_time = I64C(1000) * GetTickCount();
+#endif
InitializeCriticalSection( &date_lock );
i_wrap_counts = 0;
}
EnterCriticalSection( &date_lock );
+#if defined( WIN32 )
+ res = I64C(1000) *
+ (i_wrap_counts * I64C(0x100000000) + timeGetTime());
+#else
res = I64C(1000) *
(i_wrap_counts * I64C(0x100000000) + GetTickCount());
+#endif
if( i_previous_time > res )
{
/* Counter wrapped */
{
mtime_t earlier = cached_time;
-#if defined( HAVE_CLOCK_NANOSLEEP )
+#if defined( HAVE_CLOCK_NANOSLEEP )
lldiv_t d = lldiv( delay, 1000000 );
struct timespec ts = { d.quot, d.rem * 1000 };
#elif defined( HAVE_KERNEL_OS_H )
snooze( delay );
-#elif defined( PTH_INIT_IN_PTH_H )
- pth_usleep( delay );
-
-#elif defined( ST_INIT_IN_ST_H )
- st_usleep( delay );
-
#elif defined( WIN32 ) || defined( UNDER_CE )
- Sleep( (int) (delay / 1000) );
+ Sleep( (DWORD) (delay / 1000) );
#elif defined( HAVE_NANOSLEEP )
struct timespec ts_delay;