15#include <mach/mach_time.h> 
   19#elif defined(unix) || defined(__unix) || defined(__unix__) 
   21#elif defined(_WIN32) || defined(_WIN64) 
   32uint32_t CeilLog2(uint32_t x)
 
   49mach_timebase_info_data_t BestFrac(
double a, 
double b)
 
   51    if (floor(a) < floor(b))
 
   53        mach_timebase_info_data_t rv = { (uint32_t)ceil(a), 1 };
 
   58    mach_timebase_info_data_t next = BestFrac(1 / (b - m), 1 / (a - m));
 
   59    mach_timebase_info_data_t rv = { (int)m * next.numer + next.denom, next.numer };
 
   65uint64_t GetExpressibleSpan(uint32_t numer, uint32_t denom)
 
   67  uint64_t maxDiffWithoutOverflow = ((uint64_t)1 << (64 - CeilLog2(numer))) - 1;
 
   68  return maxDiffWithoutOverflow * numer / denom;
 
   74uint64_t PrepareTimebaseInfo(mach_timebase_info_data_t& tb)
 
   79    kern_return_t mtiStatus = mach_timebase_info(&tb);
 
   80    if (mtiStatus != KERN_SUCCESS)
 
   83    double frac = (double)tb.numer / tb.denom;
 
   84    uint64_t spanTarget = 315360000000000000llu;
 
   85    if (GetExpressibleSpan(tb.numer, tb.denom) >= spanTarget)
 
   88    for (
double errorTarget = 1 / 1024.0; errorTarget > 0.000001;)
 
   90        mach_timebase_info_data_t newFrac = BestFrac((1 - errorTarget) * frac, (1 + errorTarget) * frac);
 
   91        if (GetExpressibleSpan(newFrac.numer, newFrac.denom) < spanTarget)
 
   94        errorTarget = fabs((
double)tb.numer / tb.denom - frac) / frac / 8;
 
  107#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 
  108    struct timespec timestamp;
 
  109    if (clock_gettime(CLOCK_REALTIME, ×tamp) != 0)
 
  111    return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
 
  112#elif defined(_WIN32) || defined(_WIN64) 
  114    GetSystemTimePreciseAsFileTime(&ft);
 
  116    ULARGE_INTEGER result;
 
  117    result.LowPart = ft.dwLowDateTime;
 
  118    result.HighPart = ft.dwHighDateTime;
 
  119    return (result.QuadPart - 116444736000000000ull) * 100;
 
 
  125#if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) 
  126    uint64_t timestamp = 
utc();
 
  130    time_t 
seconds = timestamp / (1000000000);
 
  133    return timestamp + (
local.tm_gmtoff * 1000000000);
 
  134#elif defined(_WIN32) || defined(_WIN64) 
  136#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8) 
  137    GetSystemTimePreciseAsFileTime(&ft);
 
  139    GetSystemTimeAsFileTime(&ft);
 
  143    if (!FileTimeToLocalFileTime(&ft, &ft_local))
 
  146    ULARGE_INTEGER result;
 
  147    result.LowPart = ft_local.dwLowDateTime;
 
  148    result.HighPart = ft_local.dwHighDateTime;
 
  149    return (result.QuadPart - 116444736000000000ull) * 100;
 
 
  155#if defined(__APPLE__) 
  156    static mach_timebase_info_data_t info;
 
  157    static uint64_t bias = Internals::PrepareTimebaseInfo(info);
 
  158    return ((mach_absolute_time() - bias) * info.numer) / info.denom;
 
  159#elif defined(unix) || defined(__unix) || defined(__unix__) 
  160    struct timespec timestamp = { 0 };
 
  161    if (clock_gettime(CLOCK_MONOTONIC, ×tamp) != 0)
 
  163    return (timestamp.tv_sec * 1000000000) + timestamp.tv_nsec;
 
  164#elif defined(_WIN32) || defined(_WIN64) 
  165    static uint64_t offset = 0;
 
  166    static LARGE_INTEGER first = { 0 };
 
  167    static LARGE_INTEGER frequency = { 0 };
 
  168    static bool initialized = 
false;
 
  169    static bool qpc = 
true;
 
  175        GetSystemTimePreciseAsFileTime(×tamp);
 
  177        ULARGE_INTEGER result;
 
  178        result.LowPart = timestamp.dwLowDateTime;
 
  179        result.HighPart = timestamp.dwHighDateTime;
 
  182        result.QuadPart -= 116444736000000000ll;
 
  183        offset = result.QuadPart * 100;
 
  186        qpc = QueryPerformanceFrequency(&frequency) && QueryPerformanceCounter(&first);
 
  193        LARGE_INTEGER timestamp = { 0 };
 
  194        QueryPerformanceCounter(×tamp);
 
  195        timestamp.QuadPart -= first.QuadPart;
 
  196        return offset + 
Math::MulDiv64(timestamp.QuadPart, 1000000000, frequency.QuadPart);
 
  201    #error Unsupported platform 
 
  207#if defined(__APPLE__) 
  217    return mach_absolute_time();
 
  218#elif defined(_MSC_VER) 
  220#elif defined(__i386__) 
  222    __asm__ 
volatile(
"rdtsc" : 
"=A"(ret));
 
  224#elif defined(__x86_64__) || defined(__amd64__) 
  226    __asm__ 
volatile(
"rdtsc" : 
"=a"(low), 
"=d"(high));
 
  227    return (high << 32) | low;
 
  228#elif defined(__powerpc__) || defined(__ppc__) 
  230    int64_t tbl, tbu0, tbu1;
 
  231    asm(
"mftbu %0" : 
"=r"(tbu0));
 
  232    asm(
"mftb  %0" : 
"=r"(tbl));
 
  233    asm(
"mftbu %0" : 
"=r"(tbu1));
 
  234    tbl &= -
static_cast<int64
>(tbu0 == tbu1);
 
  237    return (tbu1 << 32) | tbl;
 
  238#elif defined(__sparc__) 
  240    asm(
".byte 0x83, 0x41, 0x00, 0x00");
 
  241    asm(
"mov   %%g1, %0" : 
"=r"(tick));
 
  243#elif defined(__ia64__) 
  245    asm(
"mov %0 = ar.itc" : 
"=r"(itc));
 
  247#elif defined(COMPILER_MSVC) && defined(_M_IX86) 
  253#elif defined(__aarch64__) 
  258    int64_t virtual_timer_value;
 
  259    asm volatile(
"mrs %0, cntvct_el0" : 
"=r"(virtual_timer_value));
 
  260    return virtual_timer_value;
 
  261#elif defined(__ARM_ARCH) 
  264    #if (__ARM_ARCH >= 6) 
  269    asm volatile(
"mrc p15, 0, %0, c9, c14, 0" : 
"=r"(pmuseren));
 
  273        asm volatile(
"mrc p15, 0, %0, c9, c12, 1" : 
"=r"(pmcntenset));
 
  274        if (pmcntenset & 0x80000000ul)
 
  277            asm volatile(
"mrc p15, 0, %0, c9, c13, 0" : 
"=r"(pmccntr));
 
  279            return static_cast<int64_t
>(pmccntr) * 64;
 
  285    gettimeofday(&tv, 
nullptr);
 
  286    return static_cast<int64_t
>(tv.tv_sec) * 1000000 + tv.tv_usec;
 
  287#elif defined(__mips__) || defined(__loongarch__) || defined(__riscv) 
  291    gettimeofday(&tv, 
nullptr);
 
  292    return static_cast<int64_t
>(tv.tv_sec) * 1000000 + tv.tv_usec;
 
  294    #error Unsupported platform 
 
static uint64_t MulDiv64(uint64_t operant, uint64_t multiplier, uint64_t divider)
Calculate (operant * multiplier / divider) with 64-bit unsigned integer values.
static uint64_t local()
Get the local timestamp.
static uint64_t utc()
Get the UTC timestamp.
static uint64_t nano()
Get the high resolution timestamp.
uint64_t seconds() const noexcept
Get total seconds of the current timestamp.
static uint64_t rdts()
Get the current value of RDTS (Read Time Stamp Counter)
#define throwex
Throw extended exception macro.
C++ Common project definitions.