1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 #if defined(__unix__) || defined(__native_client__) || defined(EMSCRIPTEN) || defined(ANDROID) || defined(__APPLE__) || defined (__CYGWIN__)19 #include <time.h>20 #include <errno.h>21 #include <string.h>22 #include <sys/time.h>23 #endif24 25 #ifdef WIN3226 #include "../Math/InclWindows.h"27 #endif28 29 #ifdef EMSCRIPTEN30 #include <emscripten.h>31 #endif32 33 #ifdef __APPLE__34 #include <mach/mach_time.h>35 #endif36 37 #include "[Clock.h]"38 #include "../Math/myassert.h"39 #include "../Math/assume.h"40 41 [MATH_BEGIN_NAMESPACE]42 43 #ifdef WIN3244 [u64] Clock::ddwTimerFrequency;45 #endif46 47 #ifdef __APPLE__48 [tick_t] Clock::ticksPerSecond = 0;49 #endif50 51 [tick_t] Clock::appStartTime = 0;52 53 [Clock] [impl];54 55 void Clock::InitClockData()56 {57 if (appStartTime == 0)58 appStartTime = [Tick]();59 60 #ifdef WIN3261 if (!QueryPerformanceFrequency(reinterpret_cast<LARGE_INTEGER*>(&ddwTimerFrequency)))62 {63 [LOGE]("The system doesn't support high-resolution timers!");64 ddwTimerFrequency = ([u64])-1;65 }66 67 if (appStartTime == 0)68 {69 #if WINVER >= 0x0600 && !defined(MATH_ENABLE_WINXP_SUPPORT)70 appStartTime = ([tick_t])GetTickCount64();71 #else72 73 #if _MSC_VER >= 1700 // VS201274 #pragma warning(push)75 #pragma warning(disable:28159) // warning C28159: Consider using 'GetTickCount64' instead of 'GetTickCount'. Reason: GetTickCount overflows roughly every 49 days. Code that does not take that into account can loop indefinitely. GetTickCount64 operates on 64 bit values and does not have that problem76 #endif77 appStartTime = ([tick_t])GetTickCount();78 #if _MSC_VER >= 1700 // VS201279 #pragma warning(pop)80 #endif81 82 #endif83 }84 #endif85 86 #ifdef __APPLE__87 mach_timebase_info_data_t timeBaseInfo;88 mach_timebase_info(&timeBaseInfo);89 ticksPerSecond = 1000000000ULL * (uint64_t)timeBaseInfo.denom / (uint64_t)timeBaseInfo.numer;90 [assert](ticksPerSecond > (uint64_t)timeBaseInfo.denom/timeBaseInfo.numer); 91 #endif92 }93 94 [Clock::Clock]()95 {96 InitClockData();97 }98 99 void [Clock::Sleep](int milliseconds)100 {101 #ifdef WIN8RT102 #pragma warning(Clock::Sleep has not been implemented!)103 #elif defined(WIN32)104 [::Sleep](milliseconds);105 #elif !defined(__native_client__) && !defined(EMSCRIPTEN)106 107 timespec ts;108 ts.tv_sec = milliseconds / 1000;109 ts.tv_nsec = (milliseconds - ts.tv_sec * 1000) * 1000 * 1000;110 int ret = nanosleep(&ts, NULL);111 if (ret == -1)112 [LOGI]("nanosleep returned -1! Reason: %s(%d).", strerror(errno), (int)errno);113 #else114 #warning Clock::Sleep has not been implemented!115 #endif116 }117 118 int [Clock::Year]()119 {120 #ifdef WIN32121 SYSTEMTIME s;122 GetSystemTime(&s);123 return s.wYear;124 #else125 126 return 0;127 #endif128 }129 130 int [Clock::Month]()131 {132 #ifdef WIN32133 SYSTEMTIME s;134 GetSystemTime(&s);135 return s.wMonth;136 #else137 138 return 0;139 #endif140 }141 142 int [Clock::Day]()143 {144 #ifdef WIN32145 SYSTEMTIME s;146 GetSystemTime(&s);147 return s.wDay;148 #else149 150 return 0;151 #endif152 }153 154 int [Clock::Hour]()155 {156 #ifdef WIN32157 SYSTEMTIME s;158 GetSystemTime(&s);159 return s.wHour;160 #else161 162 return 0;163 #endif164 }165 166 int [Clock::Min]()167 {168 #ifdef WIN32169 SYSTEMTIME s;170 GetSystemTime(&s);171 return s.wMinute;172 #else173 174 return 0;175 #endif176 }177 178 int [Clock::Sec]()179 {180 #ifdef WIN32181 SYSTEMTIME s;182 GetSystemTime(&s);183 return s.wSecond;184 #else185 186 return 0;187 #endif188 }189 190 unsigned long [Clock::SystemTime]()191 {192 #ifdef WIN32193 #if WINVER >= 0x0600 && !defined(MATH_ENABLE_WINXP_SUPPORT)194 return (unsigned long)GetTickCount64();195 #else196 197 #if _MSC_VER >= 1700 // VS2012198 #pragma warning(push)199 #pragma warning(disable:28159) // warning C28159: Consider using 'GetTickCount64' instead of 'GetTickCount'. Reason: GetTickCount overflows roughly every 49 days. Code that does not take that into account can loop indefinitely. GetTickCount64 operates on 64 bit values and does not have that problem200 #endif201 return (unsigned long)GetTickCount();202 #if _MSC_VER >= 1700 // VS2012203 #pragma warning(pop)204 #endif205 206 #endif207 #else208 return [TickU32]();209 #endif210 }211 212 213 214 215 216 217 unsigned long [Clock::Time]()218 {219 return (unsigned long)([Tick]() - appStartTime);220 }221 222 [tick_t] [Clock::Tick]()223 {224 #if defined(ANDROID)225 struct timespec res;226 clock_gettime(CLOCK_REALTIME, &res);227 return 1000000000ULL*res.tv_sec + ([tick_t])res.tv_nsec;228 #elif defined(EMSCRIPTEN)229 230 #ifdef MATH_TICK_IS_FLOAT231 return ([tick_t])emscripten_get_now();232 #else233 234 235 return ([tick_t])(((double)emscripten_get_now()) * 1e3);236 #endif237 238 #elif defined(WIN32)239 LARGE_INTEGER ddwTimer;240 BOOL success = QueryPerformanceCounter(&ddwTimer);241 [assume](success != 0);242 MARK_UNUSED(success);243 return ddwTimer.QuadPart;244 #elif defined(__APPLE__)245 return mach_absolute_time();246 #elif defined(_POSIX_MONOTONIC_CLOCK)247 timespec t;248 clock_gettime(CLOCK_MONOTONIC, &t);249 return ([tick_t])t.tv_sec * 1000 * 1000 * 1000 + ([tick_t])t.tv_nsec;250 #elif defined(_POSIX_C_SOURCE)251 timeval t;252 gettimeofday(&t, NULL);253 return ([tick_t])t.tv_sec * 1000 * 1000 + ([tick_t])t.tv_usec;254 #else255 return ([tick_t])clock();256 #endif257 }258 259 unsigned long [Clock::TickU32]()260 {261 #ifdef WIN32262 LARGE_INTEGER ddwTimer;263 BOOL success = QueryPerformanceCounter(&ddwTimer);264 [assume](success != 0);265 MARK_UNUSED(success);266 return ddwTimer.LowPart;267 #else268 return (unsigned long)[Tick]();269 #endif270 }271 272 [tick_t] [Clock::TicksPerSec]()273 {274 #if defined(ANDROID)275 return 1000000000ULL; 276 #elif defined(EMSCRIPTEN)277 278 #ifdef MATH_TICK_IS_FLOAT279 return ([tick_t])1000.0;280 #else281 return 1000000ULL; 282 #endif283 284 #elif defined(WIN32)285 return ddwTimerFrequency;286 #elif defined(__APPLE__)287 return ticksPerSecond;288 #elif defined(_POSIX_MONOTONIC_CLOCK)289 return 1000 * 1000 * 1000;290 #elif defined(_POSIX_C_SOURCE) || defined(__APPLE__)291 return 1000 * 1000;292 #else293 return CLOCKS_PER_SEC;294 #endif295 }296 297 unsigned long long [Clock::Rdtsc]()298 {299 #if defined(_MSC_VER) && !defined(WIN8PHONE)300 return __rdtsc();301 #elif defined(__x86_64__)302 unsigned hi, lo;303 __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));304 return ((unsigned long long)lo) | (((unsigned long long)hi) << 32);305 #elif defined(__i386__) || defined(__X86__) || defined(_X86_)306 unsigned long long int x;307 __asm__ volatile ("rdtsc" : "=A" (x));308 return x;309 #else310 return [Clock::Tick]();311 #endif312 }313 314 [MATH_END_NAMESPACE] Go back to previous page