*/
mtime_t mdate( void )
{
-#if defined( HAVE_KERNEL_OS_H )
+#if defined (HAVE_CLOCK_NANOSLEEP)
+ struct timespec ts;
+
+# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
+ /* Try to use POSIX monotonic clock if available */
+ if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
+# endif
+ /* Run-time fallback to real-time clock (always available) */
+ (void)clock_gettime( CLOCK_REALTIME, &ts );
+
+ return ((mtime_t)ts.tv_sec * (mtime_t)1000000)
+ + (mtime_t)(ts.tv_nsec / 1000);
+
+#elif defined( HAVE_KERNEL_OS_H )
return( real_time_clock_usecs() );
#elif defined( WIN32 ) || defined( UNDER_CE )
/* 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( freq == I64C(-1) )
{
* the RTC rather than the TSC. If it's anything else, we
* presume that the performance counter is unreliable.
*/
+ LARGE_INTEGER buf;
- freq = ( QueryPerformanceFrequency( (LARGE_INTEGER *)&freq ) &&
+ freq = ( QueryPerformanceFrequency( &buf ) &&
(freq == I64C(1193182) || freq == I64C(3579545) ) )
- ? freq : 0;
+ ? buf.QuadPart : 0;
}
if( freq != 0 )
{
- /* Microsecond resolution */
- QueryPerformanceCounter( (LARGE_INTEGER *)&usec_time );
- return ( usec_time * 1000000 ) / freq;
+ 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);
+
+ return (d.quot * 1000000)
+ + ((d.rem * 1000000) / freq);
}
else
{
static CRITICAL_SECTION date_lock;
static mtime_t i_previous_time = I64C(-1);
static int i_wrap_counts = -1;
+ mtime_t usec_time;
if( i_wrap_counts == -1 )
{
return usec_time;
}
-
-#elif defined (HAVE_CLOCK_NANOSLEEP)
- struct timespec ts;
-
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
- /* Try to use POSIX monotonic clock if available */
- if( clock_gettime( CLOCK_MONOTONIC, &ts ) )
-# endif
- /* Run-time fallback to real-time clock (always available) */
- (void)clock_gettime( CLOCK_REALTIME, &ts );
-
- return ((mtime_t)ts.tv_sec * (mtime_t)1000000)
- + (mtime_t)(ts.tv_nsec / 1000);
#else
struct timeval tv_date;
*/
void mwait( mtime_t date )
{
-#if defined( HAVE_KERNEL_OS_H )
- mtime_t delay;
-
- delay = date - real_time_clock_usecs();
- if( delay <= 0 )
- {
- return;
- }
- snooze( delay );
-
-#elif defined( WIN32 ) || defined( UNDER_CE )
- mtime_t usec_time, delay;
-
- usec_time = mdate();
- delay = date - usec_time;
- if( delay <= 0 )
- {
- return;
- }
- msleep( delay );
-
-#elif defined (HAVE_CLOCK_NANOSLEEP)
-# if defined (HAVE_TIMER_ABSTIME_THAT_ACTUALLY_WORKS_WELL)
+#if defined (HAVE_CLOCK_NANOSLEEP)
lldiv_t d = lldiv( date, 1000000 );
- struct timespec ts = { d.quot, d.rem };
+ struct timespec ts = { d.quot, d.rem * 1000 };
-# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
+# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
if( clock_nanosleep( CLOCK_MONOTONIC, TIMER_ABSTIME, &ts, NULL ) )
-# endif
- clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL );
-# else
- date -= mdate ();
- if( date <= 0)
- return;
- msleep( date );
# endif
+ clock_nanosleep( CLOCK_REALTIME, TIMER_ABSTIME, &ts, NULL );
#else
- struct timeval tv_date;
- mtime_t delay; /* delay in msec, signed to detect errors */
-
- /* see mdate() about gettimeofday() possible errors */
- gettimeofday( &tv_date, NULL );
-
- /* calculate delay and check if current date is before wished date */
- delay = date - (mtime_t) tv_date.tv_sec * 1000000
- - (mtime_t) tv_date.tv_usec
- - 10000;
-
- /* Linux/i386 has a granularity of 10 ms. It's better to be in advance
- * than to be late. */
- if( delay <= 0 ) /* wished date is now or already passed */
- {
- return;
- }
-
-# if defined( PTH_INIT_IN_PTH_H )
- pth_usleep( delay );
-
-# elif defined( ST_INIT_IN_ST_H )
- st_usleep( delay );
-
-# else
-
-# if defined( HAVE_NANOSLEEP )
- {
- struct timespec ts_delay;
- ts_delay.tv_sec = delay / 1000000;
- ts_delay.tv_nsec = (delay % 1000000) * 1000;
-
- nanosleep( &ts_delay, NULL );
- }
-
-# else
- tv_date.tv_sec = delay / 1000000;
- tv_date.tv_usec = delay % 1000000;
- /* see msleep() about select() errors */
- select( 0, NULL, NULL, NULL, &tv_date );
-# endif
-
-# endif
+ mtime_t delay = date - mdate();
+ if( delay > 0 )
+ msleep( delay );
#endif
}
*/
void msleep( mtime_t delay )
{
-#if defined( HAVE_KERNEL_OS_H )
+#if defined( HAVE_CLOCK_NANOSLEEP )
+ lldiv_t d = lldiv( delay, 1000000 );
+ struct timespec ts = { d.quot, d.rem * 1000 };
+
+# if (_POSIX_MONOTONIC_CLOCK - 0 >= 0)
+ if( clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, NULL ) )
+# endif
+ clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL );
+
+#elif defined( HAVE_KERNEL_OS_H )
snooze( delay );
#elif defined( PTH_INIT_IN_PTH_H )
#elif defined( WIN32 ) || defined( UNDER_CE )
Sleep( (int) (delay / 1000) );
-#elif defined( HAVE_CLOCK_NANOSLEEP )
- lldiv_t d = lldiv( delay, 1000000 );
- struct timespec ts = { d.quot, d.rem * 1000 };
-
-# if (_POSIX_CLOCK_MONOTONIC - 0 >= 0)
- if( clock_nanosleep( CLOCK_MONOTONIC, 0, &ts, NULL ) )
-# endif
- clock_nanosleep( CLOCK_REALTIME, 0, &ts, NULL );
-
#elif defined( HAVE_NANOSLEEP )
struct timespec ts_delay;
* (i.e. when a signal is sent to the thread, or when memory is full), and
* can be ignored. */
select( 0, NULL, NULL, NULL, &tv_delay );
-
#endif
}