Commit 09e9091dd7b1b63aec82e9ece47511f5810a29cd

Con Kolivas 2013-08-19T13:54:56

Simplify cgsleep code for windows by using a typedef for cgtimer_t that resolves to clock resolution, using that internally.

diff --git a/driver-avalon.c b/driver-avalon.c
index 6d72c13..6d5276a 100644
--- a/driver-avalon.c
+++ b/driver-avalon.c
@@ -147,7 +147,7 @@ static int avalon_send_task(const struct avalon_task *at, struct cgpu_info *aval
 	uint8_t buf[AVALON_WRITE_SIZE + 4 * AVALON_DEFAULT_ASIC_NUM];
 	int delay, ret, i, ep = C_AVALON_TASK;
 	struct avalon_info *info;
-	struct timespec ts_start;
+	cgtimer_t ts_start;
 	uint32_t nonce_range;
 	size_t nr_len;
 
@@ -865,7 +865,7 @@ static void *avalon_get_results(void *userdata)
 	const int rsize = AVALON_FTDI_READSIZE;
 	char readbuf[AVALON_READBUF_SIZE];
 	struct thr_info *thr = info->thr;
-	struct timespec ts_start;
+	cgtimer_t ts_start;
 	int offset = 0, ret = 0;
 	char threadname[24];
 
@@ -1015,7 +1015,7 @@ static void *avalon_send_tasks(void *userdata)
 
 	while (likely(!avalon->shutdown)) {
 		int start_count, end_count, i, j, ret;
-		struct timespec ts_start;
+		cgtimer_t ts_start;
 		struct avalon_task at;
 		bool idled = false;
 		int64_t us_timeout;
diff --git a/driver-bflsc.c b/driver-bflsc.c
index 57166f3..6df5fca 100644
--- a/driver-bflsc.c
+++ b/driver-bflsc.c
@@ -1401,7 +1401,7 @@ static void *bflsc_get_results(void *userdata)
 	}
 
 	while (sc_info->shutdown == false) {
-		struct timespec ts_start;
+		cgtimer_t ts_start;
 
 		if (bflsc->usbinfo.nodev)
 			return NULL;
diff --git a/util.c b/util.c
index 2f92a61..95419c5 100644
--- a/util.c
+++ b/util.c
@@ -906,7 +906,7 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
 /* These are cgminer specific sleep functions that use an absolute nanosecond
  * resolution timer to avoid poor usleep accuracy and overruns. */
 #ifndef WIN32
-void cgsleep_prepare_r(struct timespec *ts_start)
+void cgsleep_prepare_r(cgtimer_t *ts_start)
 {
 	clock_gettime(CLOCK_MONOTONIC, ts_start);
 }
@@ -919,74 +919,70 @@ static void nanosleep_abstime(struct timespec *ts_end)
 		ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts_end, NULL);
 	} while (ret == EINTR);
 }
-#else
-static void dtime_to_timespec(struct timespec *ts, DWORD dtime)
+
+/* Reentrant version of cgsleep functions allow start time to be set separately
+ * from the beginning of the actual sleep, allowing scheduling delays to be
+ * counted in the sleep. */
+void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
 {
-	ldiv_t tsdiv = ldiv(dtime, 1000);
+	struct timespec ts_end;
 
-	ts->tv_sec = tsdiv.quot;
-	ts->tv_nsec = tsdiv.rem * 1000000;
+	ms_to_timespec(&ts_end, ms);
+	timeraddspec(&ts_end, ts_start);
+	nanosleep_abstime(&ts_end);
 }
 
-static DWORD timespec_to_dtime(const struct timespec *ts)
+void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
 {
-	DWORD ret;
+	struct timespec ts_end;
 
-	ret = ts->tv_sec * 1000;
-	ret += ts->tv_nsec / 1000000;
-	return ret;
+	us_to_timespec(&ts_end, us);
+	timeraddspec(&ts_end, ts_start);
+	nanosleep_abstime(&ts_end);
 }
 
-void cgsleep_prepare_r(struct timespec *ts_start)
+#else
+static void dtime_to_timespec(struct timespec *ts, DWORD dtime)
 {
-	DWORD dtime;
+	ldiv_t tsdiv = ldiv(dtime, 1000);
+
+	ts->tv_sec = tsdiv.quot;
+	ts->tv_nsec = tsdiv.rem * 1000000;
+}
 
+void cgsleep_prepare_r(cgtimer_t *ts_start)
+{
 	timeBeginPeriod(1);
-	dtime = timeGetTime();
-	dtime_to_timespec(ts_start, dtime);
+	*ts_start = timeGetTime();
 }
 
-static void nanosleep_abstime(struct timespec *ts_end)
+void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
 {
-	DWORD now_ms, end_ms, diff_ms;
+	DWORD dnow, dend, ddiff;
 	struct timespec ts_diff;
 
-	end_ms = timespec_to_dtime(ts_end);
-	now_ms = timeGetTime();
-	if (unlikely(now_ms >= end_ms))
+	dend = *ts_start + ms;
+	dnow = timeGetTime();
+	if (unlikely(dnow >= dend))
 		goto out;
-	diff_ms = end_ms - now_ms;
-	dtime_to_timespec(&ts_diff, diff_ms);
+	ddiff = dend - dnow;
+	dtime_to_timespec(&ts_diff, ddiff);
 	nanosleep(&ts_diff, NULL);
 out:
 	timeEndPeriod(1);
 }
-#endif
 
-/* Reentrant version of cgsleep functions allow start time to be set separately
- * from the beginning of the actual sleep, allowing scheduling delays to be
- * counted in the sleep. */
-void cgsleep_ms_r(struct timespec *ts_start, int ms)
+void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
 {
-	struct timespec ts_end;
+	int ms = us / 1000;
 
-	ms_to_timespec(&ts_end, ms);
-	timeraddspec(&ts_end, ts_start);
-	nanosleep_abstime(&ts_end);
-}
-
-void cgsleep_us_r(struct timespec *ts_start, int64_t us)
-{
-	struct timespec ts_end;
-
-	us_to_timespec(&ts_end, us);
-	timeraddspec(&ts_end, ts_start);
-	nanosleep_abstime(&ts_end);
+	cgsleep_ms_r(ts_start, ms);
 }
+#endif
 
 void cgsleep_ms(int ms)
 {
-	struct timespec ts_start;
+	cgtimer_t ts_start;
 
 	cgsleep_prepare_r(&ts_start);
 	cgsleep_ms_r(&ts_start, ms);
@@ -994,7 +990,7 @@ void cgsleep_ms(int ms)
 
 void cgsleep_us(int64_t us)
 {
-	struct timespec ts_start;
+	cgtimer_t ts_start;
 
 	cgsleep_prepare_r(&ts_start);
 	cgsleep_us_r(&ts_start, us);
diff --git a/util.h b/util.h
index 7160f54..ed1f57f 100644
--- a/util.h
+++ b/util.h
@@ -20,6 +20,7 @@
 	{
 		return (errno == EAGAIN || errno == EWOULDBLOCK);
 	}
+	typedef struct timespec cgtimer_t;
 #elif defined WIN32
 	#include <ws2tcpip.h>
 	#include <winsock2.h>
@@ -44,6 +45,7 @@
 	#ifndef in_addr_t
 	#define in_addr_t uint32_t
 	#endif
+	typedef DWORD cgtimer_t;
 #endif
 
 #if JANSSON_MAJOR_VERSION >= 2
@@ -86,9 +88,9 @@ void ms_to_timespec(struct timespec *spec, int64_t ms);
 void timeraddspec(struct timespec *a, const struct timespec *b);
 void cgsleep_ms(int ms);
 void cgsleep_us(int64_t us);
-void cgsleep_prepare_r(struct timespec *ts_start);
-void cgsleep_ms_r(struct timespec *ts_start, int ms);
-void cgsleep_us_r(struct timespec *ts_start, int64_t us);
+void cgsleep_prepare_r(cgtimer_t *ts_start);
+void cgsleep_ms_r(cgtimer_t *ts_start, int ms);
+void cgsleep_us_r(cgtimer_t *ts_start, int64_t us);
 double us_tdiff(struct timeval *end, struct timeval *start);
 double tdiff(struct timeval *end, struct timeval *start);
 bool stratum_send(struct pool *pool, char *s, ssize_t len);