diff --git a/deps/MsvcLibX/include/msvcTime.h b/deps/MsvcLibX/include/msvcTime.h index 1897da58570cf503b05502d0a15c899f1f126015..6f8b5dac8f88e4c3dd40445f1c5512ba2e6e796f 100644 --- a/deps/MsvcLibX/include/msvcTime.h +++ b/deps/MsvcLibX/include/msvcTime.h @@ -38,6 +38,7 @@ typedef int clockid_t; /* Supported values for clockid_t */ #define CLOCK_REALTIME 0 +#define CLOCK_MONOTONIC 1 int clock_gettime(clockid_t clock_id, struct timespec *tp); diff --git a/deps/MsvcLibX/src/clock_gettime.c b/deps/MsvcLibX/src/clock_gettime.c index fee7532e2e552ec08b615e61e3f4d79276ea6cfc..cbddf7107ae3733186c014c26a769f3f9d386d0e 100644 --- a/deps/MsvcLibX/src/clock_gettime.c +++ b/deps/MsvcLibX/src/clock_gettime.c @@ -34,15 +34,56 @@ #include "msvcTime.h" #include "sys/msvcStat.h" /* For MsvcLibX's Filetime2Timespec */ -int clock_gettime(clockid_t clock_id, struct timespec *pTS) { - FILETIME ft; - if (clock_id != CLOCK_REALTIME) { - errno = EINVAL; - return -1; +#define MS_PER_SEC 1000ULL // MS = milliseconds +#define US_PER_MS 1000ULL // US = microseconds +#define HNS_PER_US 10ULL // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns) +#define NS_PER_US 1000ULL + +#define HNS_PER_SEC (MS_PER_SEC * US_PER_MS * HNS_PER_US) +#define NS_PER_HNS (100ULL) // NS = nanoseconds +#define NS_PER_SEC (MS_PER_SEC * US_PER_MS * NS_PER_US) + +int clock_gettime_monotonic(struct timespec *tv) { + static LARGE_INTEGER ticksPerSec; + LARGE_INTEGER ticks; + double seconds; + + if (!ticksPerSec.QuadPart) { + QueryPerformanceFrequency(&ticksPerSec); + if (!ticksPerSec.QuadPart) { + errno = ENOTSUP; + return -1; + } } + + QueryPerformanceCounter(&ticks); + + seconds = (double) ticks.QuadPart / (double) ticksPerSec.QuadPart; + tv->tv_sec = (time_t)seconds; + tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC); + + return 0; +} + +int clock_gettime_realtime(struct timespec *pTS) { + FILETIME ft; + GetSystemTimeAsFileTime(&ft); Filetime2Timespec(&ft, pTS); + return 0; } +int clock_gettime(clockid_t clock_id, struct timespec *pTS) { + if (clock_id == CLOCK_MONOTONIC) { + return clock_gettime_monotonic(pTS); + } else if (clock_id == CLOCK_REALTIME) { + return clock_gettime_realtime(pTS); + } + + errno = ENOTSUP; + + return -1; +} + #endif /* defined(_WIN32) */ diff --git a/deps/rmonotonic/CMakeLists.txt b/deps/rmonotonic/CMakeLists.txt index 5433f405d094bf30c36b7a09743ca59906aff1fb..119b3c31143c086628e05a5c5eb46793d291fc67 100644 --- a/deps/rmonotonic/CMakeLists.txt +++ b/deps/rmonotonic/CMakeLists.txt @@ -4,3 +4,4 @@ add_definitions(-DUSE_PROCESSOR_CLOCK) ADD_LIBRARY(rmonotonic ${SOURCE_LIST}) TARGET_INCLUDE_DIRECTORIES(rmonotonic PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/inc) +TARGET_LINK_LIBRARIES(rmonotonic MsvcLibXw) diff --git a/deps/rmonotonic/inc/monotonic.h b/deps/rmonotonic/inc/monotonic.h index d7741233c603b338b58e534c634e7f528a19d4be..0850548d36629b0b1bfba04e818937e275cac5bf 100644 --- a/deps/rmonotonic/inc/monotonic.h +++ b/deps/rmonotonic/inc/monotonic.h @@ -15,6 +15,10 @@ #include //#include +#if defined(_WIN32) || defined(_WIN64) + #define inline +#endif + /* A counter in micro-seconds. The 'monotime' type is provided for variables * holding a monotonic time. This will help distinguish & document that the * variable is associated with the monotonic clock and should not be confused diff --git a/deps/rmonotonic/src/clock_gettime_win.c b/deps/rmonotonic/src/clock_gettime_win.c deleted file mode 100644 index 98a1baaf394d162cd8339707577efcb17fd07b5f..0000000000000000000000000000000000000000 --- a/deps/rmonotonic/src/clock_gettime_win.c +++ /dev/null @@ -1,72 +0,0 @@ -#if defined(_WIN32) || defined(_WIN64) -#include -#include - -#define MS_PER_SEC 1000ULL // MS = milliseconds -#define US_PER_MS 1000ULL // US = microseconds -#define HNS_PER_US 10ULL // HNS = hundred-nanoseconds (e.g., 1 hns = 100 ns) -#define NS_PER_US 1000ULL - -#define HNS_PER_SEC (MS_PER_SEC * US_PER_MS * HNS_PER_US) -#define NS_PER_HNS (100ULL) // NS = nanoseconds -#define NS_PER_SEC (MS_PER_SEC * US_PER_MS * NS_PER_US) - -int clock_gettime_monotonic(struct timespec *tv) -{ - static LARGE_INTEGER ticksPerSec; - LARGE_INTEGER ticks; - double seconds; - - if (!ticksPerSec.QuadPart) { - QueryPerformanceFrequency(&ticksPerSec); - if (!ticksPerSec.QuadPart) { - errno = ENOTSUP; - return -1; - } - } - - QueryPerformanceCounter(&ticks); - - seconds = (double) ticks.QuadPart / (double) ticksPerSec.QuadPart; - tv->tv_sec = (time_t)seconds; - tv->tv_nsec = (long)((ULONGLONG)(seconds * NS_PER_SEC) % NS_PER_SEC); - - return 0; -} - -int clock_gettime_realtime(struct timespec *tv) -{ - FILETIME ft; - ULARGE_INTEGER hnsTime; - - GetSystemTimeAsFileTime(&ft); - - hnsTime.LowPart = ft.dwLowDateTime; - hnsTime.HighPart = ft.dwHighDateTime; - - // To get POSIX Epoch as baseline, subtract the number of hns intervals from Jan 1, 1601 to Jan 1, 1970. - hnsTime.QuadPart -= (11644473600ULL * HNS_PER_SEC); - - // modulus by hns intervals per second first, then convert to ns, as not to lose resolution - tv->tv_nsec = (long) ((hnsTime.QuadPart % HNS_PER_SEC) * NS_PER_HNS); - tv->tv_sec = (long) (hnsTime.QuadPart / HNS_PER_SEC); - - return 0; -} - -int clock_gettime(clockid_t type, struct timespec *tp) -{ - if (type == CLOCK_MONOTONIC) - { - return clock_gettime_monotonic(tp); - } - else if (type == CLOCK_REALTIME) - { - return clock_gettime_realtime(tp); - } - - errno = ENOTSUP; - return -1; -} - -#endif diff --git a/deps/rmonotonic/src/monotonic.c b/deps/rmonotonic/src/monotonic.c index 5bb4f03bfc9da57853290152571573a6bb10ebe9..37023ce2733f7b28b5029df5d4f5317539d66ee7 100644 --- a/deps/rmonotonic/src/monotonic.c +++ b/deps/rmonotonic/src/monotonic.c @@ -7,6 +7,8 @@ #undef NDEBUG #include +#include "msvcTime.h" +#include "msvcStdio.h" /* The function pointer for clock retrieval. */ monotime (*getMonotonicUs)(void) = NULL; @@ -129,8 +131,7 @@ static void monotonicInit_aarch64() { } #endif - -static monotime getMonotonicUs_posix() { +static monotime getMonotonicUs_posix(void) { /* clock_gettime() is specified in POSIX.1b (1993). Even so, some systems * did not support this until much later. CLOCK_MONOTONIC is technically * optional and may not be supported - but it appears to be universal.