Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef __HAYAI_CLOCK
00040 #define __HAYAI_CLOCK
00041
00042 #include "hayai/hayai_compatibility.hpp"
00043
00044
00045
00046 #if defined(_WIN32)
00047 #ifndef NOMINMAX
00048 #define NOMINMAX
00049 #endif
00050 #include <windows.h>
00051
00052
00053 #elif defined(__APPLE__) && defined(__MACH__)
00054 #include <mach/mach_time.h>
00055
00056
00057 #elif defined(__unix__) || defined(__unix) || defined(unix)
00058
00059
00060 # if (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
00061 # include <sys/time.h>
00062
00063
00064 # elif defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
00065 # include <time.h>
00066
00067
00068 # else
00069 # include <sys/time.h>
00070
00071 # endif
00072 #else
00073 #error "Unable to define high resolution timer for an unknown OS."
00074 #endif
00075
00076 #include <stdexcept>
00077 #include <stdint.h>
00078
00079
00080 namespace hayai
00081 {
00082
00083 #if defined(_WIN32)
00084 class Clock
00085 {
00086 public:
00088
00090 typedef LARGE_INTEGER TimePoint;
00091
00092
00094
00096 static TimePoint Now()
00097 {
00098 TimePoint result;
00099 QueryPerformanceCounter(&result);
00100 return result;
00101 }
00102
00103
00105
00110 static uint64_t Duration(const TimePoint& startTime,
00111 const TimePoint& endTime)
00112 {
00113 const static double performanceFrequencyNs =
00114 PerformanceFrequencyNs();
00115
00116 return static_cast<uint64_t>(
00117 (endTime.QuadPart - startTime.QuadPart)
00118 * performanceFrequencyNs
00119 );
00120 }
00121
00122
00124
00126 static const char* Description()
00127 {
00128 return "QueryPerformanceCounter";
00129 }
00130 private:
00131 static double PerformanceFrequencyNs()
00132 {
00133 TimePoint result;
00134 QueryPerformanceFrequency(&result);
00135 return 1e9 / static_cast<double>(result.QuadPart);
00136 }
00137 };
00138
00139
00140 #elif defined(__APPLE__) && defined(__MACH__)
00141 class Clock
00142 {
00143 public:
00145
00147 typedef uint64_t TimePoint;
00148
00149
00151
00153 static TimePoint Now() __hayai_noexcept
00154 {
00155 return mach_absolute_time();
00156 }
00157
00158
00160
00165 static uint64_t Duration(const TimePoint& startTime,
00166 const TimePoint& endTime) __hayai_noexcept
00167 {
00168 mach_timebase_info_data_t time_info;
00169 mach_timebase_info(&time_info);
00170
00171 return (endTime - startTime) * time_info.numer / time_info.denom;
00172 }
00173
00174
00176
00178 static const char* Description()
00179 {
00180 return "mach_absolute_time";
00181 }
00182 };
00183
00184
00185 #elif defined(__unix__) || defined(__unix) || defined(unix)
00186
00187
00188 # if (defined(__hpux) || defined(hpux)) || ((defined(__sun__) || defined(__sun) || defined(sun)) && (defined(__SVR4) || defined(__svr4__)))
00189 class Clock
00190 {
00191 public:
00193
00195 typedef hrtime_t TimePoint;
00196
00197
00199
00201 static TimePoint Now() __hayai_noexcept
00202 {
00203 return gethrtime();
00204 }
00205
00206
00208
00213 static uint64_t Duration(const TimePoint& startTime,
00214 const TimePoint& endTime) __hayai_noexcept
00215 {
00216 return static_cast<uint64_t>(endTime - startTime);
00217 }
00218
00219
00221
00223 static const char* Description()
00224 {
00225 return "gethrtime";
00226 }
00227 };
00228
00229
00230
00231 # elif defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
00232 class Clock
00233 {
00234 public:
00236
00238 typedef struct timespec TimePoint;
00239
00240
00242
00244 static TimePoint Now() __hayai_noexcept
00245 {
00246 TimePoint result;
00247 # if defined(CLOCK_MONOTONIC_RAW)
00248 clock_gettime(CLOCK_MONOTONIC_RAW, &result);
00249 # elif defined(CLOCK_MONOTONIC)
00250 clock_gettime(CLOCK_MONOTONIC, &result);
00251 # elif defined(CLOCK_REALTIME)
00252 clock_gettime(CLOCK_REALTIME, &result);
00253 # else
00254 clock_gettime((clockid_t) - 1, &result);
00255 # endif
00256 return result;
00257 }
00258
00259
00261
00266 static uint64_t Duration(const TimePoint& startTime,
00267 const TimePoint& endTime) __hayai_noexcept
00268 {
00269 TimePoint timeDiff;
00270
00271 timeDiff.tv_sec = endTime.tv_sec - startTime.tv_sec;
00272
00273 if (endTime.tv_nsec < startTime.tv_nsec)
00274 {
00275 timeDiff.tv_nsec = endTime.tv_nsec + 1000000000LL -
00276 startTime.tv_nsec;
00277 timeDiff.tv_sec--;
00278 }
00279 else
00280 { timeDiff.tv_nsec = endTime.tv_nsec - startTime.tv_nsec; }
00281
00282 return static_cast<uint64_t>(timeDiff.tv_sec * 1000000000L +
00283 timeDiff.tv_nsec);
00284 }
00285
00286
00288
00290 static const char* Description()
00291 {
00292 # if defined(CLOCK_MONOTONIC_RAW)
00293 return "clock_gettime(CLOCK_MONOTONIC_RAW)";
00294 # elif defined(CLOCK_MONOTONIC)
00295 return "clock_gettime(CLOCK_MONOTONIC)";
00296 # elif defined(CLOCK_REALTIME)
00297 return "clock_gettime(CLOCK_REALTIME)";
00298 # else
00299 return "clock_gettime(-1)";
00300 # endif
00301 }
00302 };
00303
00304
00305 # else
00306 class Clock
00307 {
00308 public:
00310
00312 typedef struct timeval TimePoint;
00313
00314
00316
00318 static TimePoint Now() __hayai_noexcept
00319 {
00320 TimePoint result;
00321 gettimeofday(&result, NULL);
00322 return result;
00323 }
00324
00325
00327
00332 static uint64_t Duration(const TimePoint& startTime,
00333 const TimePoint& endTime) __hayai_noexcept
00334 {
00335 TimePoint timeDiff;
00336
00337 timeDiff.tv_sec = endTime.tv_sec - startTime.tv_sec;
00338
00339 if (endTime.tv_usec < startTime.tv_usec)
00340 {
00341 timeDiff.tv_usec = endTime.tv_usec + 1000000L -
00342 startTime.tv_usec;
00343 timeDiff.tv_sec--;
00344 }
00345 else
00346 { timeDiff.tv_usec = endTime.tv_usec - startTime.tv_usec; }
00347
00348 return static_cast<uint64_t>(timeDiff.tv_sec * 1000000000LL +
00349 timeDiff.tv_usec * 1000);
00350 }
00351
00352
00354
00356 static const char* Description()
00357 {
00358 return "gettimeofday";
00359 }
00360 };
00361 # endif
00362 #endif
00363 }
00364 #endif