Browse Source

Add a ms_to_timespec helper function, and create a cgsleep_ms function that uses absolute timers with clock_nanosleep to avoid overruns.

Con Kolivas 12 years ago
parent
commit
188210a3d2
2 changed files with 21 additions and 0 deletions
  1. 19 0
      util.c
  2. 2 0
      util.h

+ 19 - 0
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)
 {

+ 2 - 0
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);