From 09e9091dd7b1b63aec82e9ece47511f5810a29cd Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Mon, 19 Aug 2013 13:54:56 +1000 Subject: [PATCH] Simplify cgsleep code for windows by using a typedef for cgtimer_t that resolves to clock resolution, using that internally. --- driver-avalon.c | 6 ++-- driver-bflsc.c | 2 +- util.c | 80 +++++++++++++++++++++++-------------------------- util.h | 8 +++-- 4 files changed, 47 insertions(+), 49 deletions(-) diff --git a/driver-avalon.c b/driver-avalon.c index 6d72c13a..6d5276ac 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 57166f3c..6df5fca7 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 2f92a61b..95419c5d 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 7160f545..ed1f57fc 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 #include @@ -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);