Use timespecs on windows as cgtimer_t to capitalise on the higher resolution clock changes.
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 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145
diff --git a/util.c b/util.c
index 2fbe7c0..ac59361 100644
--- a/util.c
+++ b/util.c
@@ -875,6 +875,11 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
}
}
+static int timespec_to_ms(struct timespec *ts)
+{
+ return ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
+}
+
/* These are cgminer specific sleep functions that use an absolute nanosecond
* resolution timer to avoid poor usleep accuracy and overruns. */
#ifndef WIN32
@@ -913,11 +918,6 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
nanosleep_abstime(&ts_end);
}
-static int timespec_to_ms(struct timespec *ts)
-{
- return ts->tv_sec * 1000 + ts->tv_nsec / 1000000;
-}
-
int cgtimer_to_ms(cgtimer_t *cgt)
{
return timespec_to_ms(cgt);
@@ -971,52 +971,65 @@ void cgtime(struct timeval *tv)
void cgtimer_time(cgtimer_t *ts_start)
{
- cgtime(ts_start);
+ lldiv_t lidiv;;
+
+ decius_time(&lidiv);
+ ts_start->tv_sec = lidiv.quot;
+ ts_start->tv_nsec = lidiv.quot * 100;
}
-static void ms_to_timeval(struct timeval *val, int ms)
+/* Subtract b from a */
+static void timersubspec(struct timespec *a, const struct timespec *b)
{
- ldiv_t tvdiv = ldiv(ms, 1000);
-
- val->tv_sec = tvdiv.quot;
- val->tv_usec = tvdiv.rem * 1000;
+ a->tv_sec -= b->tv_sec;
+ a->tv_nsec -= b->tv_nsec;
+ if (a->tv_nsec < 0) {
+ a->tv_nsec += 1000000000;
+ a->tv_sec--;
+ }
}
-void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
+static void cgsleep_spec(struct timespec *ts_diff, const struct timespec *ts_start)
{
- struct timeval now, tv_end, tv_diff;
- struct timespec ts_diff;
+ struct timespec now;
- ms_to_timeval(&tv_diff, ms);
- timeradd(ts_start, &tv_diff, &tv_end);
- cgtime(&now);
- if (unlikely(time_more(&now, &tv_end)))
+ timeraddspec(ts_diff, ts_start);
+ cgtimer_time(&now);
+ timersubspec(ts_diff, &now);
+ if (unlikely(ts_diff->tv_sec < 0))
return;
- timersub(&tv_end, &now, &tv_diff);
- timeval_to_spec(&ts_diff, &tv_diff);
- nanosleep(&ts_diff, NULL);
+ nanosleep(ts_diff, NULL);
}
-void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
+void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
{
- int ms = us / 1000;
+ struct timespec ts_diff;
- cgsleep_ms_r(ts_start, ms);
+ ms_to_timespec(&ts_diff, ms);
+ cgsleep_spec(&ts_diff, ts_start);
}
-static int timeval_to_ms(struct timeval *tv)
+void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
{
- return tv->tv_sec * 1000 + tv->tv_usec / 1000;
+ struct timespec ts_diff;
+
+ us_to_timespec(&ts_diff, us);
+ cgsleep_spec(&ts_diff, ts_start);
}
int cgtimer_to_ms(cgtimer_t *cgt)
{
- return timeval_to_ms(cgt);
+ return timespec_to_ms(cgt);
}
void cgtimer_sub(cgtimer_t *a, cgtimer_t *b, cgtimer_t *res)
{
- timersub(a, b, res);
+ res->tv_sec = a->tv_sec - b->tv_sec;
+ res->tv_nsec = a->tv_nsec - b->tv_nsec;
+ if (res->tv_nsec < 0) {
+ res->tv_nsec += 1000000000;;
+ res->tv_sec--;
+ }
}
#endif
diff --git a/util.h b/util.h
index faa3ae4..f083f20 100644
--- a/util.h
+++ b/util.h
@@ -20,7 +20,6 @@
{
return (errno == EAGAIN || errno == EWOULDBLOCK);
}
- typedef struct timespec cgtimer_t;
#elif defined WIN32
#include <ws2tcpip.h>
#include <winsock2.h>
@@ -45,7 +44,6 @@
#ifndef in_addr_t
#define in_addr_t uint32_t
#endif
- typedef struct timeval cgtimer_t;
#endif
#if JANSSON_MAJOR_VERSION >= 2
@@ -65,6 +63,7 @@ typedef struct cgsem cgsem_t;
#else
typedef sem_t cgsem_t;
#endif
+typedef struct timespec cgtimer_t;
struct thr_info;
struct pool;