/* Enable IEEE Std 1003.1b-1993 functionality required for clock_gettime. */ #ifdef __linux__ /* Works for Ubuntu 15.10 */ #define _POSIX_C_SOURCE 199309L #elif defined __CYGWIN__ /* Works for Cygwin 2.4.0 64-bit */ #define _POSIX_TIMERS 1 #define _POSIX_MONOTONIC_CLOCK 200112L #endif #include "vn/xplat/time.h" #if (defined __linux__ || defined __CYGWIN__ || defined __QNXNTO__) #include #elif defined __APPLE__ #include #include #endif VnError VnStopwatch_initializeAndStart(VnStopwatch *sw) { #if _WIN32 sw->pcFrequency = 0; sw->counterStart = -1; #elif (defined __linux__ || defined __APPLE__ || defined __CYGWIN__ || defined __QNXNTO__) sw->clockStart = -1; #else #error "Unknown System" #endif /* Start the stopwatch. */ return VnStopwatch_reset(sw); } VnError VnStopwatch_reset(VnStopwatch *sw) { #if _WIN32 LARGE_INTEGER li; if(!QueryPerformanceFrequency(&li)) /* The hardware must not support a high-resolution performance counter. */ return E_NOT_SUPPORTED; sw->pcFrequency = li.QuadPart / 1000.0; QueryPerformanceCounter(&li); sw->counterStart = li.QuadPart; #elif (defined __linux__ || defined __CYGWIN__ || defined __QNXNTO__) struct timespec time; int error; error = clock_gettime(CLOCK_MONOTONIC, &time); if (error) return E_UNKNOWN; sw->clockStart = (time.tv_sec * 1000.0) + (time.tv_nsec / 1000000.0); #elif defined __APPLE__ clock_serv_t cclock; mach_struct timespec_t mts; host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); sw->clockStart = (mts.tv_sec * 1000.0) + (mts.tv_nsec / 1000000.0); #else #error "Unknown System" #endif return E_NONE; } VnError VnStopwatch_elapsedMs(VnStopwatch *sw, float *elapsedMs) { #if _WIN32 LARGE_INTEGER li; if (sw->counterStart == -1) return E_UNKNOWN; QueryPerformanceCounter(&li); *elapsedMs = (float) ((li.QuadPart - sw->counterStart) / sw->pcFrequency); #elif (defined __linux__ || defined __CYGWIN__ || defined __QNXNTO__) struct timespec time; int error; if (sw->clockStart < 0) /* Clock not started. */ return E_INVALID_OPERATION; error = clock_gettime(CLOCK_MONOTONIC, &time); if (error) return E_UNKNOWN; *elapsedMs = (time.tv_sec * 1000.0) + (time.tv_nsec / 1000000.0) - sw->clockStart; #elif defined __APPLE__ clock_serv_t cclock; mach_struct timespec_t mts; host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); return (mts.tv_sec * 1000.0) + (mts.tv_nsec / 1000000.0) - sw->clockStart; #else #error "Unknown System" #endif return E_NONE; }