mirror of
https://github.com/nillerusr/source-engine.git
synced 2026-08-15 21:26:57 +00:00
1
This commit is contained in:
@@ -0,0 +1,183 @@
|
||||
//========= Copyright Valve Corporation, All rights reserved. ============//
|
||||
//
|
||||
// Purpose:
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
#ifndef RELIABLETIMER_H
|
||||
#define RELIABLETIMER_H
|
||||
|
||||
#include "tier0/dbg.h"
|
||||
//#include "constants.h"
|
||||
#include "tier0/fasttimer.h"
|
||||
#include "tier1/tier1.h"
|
||||
#include "tier1/strtools.h"
|
||||
|
||||
#define DbgAssert Assert
|
||||
#define kMILLION (1000000)
|
||||
#define kTHOUSAND (1000)
|
||||
|
||||
// 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 ) * kMILLION / 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 ) * kTHOUSAND / 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 ) / kMILLION );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// 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 * kMILLION / 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 * kMILLION / sm_nPerformanceFrequency );
|
||||
}
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Purpose: Returns milliseconds remaining until limit
|
||||
//-----------------------------------------------------------------------------
|
||||
inline int64 CReliableTimer::CMilliSecLeft()
|
||||
{
|
||||
return CMicroSecLeft() / 1000;
|
||||
}
|
||||
|
||||
|
||||
#endif // TICKLIMITTIMER_H
|
||||
Reference in New Issue
Block a user