Make the nmsleep and nusleep functions use the new cgsleep functions internally till functions are migrated to the new cgsleep API.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124
diff --git a/util.c b/util.c
index 77956e3..6b72823 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 e5d2e44..9d8e90f 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);