#ifndef OSG_TIMER #define OSG_TIMER 1 #include namespace osg { #ifdef WIN32 typedef __int64 Timer_t; #elif defined(__linux) || defined(__FreeBSD__) typedef unsigned long long Timer_t; #elif defined(__sgi) typedef unsigned long long Timer_t; #elif defined(unix) typedef unsigned long long Timer_t; #else #include typedef std::clock_t Timer_t; #endif /** A high resolution, low latency time stamper.*/ class SG_EXPORT Timer { public: Timer(); ~Timer() {} inline Timer_t tick(); inline double delta_s( Timer_t t1, Timer_t t2 ) const { return (double)(t2 - t1)*_secsPerClick; } inline double delta_m( Timer_t t1, Timer_t t2 ) const { return delta_s(t1,t2)*1e3; } inline double delta_u( Timer_t t1, Timer_t t2 ) const { return delta_s(t1,t2)*1e6; } inline double delta_n( Timer_t t1, Timer_t t2 ) const { return delta_s(t1,t2)*1e9; } private : double _secsPerClick; bool _useStandardClock; #ifdef __sgi unsigned long* _clockAddress; int _cycleCntrSize; static unsigned long _dummy; #endif }; #ifdef WIN32 #include #pragma optimize("",off) inline Timer_t Timer::tick( void ) { if (_useStandardClock) return clock(); volatile Timer_t ts; volatile unsigned int HighPart; volatile unsigned int LowPart; _asm { xor eax, eax // Used when QueryPerformanceCounter() xor edx, edx // not supported or minimal overhead _emit 0x0f // desired _emit 0x31 // mov HighPart,edx mov LowPart,eax } //ts = LowPart | HighPart >> 32; *((unsigned int*)&ts) = LowPart; *((unsigned int*)&ts+1) = HighPart; return ts; } #pragma optimize("",on) #elif defined(__linux) || defined(__FreeBSD__) #include #define CLK(x) __asm__ volatile (".byte 0x0f, 0x31" : "=A" (x)) inline Timer_t Timer::tick() { if (_useStandardClock) { struct timeval tv; gettimeofday(&tv, NULL); return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec; } else { Timer_t x;CLK(x);return x; } } #elif defined(__sgi) #include inline Timer_t Timer::tick() { if (_useStandardClock) { struct timeval tv; gettimeofday(&tv, NULL); return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec; } else { return *_sgiClockAddress; } } #elif defined(unix) #include inline Timer_t Timer::tick() { struct timeval tv; gettimeofday(&tv, NULL); return ((osg::Timer_t)tv.tv_sec)*1000000+(osg::Timer_t)tv.tv_usec; } #else // no choice, always use std::clock() inline Timer_t Timer::tick( void ) { return std::clock(); } #endif }; #endif