15# include <mach/mach_time.h>
24# ifdef ZTH_CUSTOM_CLOCK_GETTIME
25static mach_timebase_info_data_t clock_info;
26static uint64_t mach_clock_start;
28static void clock_global_init()
30 mach_timebase_info(&clock_info);
31 mach_clock_start = mach_absolute_time();
35int clock_gettime(
int clk_id,
struct timespec* res)
43 uint64_t c = (mach_absolute_time() - mach_clock_start);
45 if(
unlikely(clock_info.numer != clock_info.denom))
48 uint64_t chigh = (c >> 32U) * clock_info.numer;
49 uint64_t chighrem = ((chigh % clock_info.denom) << 32U) / clock_info.denom;
50 chigh /= clock_info.denom;
52 (c & (((uint64_t)1 << 32U) - 1)) * clock_info.numer / clock_info.denom;
67int clock_nanosleep(
int clk_id,
int flags,
struct timespec
const* request,
struct timespec* remain)
71 if(
unlikely(clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
75 if(
unlikely(clock_gettime(CLOCK_MONOTONIC, &now)))
78 if(
now.tv_sec > request->tv_sec)
82 time_t sec = request->tv_sec -
now.tv_sec;
83 if(sec == 0 && request->tv_nsec <=
now.tv_nsec) {
86 }
else if(sec < std::numeric_limits<useconds_t>::max() / 1000000 - 1) {
87 useconds_t us = (useconds_t)(sec * 1000000);
88 us += (useconds_t)((request->tv_nsec -
now.tv_nsec) / 1000);
93 if(
likely(!usleep(std::numeric_limits<useconds_t>::max())))
99 if(clock_gettime(CLOCK_MONOTONIC, &intr))
102 remain->tv_sec = intr.tv_sec -
now.tv_sec;
103 remain->tv_nsec = intr.tv_nsec -
now.tv_nsec;
104 if(remain->tv_nsec < 0) {
105 remain->tv_nsec += 1000000000L;
114#ifdef ZTH_OS_BAREMETAL
119__attribute__((weak))
int clock_nanosleep(
120 int clk_id,
int flags,
struct timespec
const* request,
struct timespec*
UNUSED_PAR(remain))
124 if(
unlikely(clk_id != CLOCK_MONOTONIC || flags != TIMER_ABSTIME))
129 if(
unlikely(clock_gettime(CLOCK_MONOTONIC, &now)))
131 else if(
now.tv_sec > request->tv_sec)
133 else if(
now.tv_sec == request->tv_sec &&
now.tv_nsec >= request->tv_nsec)
146 if(
unlikely(clock_gettime(CLOCK_MONOTONIC, &t)))
149 if(t.tv_sec > ts.tv_sec)
151 if(t.tv_sec == ts.tv_sec && t.tv_nsec > ts.tv_nsec)
154 t.tv_sec = ts.tv_sec - t.tv_sec;
155 t.tv_nsec = ts.tv_nsec - t.tv_nsec;
157 t.tv_nsec += 1000000000L;
162 switch(nanosleep(&t,
nullptr) ? errno : 0) {
173 return clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, &ts,
nullptr) ? errno : 0;
184static void startTimeInit()
193static void startTimeInit()
201extern Timestamp const __attribute__((alias(
"startTime_"))) startTime;
static long const BILLION
Convenient wrapper around struct timespec that contains an absolute timestamp.
void now(struct timespec &ts)
Returns the current timestamp.
Timestamp const startTime
int realsleep(struct timespec const &ts)
Sleeps the current thread.
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.