9#include "int_carry.hpp"
15#if HI_OPERATING_SYSTEM == HI_OS_WINDOWS
17#elif HI_OPERATING_SYSTEM == HI_OS_LINUX
21namespace hi::inline
v1 {
40 constexpr time_stamp_count(uint64_t count, uint32_t aux) noexcept : _count(count), _aux(aux), _thread_id(0) {}
46 if constexpr (processor::current == processor::x64) {
48 _count = __rdtscp(&tmp);
58 if constexpr (processor::current == processor::x64) {
59 _count = __rdtscp(&_aux);
69 if constexpr (processor::current == processor::x64) {
70 constexpr uint64_t NT_TIB_CurrentThreadID = 0x48;
72 _count = __rdtscp(&_aux);
73 _thread_id = __readgsdword(NT_TIB_CurrentThreadID);
93 [[nodiscard]] ssize_t
cpu_id() const noexcept
95 if (_aux_is_cpu_id.load(std::memory_order::relaxed)) {
99 return cpu_id_fallback();
106 [[nodiscard]]
constexpr uint32_t
thread_id() const noexcept
115 [[nodiscard]]
constexpr uint64_t
count() const noexcept
127 using namespace std::chrono_literals;
129 hilet[lo,
hi] = mul_carry(count, _period.load(std::memory_order::relaxed));
130 return 1ns *
static_cast<int64_t
>((
hi << 32) | (lo >> 32));
139 return duration_from_count(_count);
148 [[nodiscard]]
constexpr time_stamp_count operator+(uint64_t rhs)
const noexcept
160 static void set_frequency(uint64_t frequency)
noexcept
162 hilet period = (uint64_t{1'000'000'000} << 32) / frequency;
163 _period.store(period, std::memory_order_relaxed);
188 inline static
std::atomic<uint64_t> _period = 0;
190 inline static
std::atomic<
bool> _aux_is_cpu_id = false;
194 inline static
std::atomic<
std::
size_t> _num_aux_values = 0;
198 inline static
std::array<uint32_t, maximum_num_cpus> _aux_values;
202 inline static
std::array<
std::
size_t, maximum_num_cpus> _cpu_ids;
211 [[nodiscard]] ssize_t cpu_id_fallback() const noexcept;
213 static
void populate_aux_values() noexcept;
214 static
void configure_frequency() noexcept;
#define hi_not_implemented(...)
This part of the code has not been implemented yet.
Definition assert.hpp:193
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
Functions and macros for handling architectural difference between compilers, CPUs and operating syst...
DOXYGEN BUG.
Definition algorithm.hpp:15
geometry/margins.hpp
Definition assert.hpp:18
Since Window's 10 QueryPerformanceCounter() counts at only 10MHz which is too low to measure performa...
Definition time_stamp_count.hpp:29
static uint64_t measure_frequency(std::chrono::milliseconds duration) noexcept
Measure the frequency of the time_stamp_count.
constexpr uint32_t thread_id() const noexcept
Get the thread id.
Definition time_stamp_count.hpp:106
time_stamp_count(time_stamp_count::inplace_with_cpu_id) noexcept
Use a constructor to in-place create the timestamp.
Definition time_stamp_count.hpp:56
static time_stamp_count now() noexcept
Get the current count from the CPU's time stamp count.
Definition time_stamp_count.hpp:82
static void start_subsystem() noexcept
Start the time_stamp_count subsystem.
time_stamp_count(time_stamp_count::inplace) noexcept
Use a constructor to in-place create the timestamp.
Definition time_stamp_count.hpp:44
ssize_t cpu_id() const noexcept
Get the logical CPU index.
Definition time_stamp_count.hpp:93
time_stamp_count(time_stamp_count::inplace_with_thread_id) noexcept
Use a constructor to in-place create the timestamp.
Definition time_stamp_count.hpp:67
static std::chrono::nanoseconds duration_from_count(uint64_t count) noexcept
Convert a time-stamp count to a duration.
Definition time_stamp_count.hpp:125
std::chrono::nanoseconds time_since_epoch() const noexcept
Convert to nanoseconds since epoch.
Definition time_stamp_count.hpp:137
constexpr uint64_t count() const noexcept
Get the count since epoch.
Definition time_stamp_count.hpp:115
Definition time_stamp_count.hpp:31
Definition time_stamp_count.hpp:33
Definition time_stamp_count.hpp:35