7#include "utility/module.hpp"
8#include "concurrency/module.hpp"
9#include "int_carry.hpp"
14#if HI_OPERATING_SYSTEM == HI_OS_WINDOWS
16#elif HI_OPERATING_SYSTEM == HI_OS_LINUX
20namespace hi::inline
v1 {
39 constexpr time_stamp_count(uint64_t count, uint32_t aux) noexcept : _count(count), _aux(aux), _thread_id(0) {}
45 if constexpr (processor::current == processor::x64) {
47 _count = __rdtscp(&tmp);
57 if constexpr (processor::current == processor::x64) {
58 _count = __rdtscp(&_aux);
68 if constexpr (processor::current == processor::x64) {
69 constexpr uint64_t NT_TIB_CurrentThreadID = 0x48;
71 _count = __rdtscp(&_aux);
72 _thread_id = __readgsdword(NT_TIB_CurrentThreadID);
92 [[nodiscard]] ssize_t
cpu_id() const noexcept
94 if (_aux_is_cpu_id.load(std::memory_order::relaxed)) {
98 return cpu_id_fallback();
105 [[nodiscard]]
constexpr uint32_t
thread_id() const noexcept
114 [[nodiscard]]
constexpr uint64_t
count() const noexcept
126 using namespace std::chrono_literals;
128 hilet[lo,
hi] = mul_carry(count, _period.load(std::memory_order::relaxed));
129 return 1ns *
static_cast<int64_t
>((
hi << 32) | (lo >> 32));
138 return duration_from_count(_count);
147 [[nodiscard]]
constexpr time_stamp_count operator+(uint64_t rhs)
const noexcept
159 static void set_frequency(uint64_t frequency)
noexcept
161 hilet period = (uint64_t{1'000'000'000} << 32) / frequency;
162 _period.store(period, std::memory_order_relaxed);
187 inline static
std::atomic<uint64_t> _period = 0;
189 inline static
std::atomic<
bool> _aux_is_cpu_id = false;
193 inline static
std::atomic<
std::
size_t> _num_aux_values = 0;
197 inline static
std::array<uint32_t, maximum_num_cpus> _aux_values;
201 inline static
std::array<
std::
size_t, maximum_num_cpus> _cpu_ids;
210 [[nodiscard]] ssize_t cpu_id_fallback() const noexcept;
212 static
void populate_aux_values() noexcept;
213 static
void configure_frequency() noexcept;
#define hi_not_implemented(...)
This part of the code has not been implemented yet.
Definition assert.hpp:320
#define hilet
Invariant should be the default for variables.
Definition utility.hpp:23
DOXYGEN BUG.
Definition algorithm.hpp:13
geometry/margins.hpp
Definition cache.hpp:11
Since Window's 10 QueryPerformanceCounter() counts at only 10MHz which is too low to measure performa...
Definition time_stamp_count.hpp:28
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:105
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:55
static time_stamp_count now() noexcept
Get the current count from the CPU's time stamp count.
Definition time_stamp_count.hpp:81
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:43
ssize_t cpu_id() const noexcept
Get the logical CPU index.
Definition time_stamp_count.hpp:92
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:66
static std::chrono::nanoseconds duration_from_count(uint64_t count) noexcept
Convert a time-stamp count to a duration.
Definition time_stamp_count.hpp:124
std::chrono::nanoseconds time_since_epoch() const noexcept
Convert to nanoseconds since epoch.
Definition time_stamp_count.hpp:136
constexpr uint64_t count() const noexcept
Get the count since epoch.
Definition time_stamp_count.hpp:114
Definition time_stamp_count.hpp:30
Definition time_stamp_count.hpp:32
Definition time_stamp_count.hpp:34