17 # include <mach/mach_time.h>
22 # ifdef ZTH_CUSTOM_CLOCK_GETTIME
23 static mach_timebase_info_data_t clock_info;
24 static uint64_t mach_clock_start;
26 static void clock_global_init()
28 mach_timebase_info(&clock_info);
29 mach_clock_start = mach_absolute_time();
33 int clock_gettime(
int clk_id,
struct timespec* res)
39 uint64_t c = (mach_absolute_time() - mach_clock_start);
41 if(
unlikely(clock_info.numer != clock_info.denom))
44 uint64_t chigh = (c >> 32u) * clock_info.numer;
45 uint64_t chighrem = ((chigh % clock_info.denom) << 32u) / clock_info.denom;
46 chigh /= clock_info.denom;
48 (c & (((uint64_t)1 << 32u) - 1)) * clock_info.numer / clock_info.denom;
63 int clock_nanosleep(
int clk_id,
int flags,
struct timespec
const* request,
struct timespec* remain)
67 if(
unlikely(clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
71 int res = clock_gettime(CLOCK_MONOTONIC, &now);
75 if(now.tv_sec > request->tv_sec)
79 time_t sec = request->tv_sec - now.tv_sec;
80 if(sec == 0 && request->tv_nsec <= now.tv_nsec) {
83 }
else if(sec < std::numeric_limits<useconds_t>::max() / 1000000 - 1) {
84 useconds_t us = (useconds_t)(sec * 1000000);
85 us += (useconds_t)((request->tv_nsec - now.tv_nsec) / 1000);
90 if(
likely(!usleep(std::numeric_limits<useconds_t>::max())))
96 if((res = clock_gettime(CLOCK_MONOTONIC, &intr)))
99 remain->tv_sec = intr.tv_sec - now.tv_sec;
100 remain->tv_nsec = intr.tv_nsec - now.tv_nsec;
101 if(remain->tv_nsec < 0) {
102 remain->tv_nsec += 1000000000L;
111 #ifdef ZTH_OS_WINDOWS
115 clockid_t clock_id,
int flags,
const struct timespec* request,
struct timespec* remain)
119 if(
unlikely(clock_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
123 int res = clock_gettime(CLOCK_MONOTONIC, &t);
127 if(t.tv_sec > request->tv_sec)
129 if(t.tv_sec == request->tv_sec && t.tv_nsec > request->tv_nsec)
132 t.tv_sec = request->tv_sec - t.tv_sec;
133 t.tv_nsec = request->tv_nsec - t.tv_nsec;
135 t.tv_nsec += 1000000000L;
139 return nanosleep(&t, remain) ? errno : 0;
143 #ifdef ZTH_OS_BAREMETAL
148 __attribute__((weak))
int clock_nanosleep(
149 int clk_id,
int flags,
struct timespec
const* request,
struct timespec*
UNUSED_PAR(remain))
153 if(
unlikely(clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
158 int res = clock_gettime(CLOCK_MONOTONIC, &now);
161 else if(now.tv_sec > request->tv_sec)
163 else if(now.tv_sec == request->tv_sec && now.tv_nsec >= request->tv_nsec)
175 static void startTimeInit()
183 static void startTimeInit()
static long const BILLION
Convenient wrapper around struct timespec that contains an absolute timestamp.
Timestamp const startTime
zth::Timestamp startTime_
#define zth_assert(expr)
assert(), but better integrated in Zth.
#define likely(expr)
Marks the given expression to likely be evaluated to true.
#define unlikely(expr)
Marks the given expression to likely be evaluated to true.