#ifndef __DISPATCH_SHIMS_TIME__
#define __DISPATCH_SHIMS_TIME__
#ifndef __DISPATCH_INDIRECT__
#error "Please #include <dispatch/dispatch.h> instead of this file directly."
#endif
uint64_t _dispatch_get_nanoseconds(void);
#if defined(__i386__) || defined(__x86_64__) || !HAVE_MACH_ABSOLUTE_TIME
#define _dispatch_time_mach2nano(x) ({x;})
#define _dispatch_time_nano2mach(x) ({x;})
#else
typedef struct _dispatch_host_time_data_s {
long double frac;
bool ratio_1_to_1;
dispatch_once_t pred;
} _dispatch_host_time_data_s;
extern _dispatch_host_time_data_s _dispatch_host_time_data;
void _dispatch_get_host_time_init(void *context);
static inline uint64_t
_dispatch_time_mach2nano(uint64_t machtime)
{
_dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
return machtime * data->frac;
}
static inline int64_t
_dispatch_time_nano2mach(int64_t nsec)
{
_dispatch_host_time_data_s *const data = &_dispatch_host_time_data;
dispatch_once_f(&data->pred, NULL, _dispatch_get_host_time_init);
if (slowpath(_dispatch_host_time_data.ratio_1_to_1)) {
return nsec;
}
long double big_tmp = nsec;
big_tmp /= data->frac;
if (slowpath(big_tmp > INT64_MAX)) {
return INT64_MAX;
}
if (slowpath(big_tmp < INT64_MIN)) {
return INT64_MIN;
}
return big_tmp;
}
#endif
static inline uint64_t
_dispatch_absolute_time(void)
{
#if !HAVE_MACH_ABSOLUTE_TIME
struct timespec ts;
int ret;
#if HAVE_DECL_CLOCK_UPTIME
ret = clock_gettime(CLOCK_UPTIME, &ts);
#elif HAVE_DECL_CLOCK_MONOTONIC
ret = clock_gettime(CLOCK_MONOTONIC, &ts);
#else
#error "clock_gettime: no supported absolute time clock"
#endif
(void)dispatch_assume_zero(ret);
return (ts.tv_sec * NSEC_PER_SEC + ts.tv_nsec);
#else
return mach_absolute_time();
#endif
}
#endif