8#include "cpu_utc_clock.hpp"
10#include "tagged_map.hpp"
11#include "wfree_message_queue.hpp"
12#include "fixed_string.hpp"
13#include "statistics.hpp"
14#include <fmt/ostream.h>
15#include <fmt/format.h>
27constexpr int MAX_NR_TRACES = 1024;
50 inline int64_t
push() noexcept {
71 return {id, is_recording};
75inline thread_local trace_stack_type trace_stack;
79void trace_record() noexcept;
81template<basic_fixed_string Tag, basic_fixed_string... InfoTags>
95 timestamp(timestamp) {}
104 template<basic_fixed_
string InfoTag>
106 return info.template get<InfoTag>();
109 template<basic_fixed_
string InfoTag>
110 sdatum
const &get() const noexcept {
111 return info.template get<InfoTag>();
115template<basic_fixed_string Tag, basic_fixed_string... InfoTags>
120 for (
size_t i = 0; i < rhs.info.size(); i++) {
124 info_string += rhs.info.get_tag(i);
126 info_string +=
static_cast<std::string>(rhs.info[i]);
129 lhs << fmt::format(
"parent={} tag={} start={} {}",
155 int64_t prev_count = 0;
165 ttlet current_count = count.fetch_add(1, std::memory_order::acquire);
169 auto prev_peak = peak_duration.
load(std::memory_order::relaxed);
170 decltype(prev_peak) new_peak;
172 new_peak = d.
count() > prev_peak ? d.
count() : prev_peak;
175 version.store(current_count + 1, std::memory_order::release);
177 return current_count == 0;
192 r.peak_duration = {};
194 r.count = count.load(std::memory_order::acquire);
196 r.duration =
decltype(r.duration){duration.
load(std::memory_order::relaxed)};
198 auto tmp = peak_duration.
exchange(0, std::memory_order::relaxed);
199 if (tmp > r.peak_duration.
count()) {
200 r.peak_duration =
decltype(r.duration){tmp};
204 }
while (r.count != version.
load(std::memory_order::relaxed));
206 r.last_count = r.count - prev_count;
207 r.last_duration = r.duration - prev_duration;
209 prev_count = r.count;
210 prev_duration = r.duration;
215template<basic_fixed_
string Tag>
216inline trace_statistics_type trace_statistics;
218inline wfree_unordered_map<std::string,trace_statistics_type *,MAX_NR_TRACES> trace_statistics_map;
221template<basic_fixed_string Tag, basic_fixed_string... InfoTags>
230 tt_no_inline
static void add_to_map() {
231 trace_statistics_map.insert(Tag, &trace_statistics<Tag>);
250 ttlet end_timestamp = cpu_counter_clock::now();
252 if(trace_statistics<Tag>.write(end_timestamp - data.
timestamp)) {
253 [[unlikely]] add_to_map();
256 ttlet [id, is_recording] = stack->pop(data.
parent_id);
260 [[unlikely]] tt_log_trace(
"id={} {}",
id,
std::move(data));
269 template<basic_fixed_
string InfoTag,
typename T>
270 trace &set(T &&value) {
271 data.template get<InfoTag>() = std::forward<T>(value);
Definition cpu_counter_clock.hpp:19
A fixed size (64 bits) class for a generic value type.
Definition datum.hpp:112
A static sized stack.
Definition stack.hpp:22
static time_point convert(typename fast_clock::time_point fast_time) noexcept
Definition sync_clock.hpp:253
Definition tagged_map.hpp:16
int64_t top_trace_id
Definition trace.hpp:35
std::pair< int64_t, bool > pop(int64_t parent_id) noexcept
Definition trace.hpp:63
int8_t depth
Definition trace.hpp:39
int64_t push() noexcept
Definition trace.hpp:50
int8_t record_depth
Definition trace.hpp:43
int64_t parent_id
Definition trace.hpp:86
cpu_counter_clock::time_point timestamp
Definition trace.hpp:90
bool write(cpu_counter_clock::duration const &d)
Definition trace.hpp:162
trace()
Definition trace.hpp:241
Definition version.hpp:12
T atomic_thread_fence(T... args)
T compare_exchange_weak(T... args)