25#ifndef JOIN_CORE_CLOCK_HPP
26#define JOIN_CORE_CLOCK_HPP
34#if defined(__x86_64__) || defined(__i386__)
41 template <
class ClockPolicy>
44#ifdef JOIN_HAS_IO_URING
45 struct IoDefaultPolicy;
47 template <
typename IoPolicy>
50 template <
class ClockPolicy,
class ProactorType = BasicProactor<IoDefaultPolicy>>
55 template <
class ClockPolicy,
class ProactorType = BasicProactor>
59 template <
class ClockPolicy>
62 template <
class ClockPolicy,
class RunPolicy,
size_t Capacity, u
int64_t TickNs>
95 static constexpr
int type () noexcept
97 return CLOCK_REALTIME;
112 template <
size_t Capacity, u
int64_t TickNs = 100>
124 static constexpr
int type () noexcept
126 return CLOCK_MONOTONIC;
136 ::clock_gettime (CLOCK_MONOTONIC, &ts);
137 return TimePoint (
Duration (
static_cast<int64_t
> (ts.tv_sec) * 1'000'000'000LL + ts.tv_nsec));
151 template <
size_t Capacity, u
int64_t TickNs = 100>
163 static constexpr
int type () noexcept
165 return CLOCK_MONOTONIC_RAW;
175 ::clock_gettime (CLOCK_MONOTONIC_RAW, &ts);
176 return TimePoint (
Duration (
static_cast<int64_t
> (ts.tv_sec) * 1'000'000'000LL + ts.tv_nsec));
190 template <
size_t Capacity, u
int64_t TickNs = 100>
199#if defined(__x86_64__) || defined(__i386__)
202 throw std::runtime_error (
"cycle counter is not invariant");
214#if defined(__x86_64__) || defined(__i386__)
215 unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
216 if (__get_cpuid_max (0x80000000,
nullptr) < 0x80000007)
220 __cpuid (0x80000007, eax, ebx, ecx, edx);
221 return (edx & (1U << 8)) != 0;
232 static std::once_flag flag;
234 std::call_once (flag, [] {
235#if defined(__aarch64__)
237 __asm__
volatile (
"mrs %0, cntfrq_el0" :
"=r"(freq));
238 cycleToNs () = (1'000'000'000ULL << 32) / freq;
239#elif defined(__arm__)
241 __asm__
volatile (
"mrc p15, 0, %0, c14, c0, 0" :
"=r"(freq));
242 cycleToNs () = (1'000'000'000ULL << 32) / freq;
245 ::clock_gettime (CLOCK_MONOTONIC, &t0);
246 const uint64_t c0 = readCycles ();
248 const timespec delay{0, 100'000'000};
249 ::nanosleep (&delay,
nullptr);
251 ::clock_gettime (CLOCK_MONOTONIC, &t1);
252 const uint64_t c1 = readCycles ();
254 const int64_t ns = (t1.tv_sec - t0.tv_sec) * 1'000'000'000LL + (t1.tv_nsec - t0.tv_nsec);
255 const uint64_t cycles = c1 - c0;
257 cycleToNs () = (
static_cast<uint64_t
> (ns) << 32) / cycles;
268#if defined(__SIZEOF_INT128__)
269 const uint64_t ns =
static_cast<uint64_t
> ((
static_cast<__uint128_t
> (readCycles ()) * cycleToNs ()) >> 32);
271 const uint64_t M32 = 0xFFFFFFFFU;
273 const uint64_t cycles = readCycles ();
274 const uint64_t multiplier = cycleToNs ();
276 const uint64_t ch = cycles >> 32;
277 const uint64_t cl = cycles & M32;
278 const uint64_t mh = multiplier >> 32;
279 const uint64_t ml = multiplier & M32;
281 const uint64_t ns = ((ch * mh) << 32) + ch * ml + cl * mh + ((cl * ml) >> 32);
291 static uint64_t readCycles () noexcept
293#if defined(__x86_64__) || defined(__i386__)
295 __asm__
volatile (
"rdtsc" :
"=a"(lo),
"=d"(hi) : :
"memory");
296 return (
static_cast<uint64_t
> (hi) << 32) | lo;
297#elif defined(__aarch64__)
299 __asm__
volatile (
"mrs %0, cntvct_el0" :
"=r"(val) : :
"memory");
301#elif defined(__arm__)
303 __asm__
volatile (
"mrrc p15, 1, %Q0, %R0, c14" :
"=r"(val) : :
"memory");
306#error "Rdtsc: unsupported architecture"
314 static uint64_t& cycleToNs () noexcept
316 static uint64_t value = 0;
lock-free, multi-producer-safe performance statistics collector.
Definition statistics.hpp:50
base timer class.
Definition timer.hpp:53
timing wheel.
Definition wheel.hpp:58
raw monotonic clock policy (raw hardware clock, may drift).
Definition clock.hpp:145
std::chrono::time_point< NanoClock > TimePoint
Definition clock.hpp:148
constexpr MonotonicRaw() noexcept=default
default constructor.
static TimePoint now() noexcept
read the current time.
Definition clock.hpp:172
std::chrono::nanoseconds Duration
Definition clock.hpp:147
monotonic clock policy (stable, adjusted, recommended default).
Definition clock.hpp:105
constexpr Monotonic() noexcept=default
default constructor.
std::chrono::nanoseconds Duration
Definition clock.hpp:107
static TimePoint now() noexcept
read the current time.
Definition clock.hpp:133
std::chrono::time_point< NanoClock > TimePoint
Definition clock.hpp:108
rdtsc clock policy (invariant TSC, CPU pinning, no NTP slewing).
Definition clock.hpp:184
static void calibrate() noexcept
calibrate against CLOCK_MONOTONIC, or CNTFRQ on ARM.
Definition clock.hpp:230
static bool invariant() noexcept
check if the cycle counter is invariant.
Definition clock.hpp:212
std::chrono::time_point< NanoClock > TimePoint
Definition clock.hpp:187
std::chrono::nanoseconds Duration
Definition clock.hpp:186
Rdtsc()
default constructor.
Definition clock.hpp:197
static TimePoint now() noexcept
read the current time, requires calibrate ().
Definition clock.hpp:266
real-time clock policy.
Definition clock.hpp:82
constexpr RealTime() noexcept=default
default constructor.
Definition acceptor.hpp:32
minimal clock type used as a type tag for time_point parameterization.
Definition clock.hpp:69
int64_t rep
Definition clock.hpp:70
static constexpr bool is_steady
Definition clock.hpp:74
std::nano period
Definition clock.hpp:71
static time_point now() noexcept=delete
std::chrono::time_point< NanoClock > time_point
Definition clock.hpp:73
std::chrono::nanoseconds duration
Definition clock.hpp:72