Add a ms_to_timespec helper function, and create a cgsleep_ms function that uses absolute timers with clock_nanosleep to avoid overruns.
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
diff --git a/util.c b/util.c
index f6cb924..77956e3 100644
--- a/util.c
+++ b/util.c
@@ -914,6 +914,12 @@ void us_to_timespec(struct timespec *spec, int64_t us)
spec->tv_nsec = (us - (spec->tv_sec * 1000000)) * 1000;
}
+void ms_to_timespec(struct timespec *spec, int64_t ms)
+{
+ spec->tv_sec = ms / 1000;
+ spec->tv_nsec = (ms - (spec->tv_sec * 1000)) * 1000000;
+}
+
void timeraddspec(struct timespec *a, const struct timespec *b)
{
a->tv_sec += b->tv_sec;
@@ -924,6 +930,19 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
}
}
+void cgsleep_ms(int ms)
+{
+ struct timespec ts_start, ts_end;
+ int ret;
+
+ clock_gettime(CLOCK_MONOTONIC, &ts_start);
+ 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);
+}
+
/* 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 12ff7cd..e5d2e44 100644
--- a/util.h
+++ b/util.h
@@ -82,7 +82,9 @@ void timespec_to_val(struct timeval *val, const struct timespec *spec);
void timeval_to_spec(struct timespec *spec, const struct timeval *val);
void us_to_timeval(struct timeval *val, int64_t us);
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);
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);