From 0b5edb24f9be881a26588b84fa1a713a757c9906 Mon Sep 17 00:00:00 2001 From: Con Kolivas Date: Sun, 18 Aug 2013 10:36:25 +1000 Subject: [PATCH] Make the nmsleep and nusleep functions use the new cgsleep functions internally till functions are migrated to the new cgsleep API. --- util.c | 87 +++++++++++++++++++++++++++------------------------------- util.h | 1 + 2 files changed, 41 insertions(+), 47 deletions(-) diff --git a/util.c b/util.c index 77956e30..6b728236 100644 --- a/util.c +++ b/util.c @@ -804,53 +804,6 @@ void thr_info_cancel(struct thr_info *thr) cgsem_destroy(&thr->sem); } -/* Provide a ms based sleep that uses nanosleep to avoid poor usleep accuracy - * on SMP machines */ -void nmsleep(unsigned int msecs) -{ - struct timespec twait, tleft; - int ret; - ldiv_t d; - -#ifdef WIN32 - timeBeginPeriod(1); -#endif - d = ldiv(msecs, 1000); - tleft.tv_sec = d.quot; - tleft.tv_nsec = d.rem * 1000000; - do { - twait.tv_sec = tleft.tv_sec; - twait.tv_nsec = tleft.tv_nsec; - ret = nanosleep(&twait, &tleft); - } while (ret == -1 && errno == EINTR); -#ifdef WIN32 - timeEndPeriod(1); -#endif -} - -/* Same for usecs */ -void nusleep(unsigned int usecs) -{ - struct timespec twait, tleft; - int ret; - ldiv_t d; - -#ifdef WIN32 - timeBeginPeriod(1); -#endif - d = ldiv(usecs, 1000000); - tleft.tv_sec = d.quot; - tleft.tv_nsec = d.rem * 1000; - do { - twait.tv_sec = tleft.tv_sec; - twait.tv_nsec = tleft.tv_nsec; - ret = nanosleep(&twait, &tleft); - } while (ret == -1 && errno == EINTR); -#ifdef WIN32 - timeEndPeriod(1); -#endif -} - /* 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. */ @@ -930,6 +883,8 @@ void timeraddspec(struct timespec *a, const struct timespec *b) } } +/* These are cgminer specific sleep functions that use an absolute nanosecond + * resolution timer to avoid pool usleep accuracy and overruns. */ void cgsleep_ms(int ms) { struct timespec ts_start, ts_end; @@ -943,6 +898,44 @@ void cgsleep_ms(int ms) } while (ret == EINTR); } +void cgsleep_us(int64_t us) +{ + struct timespec ts_start, ts_end; + int ret; + + clock_gettime(CLOCK_MONOTONIC, &ts_start); + us_to_timespec(&ts_end, us); + timeraddspec(&ts_end, &ts_start); + do { + ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts_end, NULL); + } while (ret == EINTR); +} + +/* Provide a ms based sleep that uses nanosleep to avoid poor usleep accuracy + * on SMP machines */ +void nmsleep(unsigned int msecs) +{ +#ifdef WIN32 + timeBeginPeriod(1); +#endif + cgsleep_ms((int)msecs); +#ifdef WIN32 + timeEndPeriod(1); +#endif +} + +/* Same for usecs */ +void nusleep(unsigned int usecs) +{ +#ifdef WIN32 + timeBeginPeriod(1); +#endif + cgsleep_us((int64_t)usecs); +#ifdef WIN32 + timeEndPeriod(1); +#endif +} + /* Returns the microseconds difference between end and start times as a double */ double us_tdiff(struct timeval *end, struct timeval *start) { diff --git a/util.h b/util.h index e5d2e44e..9d8e90f4 100644 --- a/util.h +++ b/util.h @@ -85,6 +85,7 @@ void us_to_timespec(struct timespec *spec, int64_t us); 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); 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);