From e1ab8c5b7779e72d3cbec0924ee7c86001448a5d Mon Sep 17 00:00:00 2001 From: Ted Percival Date: Thu, 24 Mar 2005 19:46:50 +0000 Subject: [PATCH] fix timing errors in thread wait functions on unix. patch by makovick fixes bug #1154212 --- .../src/arch/ArchHooks/ArchHooks_Unix.cpp | 40 +++++++++++-------- stepmania/src/arch/ArchHooks/ArchHooks_Unix.h | 2 + .../src/arch/Threads/Threads_Pthreads.cpp | 5 ++- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_Unix.cpp b/stepmania/src/arch/ArchHooks/ArchHooks_Unix.cpp index ec6607407d..35f48fdc4f 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_Unix.cpp +++ b/stepmania/src/arch/ArchHooks/ArchHooks_Unix.cpp @@ -17,6 +17,9 @@ #endif +int64_t ArchHooks_Unix::iStartTime = 0; +bool ArchHooks_Unix::bTimerInitialized = false; + static bool IsFatalSignal( int signal ) { switch( signal ) @@ -95,6 +98,26 @@ static void TestTLS() } #endif +static int64_t GetMicrosecondsSinceEpoch() +{ + struct timeval tv; + gettimeofday( &tv, NULL ); + + return int64_t(tv.tv_sec) * 1000000 + int64_t(tv.tv_usec); +} + +int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate ) +{ + if (!ArchHooks_Unix::bTimerInitialized) { + ArchHooks_Unix::bTimerInitialized = true; + ArchHooks_Unix::iStartTime = GetMicrosecondsSinceEpoch(); + } + int64_t ret = GetMicrosecondsSinceEpoch() - ArchHooks_Unix::iStartTime; + if( bAccurate ) + ret = FixupTimeIfBackwards( ret ); + return ret; +} + ArchHooks_Unix::ArchHooks_Unix() { /* First, handle non-fatal termination signals. */ @@ -166,23 +189,6 @@ void ArchHooks_Unix::SetTime( tm newtime ) system( "hwclock --systohc" ); } -static int64_t GetMicrosecondsSinceEpoch() -{ - struct timeval tv; - gettimeofday( &tv, NULL ); - - return int64_t(tv.tv_sec) * 1000000 + int64_t(tv.tv_usec); -} - -int64_t ArchHooks::GetMicrosecondsSinceStart( bool bAccurate ) -{ - static int64_t iStartTime = GetMicrosecondsSinceEpoch(); - int64_t ret = GetMicrosecondsSinceEpoch() - iStartTime; - if( bAccurate ) - ret = FixupTimeIfBackwards( ret ); - return ret; -} - /* * (c) 2003-2004 Glenn Maynard * All rights reserved. diff --git a/stepmania/src/arch/ArchHooks/ArchHooks_Unix.h b/stepmania/src/arch/ArchHooks/ArchHooks_Unix.h index 98d63d9a26..a09f801bbd 100644 --- a/stepmania/src/arch/ArchHooks/ArchHooks_Unix.h +++ b/stepmania/src/arch/ArchHooks/ArchHooks_Unix.h @@ -5,6 +5,8 @@ class ArchHooks_Unix: public ArchHooks { public: + static int64_t iStartTime; + static bool bTimerInitialized; ArchHooks_Unix(); void DumpDebugInfo(); diff --git a/stepmania/src/arch/Threads/Threads_Pthreads.cpp b/stepmania/src/arch/Threads/Threads_Pthreads.cpp index 28c35916d5..ffdbfdf2cf 100644 --- a/stepmania/src/arch/Threads/Threads_Pthreads.cpp +++ b/stepmania/src/arch/Threads/Threads_Pthreads.cpp @@ -4,6 +4,7 @@ #include "RageUtil.h" #include #include +#include "arch/ArchHooks/ArchHooks_Unix.h" #if defined(LINUX) #include "archutils/Unix/LinuxThreadHelpers.h" @@ -226,8 +227,8 @@ bool EventImpl_Pthreads::Wait( RageTimer *pTimeout ) } timespec abstime; - abstime.tv_sec = pTimeout->m_secs; - abstime.tv_nsec = pTimeout->m_us * 1000; + abstime.tv_sec = pTimeout->m_secs + ArchHooks_Unix::iStartTime/1000000; + abstime.tv_nsec = (pTimeout->m_us + ArchHooks_Unix::iStartTime%1000000) * 1000; int iRet = pthread_cond_timedwait( &m_Cond, &m_pParent->mutex, &abstime ); return iRet != ETIMEDOUT; }