15# include <mach/mach_time.h>
20# ifdef ZTH_CUSTOM_CLOCK_GETTIME
21static mach_timebase_info_data_t clock_info;
22static uint64_t mach_clock_start;
24static void clock_global_init()
26 mach_timebase_info(&clock_info);
27 mach_clock_start = mach_absolute_time();
31int clock_gettime(
int clk_id,
struct timespec* res)
37 uint64_t c = (mach_absolute_time() - mach_clock_start);
39 if(
unlikely(clock_info.numer != clock_info.denom))
42 uint64_t chigh = (c >> 32U) * clock_info.numer;
43 uint64_t chighrem = ((chigh % clock_info.denom) << 32U) / clock_info.denom;
44 chigh /= clock_info.denom;
46 (c & (((uint64_t)1 << 32U) - 1)) * clock_info.numer / clock_info.denom;
61int clock_nanosleep(
int clk_id,
int flags,
struct timespec
const* request,
struct timespec* remain)
65 if(
unlikely(clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
69 int res = clock_gettime(CLOCK_MONOTONIC, &now);
73 if(now.tv_sec > request->tv_sec)
77 time_t sec = request->tv_sec - now.tv_sec;
78 if(sec == 0 && request->tv_nsec <= now.tv_nsec) {
81 }
else if(sec < std::numeric_limits<useconds_t>::max() / 1000000 - 1) {
82 useconds_t us = (useconds_t)(sec * 1000000);
83 us += (useconds_t)((request->tv_nsec - now.tv_nsec) / 1000);
88 if(
likely(!usleep(std::numeric_limits<useconds_t>::max())))
94 if((res = clock_gettime(CLOCK_MONOTONIC, &intr)))
97 remain->tv_sec = intr.tv_sec - now.tv_sec;
98 remain->tv_nsec = intr.tv_nsec - now.tv_nsec;
99 if(remain->tv_nsec < 0) {
100 remain->tv_nsec += 1000000000L;
112# ifdef WINPTHREADS_TIME_BITS
115# if WINPTHREADS_TIME_BITS == 32
116int clock_nanosleep32(
117 clockid_t clock_id,
int flags,
const struct _timespec32* request,
118 struct _timespec32* remain)
120int clock_nanosleep64(
121 clockid_t clock_id,
int flags,
const struct _timespec64* request,
122 struct _timespec64* remain)
126 clockid_t clock_id,
int flags,
const struct timespec* request,
struct timespec* remain)
131 if(
unlikely(clock_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
135 int res = clock_gettime(CLOCK_MONOTONIC, &t);
139 if(t.tv_sec > request->tv_sec)
141 if(t.tv_sec == request->tv_sec && t.tv_nsec > request->tv_nsec)
144 t.tv_sec = request->tv_sec - t.tv_sec;
145 t.tv_nsec = request->tv_nsec - t.tv_nsec;
147 t.tv_nsec += 1000000000L;
152 return nanosleep(&t, (
struct timespec*)remain) ? errno : 0;
156#ifdef ZTH_OS_BAREMETAL
161__attribute__((weak))
int clock_nanosleep(
162 int clk_id,
int flags,
struct timespec
const* request,
struct timespec*
UNUSED_PAR(remain))
166 if(
unlikely(clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
171 int res = clock_gettime(CLOCK_MONOTONIC, &now);
174 else if(now.tv_sec > request->tv_sec)
176 else if(now.tv_sec == request->tv_sec && now.tv_nsec >= request->tv_nsec)
188static void startTimeInit()
197static void startTimeInit()
205extern Timestamp const __attribute__((alias(
"startTime_"))) startTime;
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.