Counter Strike : Global Offensive Source Code
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
//====== Copyright � 1996-2004, Valve Corporation, All rights reserved. =======
//
// Purpose:
//
//=============================================================================
#ifndef RELIABLETIMER_H
#define RELIABLETIMER_H
#include "tier0/dbg.h"
// Timer class that uses QueryPerformanceCounter. This is heavier-weight than CFastTimer which uses rdtsc,
// but this is reliable on multi-core systems whereas CFastTimer is not.
class CReliableTimer { public: CReliableTimer(); void Start(); void End(); int64 GetMicroseconds(); int64 GetMilliseconds(); void SetLimit( uint64 m_cMicroSecDuration ); bool BLimitReached(); int64 CMicroSecOverage(); int64 CMicroSecLeft(); int64 CMilliSecLeft(); private: int64 GetPerformanceCountNow();
int64 m_nPerformanceCounterStart; int64 m_nPerformanceCounterEnd; int64 m_nPerformanceCounterLimit;
static int64 sm_nPerformanceFrequency; static bool sm_bUseQPC; };
//-----------------------------------------------------------------------------
// Purpose: Records timer start time
//-----------------------------------------------------------------------------
inline void CReliableTimer::Start() { m_nPerformanceCounterStart = GetPerformanceCountNow(); }
//-----------------------------------------------------------------------------
// Purpose: Records timer end time
//-----------------------------------------------------------------------------
inline void CReliableTimer::End() { m_nPerformanceCounterEnd = GetPerformanceCountNow();
// enforce that we've advanced at least one cycle
if ( m_nPerformanceCounterEnd < m_nPerformanceCounterStart ) { #ifdef _SERVER
if ( m_nPerformanceCounterEnd+10000 < m_nPerformanceCounterStart ) AssertMsgOnce( false, CDbgFmtMsg( "CReliableTimer went backwards - start:%lld end:%lld", m_nPerformanceCounterStart, m_nPerformanceCounterEnd ).ToString() ); #endif
m_nPerformanceCounterEnd = m_nPerformanceCounterStart + 1; } }
//-----------------------------------------------------------------------------
// Purpose: Gets microseconds elapsed between start and end
//-----------------------------------------------------------------------------
inline int64 CReliableTimer::GetMicroseconds() { DbgAssert( m_nPerformanceCounterStart ); // timer must have been started
DbgAssert( m_nPerformanceCounterEnd ); // timer must have been ended
DbgAssert( 0 != sm_nPerformanceFrequency ); // must have calc'd performance counter frequency
return ( ( m_nPerformanceCounterEnd - m_nPerformanceCounterStart ) * k_nMillion / sm_nPerformanceFrequency ); }
//-----------------------------------------------------------------------------
// Purpose: Gets microseconds elapsed between start and end
//-----------------------------------------------------------------------------
inline int64 CReliableTimer::GetMilliseconds() { DbgAssert( m_nPerformanceCounterStart ); // timer must have been started
DbgAssert( m_nPerformanceCounterEnd ); // timer must have been ended
DbgAssert( 0 != sm_nPerformanceFrequency ); // must have calc'd performance counter frequency
return ( ( m_nPerformanceCounterEnd - m_nPerformanceCounterStart ) * k_nThousand / sm_nPerformanceFrequency ); }
//-----------------------------------------------------------------------------
// Purpose: Sets a limit on this timer that can subsequently be checked against
//-----------------------------------------------------------------------------
inline void CReliableTimer::SetLimit( uint64 cMicroSecDuration ) { DbgAssert( 0 != sm_nPerformanceFrequency ); // must have calc'd performance counter frequency
m_nPerformanceCounterStart = GetPerformanceCountNow(); m_nPerformanceCounterLimit = m_nPerformanceCounterStart + ( ( cMicroSecDuration * sm_nPerformanceFrequency ) / k_nMillion ); }
//-----------------------------------------------------------------------------
// Purpose: Returns if previously set limit has been reached
//-----------------------------------------------------------------------------
inline bool CReliableTimer::BLimitReached() { DbgAssert( m_nPerformanceCounterStart ); // SetLimit must have been called
DbgAssert( m_nPerformanceCounterLimit ); // SetLimit must have been called
int64 nPerformanceCountNow = GetPerformanceCountNow();
// make sure time advances
if ( nPerformanceCountNow < m_nPerformanceCounterStart ) { #ifdef _SERVER
if ( nPerformanceCountNow+10000 < m_nPerformanceCounterStart ) AssertMsgOnce( false, CDbgFmtMsg( "CReliableTimer went backwards - start:%lld end:%lld", m_nPerformanceCounterStart, m_nPerformanceCounterEnd ).ToString() ); #endif
// reset the limit to be lower, to match our new clock
m_nPerformanceCounterLimit = nPerformanceCountNow + (m_nPerformanceCounterLimit - m_nPerformanceCounterStart); }
return ( nPerformanceCountNow >= m_nPerformanceCounterLimit ); }
//-----------------------------------------------------------------------------
// Purpose: Returns microseconds current time is past limit, or 0 if not past limit
//-----------------------------------------------------------------------------
inline int64 CReliableTimer::CMicroSecOverage() { DbgAssert( m_nPerformanceCounterStart ); // SetLimit must have been called
DbgAssert( m_nPerformanceCounterLimit ); // SetLimit must have been called
int64 nPerformanceCountNow = GetPerformanceCountNow(); #ifdef _SERVER
if ( nPerformanceCountNow+10000 < m_nPerformanceCounterStart ) AssertMsgOnce( nPerformanceCountNow >= m_nPerformanceCounterStart, CDbgFmtMsg( "CReliableTimer went backwards - start:%lld end:%lld", m_nPerformanceCounterStart, m_nPerformanceCounterEnd ).ToString() ); #endif
int64 nPerformanceCountOver = ( nPerformanceCountNow > m_nPerformanceCounterLimit ? nPerformanceCountNow - m_nPerformanceCounterLimit : 0 );
Assert( 0 != sm_nPerformanceFrequency ); // must have calc'd performance counter frequency
return ( nPerformanceCountOver * k_nMillion / sm_nPerformanceFrequency ); }
//-----------------------------------------------------------------------------
// Purpose: Returns microseconds remaining until limit
//-----------------------------------------------------------------------------
inline int64 CReliableTimer::CMicroSecLeft() { DbgAssert( m_nPerformanceCounterStart ); // SetLimit must have been called
DbgAssert( m_nPerformanceCounterLimit ); // SetLimit must have been called
int64 nPerformanceCountNow = GetPerformanceCountNow(); #ifdef _SERVER
if ( nPerformanceCountNow+10000 < m_nPerformanceCounterStart ) AssertMsgOnce( nPerformanceCountNow >= m_nPerformanceCounterStart, CDbgFmtMsg( "CReliableTimer went backwards - start:%lld end:%lld", m_nPerformanceCounterStart, m_nPerformanceCounterEnd ).ToString() ); #endif
int64 nPerformanceCountLeft = ( nPerformanceCountNow < m_nPerformanceCounterLimit ? m_nPerformanceCounterLimit - nPerformanceCountNow : 0 );
DbgAssert( 0 != sm_nPerformanceFrequency ); // must have calc'd performance counter frequency
return ( nPerformanceCountLeft * k_nMillion / sm_nPerformanceFrequency ); }
//-----------------------------------------------------------------------------
// Purpose: Returns milliseconds remaining until limit
//-----------------------------------------------------------------------------
inline int64 CReliableTimer::CMilliSecLeft() { return CMicroSecLeft() / 1000; }
#endif // TICKLIMITTIMER_H
|