clock.h
00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef EQBASE_CLOCK_H
00020 #define EQBASE_CLOCK_H
00021
00022 #include <eq/base/base.h>
00023
00024 #ifdef Darwin
00025
00026 # include <mach/mach_time.h>
00027 #endif
00028
00029 #ifdef WIN32
00030 # include <Windows.h>
00031 #else
00032 # include <time.h>
00033 #endif
00034
00035 namespace eq
00036 {
00037 namespace base
00038 {
00040 class Clock
00041 {
00042 public :
00044 Clock()
00045 {
00046 reset();
00047 #ifdef Darwin
00048 mach_timebase_info( &_timebaseInfo );
00049 #elif defined (WIN32)
00050 QueryPerformanceFrequency( &_frequency );
00051 #endif
00052 }
00053
00055 ~Clock() {}
00056
00058 void reset()
00059 {
00060 #ifdef Darwin
00061 _start = mach_absolute_time();
00062 #elif defined (WIN32)
00063 QueryPerformanceCounter( &_start );
00064 #else
00065 clock_gettime( CLOCK_REALTIME, &_start );
00066 #endif
00067 }
00068
00077 void setAlarm( const float time )
00078 {
00079 reset();
00080 #ifdef Darwin
00081 _start += static_cast<uint64_t>(
00082 time / _timebaseInfo.numer * _timebaseInfo.denom *
00083 1000000.f );
00084 #elif defined (WIN32)
00085 _start.QuadPart += static_cast<long long>( 0.001f * time *
00086 _frequency.QuadPart);
00087 #else
00088 const int sec = static_cast<int>( time * 0.001f );
00089 _start.tv_sec += sec;
00090 _start.tv_nsec += static_cast<int>(
00091 (time - sec * 1000) * 1000000 );
00092 if( _start.tv_nsec > 1000000000 )
00093 {
00094 _start.tv_sec += 1;
00095 _start.tv_nsec -= 1000000000;
00096 }
00097 #endif
00098 }
00099
00101 void set( const int64_t time )
00102 {
00103 reset();
00104 #ifdef Darwin
00105 _start -= static_cast< uint64_t >(
00106 time * _timebaseInfo.denom / _timebaseInfo.numer *
00107 1000000 );
00108 #elif defined (WIN32)
00109 _start.QuadPart -= static_cast<long long>(
00110 time * _frequency.QuadPart / 1000 );
00111 #else
00112 const int sec = static_cast< int >( time / 1000 ) + 1;
00113 _start.tv_sec -= sec;
00114 _start.tv_nsec -= static_cast<int>(
00115 (time - sec * 1000) * 1000000 );
00116 if( _start.tv_nsec > 1000000000 )
00117 {
00118 _start.tv_sec += 1;
00119 _start.tv_nsec -= 1000000000;
00120 }
00121 #endif
00122 }
00123
00127 float getTimef() const
00128 {
00129 #ifdef Darwin
00130 const int64_t elapsed = mach_absolute_time() - _start;
00131 return ( elapsed * _timebaseInfo.numer / _timebaseInfo.denom /
00132 1000000.f );
00133 #elif defined (WIN32)
00134 LARGE_INTEGER now;
00135 QueryPerformanceCounter( &now );
00136 return 1000.0f * (now.QuadPart - _start.QuadPart) /
00137 _frequency.QuadPart;
00138 #else
00139 struct timespec now;
00140 clock_gettime( CLOCK_REALTIME, &now );
00141 return ( 1000.0f * (now.tv_sec - _start.tv_sec) +
00142 0.000001f * (now.tv_nsec - _start.tv_nsec));
00143 #endif
00144 }
00145
00149 int64_t getTime64() const
00150 {
00151 #ifdef Darwin
00152 const int64_t elapsed = mach_absolute_time() - _start;
00153 return ( elapsed * _timebaseInfo.numer / _timebaseInfo.denom /
00154 1000000 );
00155 #elif defined (WIN32)
00156 LARGE_INTEGER now;
00157 QueryPerformanceCounter( &now );
00158 return 1000 * (now.QuadPart - _start.QuadPart) /
00159 _frequency.QuadPart;
00160 #else
00161 struct timespec now;
00162 clock_gettime( CLOCK_REALTIME, &now );
00163 return ( 1000 * (now.tv_sec - _start.tv_sec) +
00164 static_cast< int64_t >(0.000001f *
00165 (now.tv_nsec-_start.tv_nsec)));
00166 #endif
00167 }
00168
00172 double getTimed() const
00173 {
00174 #ifdef Darwin
00175 const int64_t elapsed = mach_absolute_time() - _start;
00176 return ( elapsed * _timebaseInfo.numer / _timebaseInfo.denom /
00177 1000000. );
00178 #elif defined (WIN32)
00179 LARGE_INTEGER now;
00180 QueryPerformanceCounter( &now );
00181 return 1000.0 * (now.QuadPart - _start.QuadPart) / _frequency.QuadPart;
00182 #else
00183 struct timespec now;
00184 clock_gettime( CLOCK_REALTIME, &now );
00185 return ( 1000.0 * (now.tv_sec - _start.tv_sec) +
00186 0.000001 * (now.tv_nsec - _start.tv_nsec));
00187 #endif
00188 }
00189
00198 float getMSf() const
00199 {
00200 #if defined (Darwin) || defined (WIN32)
00201 double time = getTimed();
00202 return static_cast<float>
00203 (time - static_cast<unsigned>(time/1000.) * 1000);
00204 #else
00205 struct timespec now;
00206 clock_gettime( CLOCK_REALTIME, &now );
00207
00208 if( now.tv_nsec < _start.tv_nsec )
00209 return ( 1000.f + 0.000001f*(now.tv_nsec - _start.tv_nsec));
00210
00211 return ( 0.000001f * ( now.tv_nsec - _start.tv_nsec ));
00212 #endif
00213 }
00214
00215 private:
00216 #ifdef Darwin
00217 uint64_t _start;
00218 mach_timebase_info_data_t _timebaseInfo;
00219 #elif defined (WIN32)
00220 LARGE_INTEGER _start;
00221 LARGE_INTEGER _frequency;
00222 #else
00223 struct timespec _start;
00224 #endif
00225 };
00226 }
00227 }
00228 #endif // EQBASE_CLOCK_H