00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "trueClock.h"
00021 #include "config_express.h"
00022 #include "numeric_types.h"
00023
00024 #include "math.h"
00025
00026 TrueClock *TrueClock::_global_ptr = NULL;
00027
00028 #if defined(WIN32_VC)
00029
00030
00031
00032
00033
00034
00035
00036 #include <sys/timeb.h>
00037
00038 #define WINDOWS_LEAN_AND_MEAN
00039 #include <windows.h>
00040 #undef WINDOWS_LEAN_AND_MEAN
00041
00042 static BOOL _has_high_res;
00043 static PN_int64 _frequency;
00044 static PN_int64 _init_count;
00045 static double _fFrequency,_recip_fFrequency;
00046 static DWORD _init_tc;
00047 static bool _paranoid_clock;
00048 static const double _0001 = 1.0/1000.0;
00049
00050 void get_true_time_of_day(ulong &sec, ulong &usec) {
00051 struct timeb tb;
00052 ftime(&tb);
00053 sec = tb.time;
00054 usec = (ulong)(tb.millitm * 1000.0);
00055 }
00056
00057 double TrueClock::
00058 get_long_time() const {
00059 DWORD tc = GetTickCount();
00060 return (double)(tc - _init_tc) * _0001;
00061 }
00062
00063 double TrueClock::
00064 get_short_time() const {
00065 if (_has_high_res) {
00066 LARGE_INTEGER count;
00067 QueryPerformanceCounter(&count);
00068
00069 double time = (double)(count.QuadPart - _init_count) * _recip_fFrequency;
00070
00071 if (_paranoid_clock) {
00072
00073
00074 DWORD tc = GetTickCount();
00075 double sys_time = (double)(tc - _init_tc) * _0001;
00076 if (fabs(time - sys_time) > 0.5) {
00077
00078 express_cat.info()
00079 << "Clock error! High resolution clock reads " << time
00080 << " while system clock reads " << sys_time << ".\n";
00081 _init_count =
00082 (PN_int64)(count.QuadPart - sys_time * _fFrequency);
00083 time = (double)(count.QuadPart - _init_count) * _recip_fFrequency;
00084 express_cat.info()
00085 << "High resolution clock reset to " << time << ".\n";
00086 }
00087 }
00088
00089 return time;
00090
00091 } else {
00092
00093 DWORD tc = GetTickCount();
00094 return (double)(tc - _init_tc) * _0001;
00095 }
00096 }
00097
00098 TrueClock::
00099 TrueClock() {
00100 _has_high_res = false;
00101 if (get_use_high_res_clock()) {
00102 _has_high_res = QueryPerformanceFrequency((LARGE_INTEGER *)&_frequency);
00103 _fFrequency = (double) _frequency;
00104 _recip_fFrequency = 1.0/_fFrequency;
00105 }
00106
00107 _paranoid_clock = get_paranoid_clock();
00108
00109 if (_has_high_res) {
00110 LARGE_INTEGER count;
00111 QueryPerformanceCounter(&count);
00112 _init_count = count.QuadPart;
00113
00114 if (_frequency <= 0) {
00115 express_cat.error()
00116 << "TrueClock::get_real_time() - frequency is negative!" << endl;
00117 _has_high_res = false;
00118 }
00119 }
00120
00121
00122
00123
00124
00125 _init_tc = GetTickCount();
00126
00127 if (!_has_high_res) {
00128 express_cat.warning()
00129 << "No high resolution clock available." << endl;
00130
00131 } else if (_paranoid_clock) {
00132 express_cat.info()
00133 << "Not trusting the high resolution clock." << endl;
00134 }
00135 }
00136
00137
00138 #elif defined(PENV_PS2)
00139
00140
00141
00142
00143
00144
00145
00146
00147 #include <eeregs.h>
00148 #include <eekernel.h>
00149
00150 static unsigned int _msec;
00151 static unsigned int _sec;
00152
00153
00154
00155 static int
00156 timer_handler(int) {
00157 _msec++;
00158
00159 if (_msec >= 1000) {
00160 _msec = 0;
00161 _sec++;
00162 }
00163
00164 return -1;
00165 }
00166
00167 void get_true_time_of_day(ulong &sec, ulong &msec) {
00168 cerr << "get_true_time_of_day() not implemented!" << endl;
00169 }
00170
00171 double TrueClock::
00172 get_long_time() const {
00173 return (double) _sec + ((double) _msec / 1000.0);
00174 }
00175
00176 double TrueClock::
00177 get_short_time() const {
00178 return (double) _sec + ((double) _msec / 1000.0);
00179 }
00180
00181 TrueClock::
00182 TrueClock() {
00183 _init_sec = 0;
00184 _msec = 0;
00185 _sec = 0;
00186
00187 tT_MODE timer_mode;
00188 *(unsigned int *) &timer_mode = 0;
00189
00190 timer_mode.cxxLKS = 1;
00191 timer_mode.ZRET = 1;
00192 timer_mode.cxxUE = 1;
00193 timer_mode.cxxMPE = 1;
00194 timer_mode.EQUF = 1;
00195
00196 *T0_COMP = 9375;
00197 *T0_MODE = *(unsigned int *) &timer_mode;
00198
00199 EnableIntc(INTC_TIM0);
00200 AddIntcHandler(INTC_TIM0, timer_handler, -1);
00201 }
00202
00203
00204 #elif !defined(WIN32_VC)
00205
00206
00207
00208
00209
00210
00211
00212 #include <sys/time.h>
00213 #include <stdio.h>
00214
00215 static long _init_sec;
00216
00217 void get_true_time_of_day(ulong &sec, ulong &msec) {
00218 struct timeval tv;
00219 int result;
00220
00221 #ifdef GETTIMEOFDAY_ONE_PARAM
00222 result = gettimeofday(&tv);
00223 #else
00224 result = gettimeofday(&tv, (struct timezone *)NULL);
00225 #endif
00226
00227 if (result < 0) {
00228 sec = 0;
00229 msec = 0;
00230
00231 return;
00232 }
00233 sec = tv.tv_sec;
00234 msec = tv.tv_usec;
00235 }
00236
00237 double TrueClock::
00238 get_long_time() const {
00239 struct timeval tv;
00240
00241 int result;
00242
00243 #ifdef GETTIMEOFDAY_ONE_PARAM
00244 result = gettimeofday(&tv);
00245 #else
00246 result = gettimeofday(&tv, (struct timezone *)NULL);
00247 #endif
00248
00249 if (result < 0) {
00250
00251 return 0.0;
00252 }
00253
00254
00255
00256
00257
00258 return (double)(tv.tv_sec - _init_sec) + (double)tv.tv_usec / 1000000.0;
00259 }
00260
00261 double TrueClock::
00262 get_short_time() const {
00263 struct timeval tv;
00264
00265 int result;
00266
00267 #ifdef GETTIMEOFDAY_ONE_PARAM
00268 result = gettimeofday(&tv);
00269 #else
00270 result = gettimeofday(&tv, (struct timezone *)NULL);
00271 #endif
00272
00273 if (result < 0) {
00274
00275 return 0.0;
00276 }
00277
00278
00279
00280
00281
00282 return (double)(tv.tv_sec - _init_sec) + (double)tv.tv_usec / 1000000.0;
00283 }
00284
00285 TrueClock::
00286 TrueClock() {
00287 struct timeval tv;
00288
00289 int result;
00290 #ifdef GETTIMEOFDAY_ONE_PARAM
00291 result = gettimeofday(&tv);
00292 #else
00293 result = gettimeofday(&tv, (struct timezone *)NULL);
00294 #endif
00295
00296 if (result < 0) {
00297 perror("gettimeofday");
00298 _init_sec = 0;
00299 } else {
00300 _init_sec = tv.tv_sec;
00301 }
00302 }
00303
00304 #endif