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.
101 lines
2.7 KiB
101 lines
2.7 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//============================================================================= |
|
|
|
#include "tier1/reliabletimer.h" |
|
|
|
int64 CReliableTimer::sm_nPerformanceFrequency = 0; |
|
bool CReliableTimer::sm_bUseQPC = false; |
|
|
|
#ifdef _WIN32 |
|
#include "winlite.h" |
|
#endif |
|
|
|
#ifdef POSIX |
|
#include <time.h> |
|
#endif |
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Constructor |
|
//----------------------------------------------------------------------------- |
|
CReliableTimer::CReliableTimer() |
|
{ |
|
m_nPerformanceCounterStart = 0; |
|
m_nPerformanceCounterEnd = 0; |
|
m_nPerformanceCounterLimit = 0; |
|
|
|
#ifdef _WIN32 |
|
// calculate performance frequency the first time we use a timer |
|
if ( 0 == sm_nPerformanceFrequency ) |
|
{ |
|
// Are we on a bad CPU? |
|
sm_bUseQPC = false; // todo |
|
const CPUInformation &cpu = *GetCPUInformation(); |
|
sm_bUseQPC = ( ( 0 == Q_stricmp( cpu.m_szProcessorID, "AuthenticAMD" ) ) |
|
&& ( cpu.m_nPhysicalProcessors > 1 ) |
|
&& !cpu.m_bSSE41 ); |
|
|
|
if ( sm_bUseQPC ) |
|
{ |
|
LARGE_INTEGER li; |
|
QueryPerformanceFrequency( &li ); |
|
sm_nPerformanceFrequency = li.QuadPart; |
|
} |
|
else |
|
{ |
|
sm_nPerformanceFrequency = g_ClockSpeed; |
|
} |
|
} |
|
#elif defined(_PS3) |
|
// On PowerPC, the time base register increment frequency is implementation dependent, and doesn't have to be constant. |
|
// On PS3, measured it to be just shy of 80Mhz on the PPU and doesn't seem to change |
|
if ( sm_nPerformanceFrequency == 0 ) |
|
sm_nPerformanceFrequency = sys_time_get_timebase_frequency(); |
|
#else |
|
// calculate performance frequency the first time we use a timer |
|
if ( 0 == sm_nPerformanceFrequency ) |
|
{ |
|
sm_nPerformanceFrequency = g_ClockSpeed; |
|
} |
|
#endif |
|
} |
|
|
|
|
|
//----------------------------------------------------------------------------- |
|
// Purpose: Returns current QueryPerformanceCounter value |
|
//----------------------------------------------------------------------------- |
|
int64 CReliableTimer::GetPerformanceCountNow() |
|
{ |
|
//VPROF_BUDGET( "CReliableTimer::GetPerformanceCountNow", VPROF_BUDGETGROUP_OTHER_UNACCOUNTED ); |
|
#ifdef _WIN32 |
|
if ( sm_bUseQPC ) |
|
{ |
|
LARGE_INTEGER li = {0}; |
|
QueryPerformanceCounter( &li ); |
|
return li.QuadPart; |
|
} |
|
else |
|
{ |
|
CCycleCount CycleCount; |
|
CycleCount.Sample(); |
|
return CycleCount.GetLongCycles(); |
|
} |
|
#elif defined( _PS3 ) |
|
// use handy macro to grab tb |
|
uint64 ulNow; |
|
SYS_TIMEBASE_GET( ulNow ); |
|
return ulNow; |
|
#elif (defined( __arm__ ) || defined( __aarch64__ )) && defined (POSIX) |
|
struct timespec ts; |
|
clock_gettime(CLOCK_REALTIME, &ts); |
|
return ts.tv_sec * 1000000000ULL + ts.tv_nsec; |
|
#else |
|
uint64 un64; |
|
__asm__ __volatile__ ( |
|
"rdtsc\n\t" |
|
: "=A" (un64) ); |
|
return (int64)un64; |
|
#endif |
|
}
|
|
|