Browse Source

Provide an osx fix for cgtimers and a fallback to timevals for all other platforms !linux !win32 !osx.

nfactor-troky
Con Kolivas 11 years ago
parent
commit
79ca14f5e8
  1. 105
      util.c

105
util.c

@ -914,17 +914,60 @@ static void __maybe_unused cgsleep_spec(struct timespec *ts_diff, const struct t @@ -914,17 +914,60 @@ static void __maybe_unused cgsleep_spec(struct timespec *ts_diff, const struct t
nanosleep(ts_diff, NULL);
}
int cgtimer_to_ms(cgtimer_t *cgt)
{
return timespec_to_ms(cgt);
}
/* These are cgminer specific sleep functions that use an absolute nanosecond
* resolution timer to avoid poor usleep accuracy and overruns. */
#ifndef WIN32
#ifdef WIN32
/* Windows start time is since 1601 LOL so convert it to unix epoch 1970. */
#define EPOCHFILETIME (116444736000000000LL)
/* Return the system time as an lldiv_t in decimicroseconds. */
static void decius_time(lldiv_t *lidiv)
{
FILETIME ft;
LARGE_INTEGER li;
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
li.QuadPart -= EPOCHFILETIME;
/* SystemTime is in decimicroseconds so divide by an unusual number */
*lidiv = lldiv(li.QuadPart, 10000000);
}
/* This is a cgminer gettimeofday wrapper. Since we always call gettimeofday
* with tz set to NULL, and windows' default resolution is only 15ms, this
* gives us higher resolution times on windows. */
void cgtime(struct timeval *tv)
{
lldiv_t lidiv;
decius_time(&lidiv);
tv->tv_sec = lidiv.quot;
tv->tv_usec = lidiv.rem / 10;
}
void cgtimer_time(cgtimer_t *ts_start)
{
lldiv_t lidiv;;
decius_time(&lidiv);
ts_start->tv_sec = lidiv.quot;
ts_start->tv_nsec = lidiv.quot * 100;
}
#else /* WIN32 */
void cgtime(struct timeval *tv)
{
gettimeofday(tv, NULL);
}
#endif /* WIN32 */
#ifdef CLOCK_MONOTONIC /* Essentially just linux */
void cgtimer_time(cgtimer_t *ts_start)
{
clock_gettime(CLOCK_MONOTONIC, ts_start);
@ -959,48 +1002,31 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us) @@ -959,48 +1002,31 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
timeraddspec(&ts_end, ts_start);
nanosleep_abstime(&ts_end);
}
int cgtimer_to_ms(cgtimer_t *cgt)
{
return timespec_to_ms(cgt);
}
#else
/* Windows start time is since 1601 lol so convert it to unix epoch 1970. */
#define EPOCHFILETIME (116444736000000000LL)
/* Return the system time as an lldiv_t in decimicroseconds. */
static void decius_time(lldiv_t *lidiv)
{
FILETIME ft;
LARGE_INTEGER li;
GetSystemTimeAsFileTime(&ft);
li.LowPart = ft.dwLowDateTime;
li.HighPart = ft.dwHighDateTime;
li.QuadPart -= EPOCHFILETIME;
/* SystemTime is in decimicroseconds so divide by an unusual number */
*lidiv = lldiv(li.QuadPart, 10000000);
}
void cgtime(struct timeval *tv)
#else /* CLOCK_MONOTONIC */
#ifdef __MACH__
#include <mach/clock.h>
#include <mach/mach.h>
void cgtimer_time(cgtimer_t *ts_start)
{
lldiv_t lidiv;
clock_serv_t cclock;
mach_timespec_t mts;
decius_time(&lidiv);
tv->tv_sec = lidiv.quot;
tv->tv_usec = lidiv.rem / 10;
host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
ts->tv_sec = mts.tv_sec;
ts->tv_nsec = mts.tv_nsec;
}
#else /* __MACH__ - Everything not linux/macosx/win32 */
void cgtimer_time(cgtimer_t *ts_start)
{
lldiv_t lidiv;;
struct timeval tv;
decius_time(&lidiv);
ts_start->tv_sec = lidiv.quot;
ts_start->tv_nsec = lidiv.quot * 100;
cgtime(&tv);
ts_start->tv_sec = tv->tv_sec;
ts_start->tv_nsec = tv->tv_usec * 1000;
}
#endif /* __MACH__ */
void cgsleep_ms_r(cgtimer_t *ts_start, int ms)
{
struct timespec ts_diff;
@ -1016,12 +1042,7 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us) @@ -1016,12 +1042,7 @@ void cgsleep_us_r(cgtimer_t *ts_start, int64_t us)
us_to_timespec(&ts_diff, us);
cgsleep_spec(&ts_diff, ts_start);
}
int cgtimer_to_ms(cgtimer_t *cgt)
{
return timespec_to_ms(cgt);
}
#endif
#endif /* CLOCK_MONOTONIC */
void cgsleep_ms(int ms)
{

Loading…
Cancel
Save