Commit 621eb003094ca6acd5aab0cc01ed4e407101a658

Con Kolivas 2013-08-18T10:49:52

Provide reentrant versions of cgsleep functions to allow start time to be set separately from the beginning of the actual sleep, allowing scheduling delays to be counted in the sleep.

diff --git a/util.c b/util.c
index 6b72823..43f5005 100644
--- a/util.c
+++ b/util.c
@@ -911,6 +911,38 @@ void cgsleep_us(int64_t us)
 	} while (ret == EINTR);
 }
 
+/* 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_prepare_r(struct timespec *ts_start)
+{
+	clock_gettime(CLOCK_MONOTONIC, ts_start);
+}
+
+void cgsleep_ms_r(struct timespec *ts_start, int ms)
+{
+	struct timespec ts_end;
+	int ret;
+
+	ms_to_timespec(&ts_end, ms);
+	timeraddspec(&ts_end, ts_start);
+	do {
+		ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts_end, NULL);
+	} while (ret == EINTR);
+}
+
+void cgsleep_us_r(struct timespec *ts_start, int us)
+{
+	struct timespec ts_end;
+	int ret;
+
+	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)
diff --git a/util.h b/util.h
index 9d8e90f..e88492b 100644
--- a/util.h
+++ b/util.h
@@ -86,6 +86,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, int 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);