Commit e1433f8ef89b17004b83b307bc9f6e4f1cdfd828

Con Kolivas 2013-08-22T13:49:22

Use timespecs on windows as cgtimer_t to capitalise on the higher resolution clock changes.

diff --git a/util.c b/util.c
index 2fbe7c0..ac59361 100644
--- a/util.c
+++ b/util.c
@@ -875,6 +875,11 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
 	}
 }
 
+static int timespec_to_ms(struct timespec *ts)
+{
+	return ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
+}
+
 /* These are cgminer specific sleep functions that use an absolute nanosecond
  * resolution timer to avoid poor usleep accuracy and overruns. */
 #ifndef WIN32
@@ -913,11 +918,6 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
 	nanosleep_abstime(&ts_end);
 }
 
-static int timespec_to_ms(struct timespec *ts)
-{
-	return ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
-}
-
 int cgtimer_to_ms(cgtimer_t *cgt)
 {
 	return timespec_to_ms(cgt);
@@ -971,52 +971,65 @@ void cgtime(struct timeval *tv)
 
 void cgtimer_time(cgtimer_t *ts_start)
 {
-	cgtime(ts_start);
+	lldiv_t lidiv;;
+
+	decius_time(&lidiv);
+	ts_start->tv_sec = lidiv.quot;
+	ts_start->tv_nsec = lidiv.quot * 100;
 }
 
-static void ms_to_timeval(struct timeval *val, int ms)
+/* Subtract b from a */
+static void timersubspec(struct timespec *a, const struct timespec *b)
 {
-	ldiv_t tvdiv = ldiv(ms, 1000);
-
-	val->tv_sec = tvdiv.quot;
-	val->tv_usec = tvdiv.rem * 1000;
+	a->tv_sec -= b->tv_sec;
+	a->tv_nsec -= b->tv_nsec;
+	if (a->tv_nsec < 0) {
+		a->tv_nsec += 1000000000;
+		a->tv_sec--;
+	}
 }
 
-void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
+static void cgsleep_spec(struct timespec *ts_diff, const struct timespec *ts_start)
 {
-	struct timeval now, tv_end, tv_diff;
-	struct timespec ts_diff;
+	struct timespec now;
 
-	ms_to_timeval(&tv_diff, ms);
-	timeradd(ts_start, &tv_diff, &tv_end);
-	cgtime(&now);
-	if (unlikely(time_more(&now, &tv_end)))
+	timeraddspec(ts_diff, ts_start);
+	cgtimer_time(&now);
+	timersubspec(ts_diff, &now);
+	if (unlikely(ts_diff->tv_sec < 0))
 		return;
-	timersub(&tv_end, &now, &tv_diff);
-	timeval_to_spec(&ts_diff, &tv_diff);
-	nanosleep(&ts_diff, NULL);
+	nanosleep(ts_diff, NULL);
 }
 
-void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
+void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
 {
-	int ms = us / 1000;
+	struct timespec ts_diff;
 
-	cgsleep_ms_r(ts_start, ms);
+	ms_to_timespec(&ts_diff, ms);
+	cgsleep_spec(&ts_diff, ts_start);
 }
 
-static int timeval_to_ms(struct timeval *tv)
+void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
 {
-	return tv->tv_sec * 1000 + tv->tv_usec / 1000;
+	struct timespec ts_diff;
+
+	us_to_timespec(&ts_diff, us);
+	cgsleep_spec(&ts_diff, ts_start);
 }
 
 int cgtimer_to_ms(cgtimer_t *cgt)
 {
-	return timeval_to_ms(cgt);
+	return timespec_to_ms(cgt);
 }
 
 void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res)
 {
-	timersub(a, b, res);
+	res->tv_sec = a->tv_sec - b->tv_sec;
+	res->tv_nsec = a->tv_nsec - b->tv_nsec;
+	if (res->tv_nsec < 0) {
+		res->tv_nsec += 1000000000;;
+		res->tv_sec--;
+	}
 }
 #endif
 
diff --git a/util.h b/util.h
index faa3ae4..f083f20 100644
--- a/util.h
+++ b/util.h
@@ -20,7 +20,6 @@
 	{
 		return (errno == EAGAIN || errno == EWOULDBLOCK);
 	}
-	typedef struct timespec cgtimer_t;
 #elif defined WIN32
 	#include <ws2tcpip.h>
 	#include <winsock2.h>
@@ -45,7 +44,6 @@
 	#ifndef in_addr_t
 	#define in_addr_t uint32_t
 	#endif
-	typedef struct timeval cgtimer_t;
 #endif
 
 #if JANSSON_MAJOR_VERSION >= 2
@@ -65,6 +63,7 @@ typedef struct cgsem cgsem_t;
 #else
 typedef sem_t cgsem_t;
 #endif
+typedef struct timespec cgtimer_t;
 
 struct thr_info;
 struct pool;