Commit 79ca14f5e8008649ac9a74790ee1bbc3b8a34aef

Con Kolivas 2013-08-25T15:17:34

Provide an osx fix for cgtimers and a fallback to timevals for all other platforms !linux !win32 !osx.

diff --git a/util.c b/util.c
index 8b27255..504bcb1 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 <mach/clock.h>
+#include <mach/mach.h>
+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)
 {