|
|
|
@ -906,7 +906,7 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
@@ -906,7 +906,7 @@ void timeraddspec(struct timespec *a, const struct timespec *b)
|
|
|
|
|
/* These are cgminer specific sleep functions that use an absolute nanosecond
|
|
|
|
|
* resolution timer to avoid poor usleep accuracy and overruns. */ |
|
|
|
|
#ifndef WIN32 |
|
|
|
|
void cgsleep_prepare_r(struct timespec *ts_start) |
|
|
|
|
void cgsleep_prepare_r(cgtimer_t *ts_start) |
|
|
|
|
{ |
|
|
|
|
clock_gettime(CLOCK_MONOTONIC, ts_start); |
|
|
|
|
} |
|
|
|
@ -919,74 +919,70 @@ static void nanosleep_abstime(struct timespec *ts_end)
@@ -919,74 +919,70 @@ static void nanosleep_abstime(struct timespec *ts_end)
|
|
|
|
|
ret = clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts_end, NULL); |
|
|
|
|
} while (ret == EINTR); |
|
|
|
|
} |
|
|
|
|
#else |
|
|
|
|
static void dtime_to_timespec(struct timespec *ts, DWORD dtime) |
|
|
|
|
|
|
|
|
|
/* 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_ms_r(cgtimer_t *ts_start, int ms) |
|
|
|
|
{ |
|
|
|
|
ldiv_t tsdiv = ldiv(dtime, 1000); |
|
|
|
|
struct timespec ts_end; |
|
|
|
|
|
|
|
|
|
ts->tv_sec = tsdiv.quot; |
|
|
|
|
ts->tv_nsec = tsdiv.rem * 1000000; |
|
|
|
|
ms_to_timespec(&ts_end, ms); |
|
|
|
|
timeraddspec(&ts_end, ts_start); |
|
|
|
|
nanosleep_abstime(&ts_end); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static DWORD timespec_to_dtime(const struct timespec *ts) |
|
|
|
|
void cgsleep_us_r(cgtimer_t *ts_start, int64_t us) |
|
|
|
|
{ |
|
|
|
|
DWORD ret; |
|
|
|
|
struct timespec ts_end; |
|
|
|
|
|
|
|
|
|
ret = ts->tv_sec * 1000; |
|
|
|
|
ret += ts->tv_nsec / 1000000; |
|
|
|
|
return ret; |
|
|
|
|
us_to_timespec(&ts_end, us); |
|
|
|
|
timeraddspec(&ts_end, ts_start); |
|
|
|
|
nanosleep_abstime(&ts_end); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void cgsleep_prepare_r(struct timespec *ts_start) |
|
|
|
|
#else |
|
|
|
|
static void dtime_to_timespec(struct timespec *ts, DWORD dtime) |
|
|
|
|
{ |
|
|
|
|
DWORD dtime; |
|
|
|
|
ldiv_t tsdiv = ldiv(dtime, 1000); |
|
|
|
|
|
|
|
|
|
ts->tv_sec = tsdiv.quot; |
|
|
|
|
ts->tv_nsec = tsdiv.rem * 1000000; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void cgsleep_prepare_r(cgtimer_t *ts_start) |
|
|
|
|
{ |
|
|
|
|
timeBeginPeriod(1); |
|
|
|
|
dtime = timeGetTime(); |
|
|
|
|
dtime_to_timespec(ts_start, dtime); |
|
|
|
|
*ts_start = timeGetTime(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
static void nanosleep_abstime(struct timespec *ts_end) |
|
|
|
|
void cgsleep_ms_r(cgtimer_t *ts_start, int ms) |
|
|
|
|
{ |
|
|
|
|
DWORD now_ms, end_ms, diff_ms; |
|
|
|
|
DWORD dnow, dend, ddiff; |
|
|
|
|
struct timespec ts_diff; |
|
|
|
|
|
|
|
|
|
end_ms = timespec_to_dtime(ts_end); |
|
|
|
|
now_ms = timeGetTime(); |
|
|
|
|
if (unlikely(now_ms >= end_ms)) |
|
|
|
|
dend = *ts_start + ms; |
|
|
|
|
dnow = timeGetTime(); |
|
|
|
|
if (unlikely(dnow >= dend)) |
|
|
|
|
goto out; |
|
|
|
|
diff_ms = end_ms - now_ms; |
|
|
|
|
dtime_to_timespec(&ts_diff, diff_ms); |
|
|
|
|
ddiff = dend - dnow; |
|
|
|
|
dtime_to_timespec(&ts_diff, ddiff); |
|
|
|
|
nanosleep(&ts_diff, NULL); |
|
|
|
|
out: |
|
|
|
|
timeEndPeriod(1); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
/* 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_ms_r(struct timespec *ts_start, int ms) |
|
|
|
|
void cgsleep_us_r(cgtimer_t *ts_start, int64_t us) |
|
|
|
|
{ |
|
|
|
|
struct timespec ts_end; |
|
|
|
|
int ms = us / 1000; |
|
|
|
|
|
|
|
|
|
ms_to_timespec(&ts_end, ms); |
|
|
|
|
timeraddspec(&ts_end, ts_start); |
|
|
|
|
nanosleep_abstime(&ts_end); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void cgsleep_us_r(struct timespec *ts_start, int64_t us) |
|
|
|
|
{ |
|
|
|
|
struct timespec ts_end; |
|
|
|
|
|
|
|
|
|
us_to_timespec(&ts_end, us); |
|
|
|
|
timeraddspec(&ts_end, ts_start); |
|
|
|
|
nanosleep_abstime(&ts_end); |
|
|
|
|
cgsleep_ms_r(ts_start, ms); |
|
|
|
|
} |
|
|
|
|
#endif |
|
|
|
|
|
|
|
|
|
void cgsleep_ms(int ms) |
|
|
|
|
{ |
|
|
|
|
struct timespec ts_start; |
|
|
|
|
cgtimer_t ts_start; |
|
|
|
|
|
|
|
|
|
cgsleep_prepare_r(&ts_start); |
|
|
|
|
cgsleep_ms_r(&ts_start, ms); |
|
|
|
@ -994,7 +990,7 @@ void cgsleep_ms(int ms)
@@ -994,7 +990,7 @@ void cgsleep_ms(int ms)
|
|
|
|
|
|
|
|
|
|
void cgsleep_us(int64_t us) |
|
|
|
|
{ |
|
|
|
|
struct timespec ts_start; |
|
|
|
|
cgtimer_t ts_start; |
|
|
|
|
|
|
|
|
|
cgsleep_prepare_r(&ts_start); |
|
|
|
|
cgsleep_us_r(&ts_start, us); |
|
|
|
|