From 79ca14f5e8008649ac9a74790ee1bbc3b8a34aef Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 25 Aug 2013 15:17:34 +1000 Subject: [PATCH] Provide an osx fix for cgtimers and a fallback to timevals for all other platforms !linux !win32 !osx. --- util.c | 105 ++++++++++++++++++++++++++++++++++----------------------- 1 file changed, 63 insertions(+), 42 deletions(-) diff --git a/util.c b/util.c index 8b272553..504bcb1c 100644 --- a/util.c +++ b/util.c @@ -914,17 +914,60 @@ static void __maybe_unused cgsleep_spec(struct timespec *ts_diff, const struct t nanosleep(ts_diff, NULL); } +int cgtimer_to_ms(cgtimer_t *cgt) +{ + return timespec_to_ms(cgt); +} + /* These are cgminer specific sleep functions that use an absolute nanosecond * resolution timer to avoid poor usleep accuracy and overruns. */ -#ifndef WIN32 +#ifdef WIN32 +/* Windows start time is since 1601 LOL so convert it to unix epoch 1970. */ +#define EPOCHFILETIME (116444736000000000LL) + +/* Return the system time as an lldiv_t in decimicroseconds. */ +static void decius_time(lldiv_t *lidiv) +{ + FILETIME ft; + LARGE_INTEGER li; + + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + li.QuadPart -= EPOCHFILETIME; + + /* SystemTime is in decimicroseconds so divide by an unusual number */ + *lidiv = lldiv(li.QuadPart, 10000000); +} + /* This is a cgminer gettimeofday wrapper. Since we always call gettimeofday * with tz set to NULL, and windows' default resolution is only 15ms, this * gives us higher resolution times on windows. */ void cgtime(struct timeval *tv) +{ + lldiv_t lidiv; + + decius_time(&lidiv); + tv->tv_sec = lidiv.quot; + tv->tv_usec = lidiv.rem / 10; +} + +void cgtimer_time(cgtimer_t *ts_start) +{ + lldiv_t lidiv;; + + decius_time(&lidiv); + ts_start->tv_sec = lidiv.quot; + ts_start->tv_nsec = lidiv.quot * 100; +} +#else /* WIN32 */ +void cgtime(struct timeval *tv) { gettimeofday(tv, NULL); } +#endif /* WIN32 */ +#ifdef CLOCK_MONOTONIC /* Essentially just linux */ void cgtimer_time(cgtimer_t *ts_start) { clock_gettime(CLOCK_MONOTONIC, ts_start); @@ -959,48 +1002,31 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us) timeraddspec(&ts_end, ts_start); nanosleep_abstime(&ts_end); } - -int cgtimer_to_ms(cgtimer_t *cgt) -{ - return timespec_to_ms(cgt); -} -#else -/* Windows start time is since 1601 lol so convert it to unix epoch 1970. */ -#define EPOCHFILETIME (116444736000000000LL) - -/* Return the system time as an lldiv_t in decimicroseconds. */ -static void decius_time(lldiv_t *lidiv) -{ - FILETIME ft; - LARGE_INTEGER li; - - GetSystemTimeAsFileTime(&ft); - li.LowPart = ft.dwLowDateTime; - li.HighPart = ft.dwHighDateTime; - li.QuadPart -= EPOCHFILETIME; - - /* SystemTime is in decimicroseconds so divide by an unusual number */ - *lidiv = lldiv(li.QuadPart, 10000000); -} - -void cgtime(struct timeval *tv) +#else /* CLOCK_MONOTONIC */ +#ifdef __MACH__ +#include +#include +void cgtimer_time(cgtimer_t *ts_start) { - lldiv_t lidiv; + clock_serv_t cclock; + mach_timespec_t mts; - decius_time(&lidiv); - tv->tv_sec = lidiv.quot; - tv->tv_usec = lidiv.rem / 10; + host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); + clock_get_time(cclock, &mts); + mach_port_deallocate(mach_task_self(), cclock); + ts->tv_sec = mts.tv_sec; + ts->tv_nsec = mts.tv_nsec; } - +#else /* __MACH__ - Everything not linux/macosx/win32 */ void cgtimer_time(cgtimer_t *ts_start) { - lldiv_t lidiv;; + struct timeval tv; - decius_time(&lidiv); - ts_start->tv_sec = lidiv.quot; - ts_start->tv_nsec = lidiv.quot * 100; + cgtime(&tv); + ts_start->tv_sec = tv->tv_sec; + ts_start->tv_nsec = tv->tv_usec * 1000; } - +#endif /* __MACH__ */ void cgsleep_ms_r(cgtimer_t *ts_start, int ms) { struct timespec ts_diff; @@ -1016,12 +1042,7 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us) us_to_timespec(&ts_diff, us); cgsleep_spec(&ts_diff, ts_start); } - -int cgtimer_to_ms(cgtimer_t *cgt) -{ - return timespec_to_ms(cgt); -} -#endif +#endif /* CLOCK_MONOTONIC */ void cgsleep_ms(int ms) {