#include "tick.h" #include #include #ifdef _WIN32 # include #endif sc_tick sc_tick_now(void) { #ifndef _WIN32 // Maximum sc_tick precision (microsecond) struct timespec ts; int ret = clock_gettime(CLOCK_MONOTONIC, &ts); if (ret) { abort(); } return SC_TICK_FROM_SEC(ts.tv_sec) + SC_TICK_FROM_NS(ts.tv_nsec); #else LARGE_INTEGER c; // On systems that run Windows XP or later, the function will always // succeed and will thus never return zero. // // BOOL ok = QueryPerformanceCounter(&c); assert(ok); (void) ok; LONGLONG counter = c.QuadPart; static LONGLONG frequency; if (!frequency) { // Initialize on first call LARGE_INTEGER f; ok = QueryPerformanceFrequency(&f); assert(ok); frequency = f.QuadPart; assert(frequency); } if (frequency % SC_TICK_FREQ == 0) { // Expected case (typically frequency = 10000000, i.e. 100ns precision) sc_tick div = frequency / SC_TICK_FREQ; return SC_TICK_FROM_US(counter / div); } // Split the division to avoid overflow sc_tick secs = SC_TICK_FROM_SEC(counter / frequency); sc_tick subsec = SC_TICK_FREQ * (counter % frequency) / frequency; return secs + subsec; #endif }