Some timer-related improvements for POSIX

* idSysSignal::Wait should now handle timeouts > 1s better (or at all)
* Use clock_gettime for Sys_Milliseconds()
* Use CLOCK_MONOTONIC_RAW (and CLOCK_MONOTONIC as fallback if
  that's not available) for Sys_Milliseconds() and Sys_Microseconds()
  CLOCK_MONOTONIC can behave strange when NTP is used
* Small fixes in Sys_Microseconds(): use 64bit int to store time
  (like return type...), divide by 1000 (not 1000000) for nsec=>musec
This commit is contained in:
Daniel Gibson 2013-03-04 00:47:14 +01:00
parent a203345897
commit 9aa63e4074
2 changed files with 26 additions and 26 deletions

View file

@ -266,9 +266,11 @@ bool idSysSignal::Wait( int timeout )
{ {
timespec ts; timespec ts;
clock_gettime( CLOCK_REALTIME, &ts ); clock_gettime( CLOCK_REALTIME, &ts );
// DG: handle timeouts > 1s better
ts.tv_nsec += ( timeout * 1000000 ); int64 t = timeout * 1000000;
ts.tv_nsec += t % 1000000000;
ts.tv_sec += t / 1000000000;
// DG end
result = pthread_cond_timedwait( &cond, &mutex, &ts ); result = pthread_cond_timedwait( &cond, &mutex, &ts );
assert( result == 0 || ( timeout != idSysSignal::WAIT_INFINITE && result == ETIMEDOUT ) ); assert( result == 0 || ( timeout != idSysSignal::WAIT_INFINITE && result == ETIMEDOUT ) );

View file

@ -182,6 +182,14 @@ Sys_Milliseconds
timeval:tv_sec is an int: timeval:tv_sec is an int:
assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038 assuming this wraps every 0x7fffffff - ~68 years since the Epoch (1970) - we're safe till 2038
using unsigned long data type to work right with Sys_XTimeToSysTime */ using unsigned long data type to work right with Sys_XTimeToSysTime */
#ifdef CLOCK_MONOTONIC_RAW
// use RAW monotonic clock if available (=> not subject to NTP etc)
#define D3_CLOCK_TO_USE CLOCK_MONOTONIC_RAW
#else
#define D3_CLOCK_TO_USE CLOCK_MONOTONIC
#endif
// RB: changed long to int // RB: changed long to int
unsigned int sys_timeBase = 0; unsigned int sys_timeBase = 0;
// RB end // RB end
@ -192,23 +200,12 @@ unsigned int sys_timeBase = 0;
*/ */
int Sys_Milliseconds() int Sys_Milliseconds()
{ {
// RB: clock_gettime should be a good replacement on Android // DG: use clock_gettime on all platforms
// because gettimeofday() seemed to cause a 64 bit emulation and performance penalty #if 1
#if defined(__ANDROID__)
#if 0
int curtime; int curtime;
struct timespec ts; struct timespec ts;
clock_gettime( CLOCK_MONOTONIC, &ts ); clock_gettime( D3_CLOCK_TO_USE, &ts );
curtime = ts.tv_sec * 1000 + ts.tv_nsec / 1000000;
return curtime;
#else
int curtime;
struct timespec ts;
clock_gettime( CLOCK_MONOTONIC, &ts );
if( !sys_timeBase ) if( !sys_timeBase )
{ {
@ -219,24 +216,25 @@ int Sys_Milliseconds()
curtime = ( ts.tv_sec - sys_timeBase ) * 1000 + ts.tv_nsec / 1000000; curtime = ( ts.tv_sec - sys_timeBase ) * 1000 + ts.tv_nsec / 1000000;
return curtime; return curtime;
#endif
// RB end
#else #else
// gettimeofday() implementation
int curtime; int curtime;
struct timeval tp; struct timeval tp;
gettimeofday( &tp, NULL ); gettimeofday( &tp, NULL );
if( !sys_timeBase ) if( !sys_timeBase )
{ {
sys_timeBase = tp.tv_sec; sys_timeBase = tp.tv_sec;
return tp.tv_usec / 1000; return tp.tv_usec / 1000;
} }
curtime = ( tp.tv_sec - sys_timeBase ) * 1000 + tp.tv_usec / 1000; curtime = ( tp.tv_sec - sys_timeBase ) * 1000 + tp.tv_usec / 1000;
return curtime; return curtime;
* /
#endif #endif
// DG end
} }
// RB: added for BFG // RB: added for BFG
@ -270,15 +268,15 @@ uint64 Sys_Microseconds()
return curtime; return curtime;
#else #else
int curtime; uint64 curtime;
struct timespec ts; struct timespec ts;
clock_gettime( CLOCK_MONOTONIC, &ts ); clock_gettime( D3_CLOCK_TO_USE, &ts );
if( !sys_microTimeBase ) if( !sys_microTimeBase )
{ {
sys_microTimeBase = ts.tv_sec; sys_microTimeBase = ts.tv_sec;
return ts.tv_nsec / 1000000; return ts.tv_nsec / 1000;
} }
curtime = ( ts.tv_sec - sys_microTimeBase ) * 1000000 + ts.tv_nsec / 1000; curtime = ( ts.tv_sec - sys_microTimeBase ) * 1000000 + ts.tv_nsec / 1000;