Commit ace912ba authored by zhujiashun's avatar zhujiashun

Implement clock_gettime using mach_absolute_time

parent 23d6ecc7
...@@ -27,30 +27,47 @@ ...@@ -27,30 +27,47 @@
#ifdef __MACH__ #ifdef __MACH__
#include <mach/clock.h> #include <mach/clock.h>
#include <mach/mach.h> #include <mach/mach.h>
#include <mach/mach_time.h>
# ifndef clock_gettime # ifndef clock_gettime
# define CLOCK_REALTIME CALENDAR_CLOCK # define CLOCK_REALTIME CALENDAR_CLOCK
# define CLOCK_MONOTONIC SYSTEM_CLOCK # define CLOCK_MONOTONIC SYSTEM_CLOCK
#include <pthread.h>
#include <stdlib.h> // exit
typedef int clockid_t; typedef int clockid_t;
static mach_timebase_info_data_t timebase;
static timespec inittime;
static uint64_t initticks;
static pthread_once_t init_clock_once = PTHREAD_ONCE_INIT;
static void InitClock() {
if (mach_timebase_info(&timebase) != 0) {
exit(1);
}
timeval micro;
if (gettimeofday(&micro, NULL) != 0) {
exit(1);
}
inittime.tv_sec = micro.tv_sec;
inittime.tv_nsec = micro.tv_usec * 1000L;
initticks = mach_absolute_time();
}
// clock_gettime is not available in MacOS < 10.12 // clock_gettime is not available in MacOS < 10.12
inline int clock_gettime(clockid_t id, timespec* time) { inline int clock_gettime(clockid_t id, timespec* time) {
if (id == CLOCK_MONOTONIC) { if (pthread_once(&init_clock_once, InitClock) != 0) {
clock_serv_t cclock; exit(1);
mach_timespec_t mts;
host_get_clock_service(mach_host_self(), id, &cclock);
clock_get_time(cclock, &mts);
mach_port_deallocate(mach_task_self(), cclock);
time->tv_sec = mts.tv_sec;
time->tv_nsec = mts.tv_nsec;
} else if (id == CLOCK_REALTIME) {
struct timeval now;
if (gettimeofday(&now, NULL) < 0) {
return -1;
}
time->tv_sec = now.tv_sec;
time->tv_nsec = now.tv_usec * 1000;
} }
uint64_t clock = mach_absolute_time() - initticks;
uint64_t elapsed = clock * (uint64_t)timebase.numer / (uint64_t)timebase.denom;
*time = inittime;
time->tv_sec += elapsed / 1000000000L;
time->tv_nsec += elapsed % 1000000000L;
time->tv_sec += time->tv_nsec / 1000000000L;
time->tv_nsec = time->tv_nsec % 1000000000L;
return 0; return 0;
} }
# endif # endif
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment