4#include "TTauri/Foundation/counters.hpp"
5#include "TTauri/Foundation/datum.hpp"
6#include "TTauri/Foundation/logger.hpp"
7#include "TTauri/Foundation/cpu_utc_clock.hpp"
8#include "TTauri/Foundation/required.hpp"
9#include "TTauri/Foundation/tagged_map.hpp"
10#include "TTauri/Foundation/wfree_message_queue.hpp"
11#include <fmt/ostream.h>
12#include <fmt/format.h>
24constexpr int MAX_NR_TRACES = 1024;
47 inline int64_t
push() noexcept {
68 return {id, is_recording};
72inline thread_local trace_stack_type trace_stack;
76void trace_record() noexcept;
78template<typename Tag, typename... InfoTags>
92 timestamp(timestamp) {}
101 template<
typename InfoTag>
103 return info.template get<InfoTag>();
106 template<
typename InfoTag>
107 sdatum
const &get() const noexcept {
108 return info.template get<InfoTag>();
112template<
typename Tag,
typename... InfoTags>
117 for (
size_t i = 0; i < rhs.info.size(); i++) {
121 info_string += rhs.info.get_tag(i).name();
123 info_string +=
static_cast<std::string>(rhs.info[i]);
126 lhs << fmt::format(
"parent={} tag={} start={} {}",
152 int64_t prev_count = 0;
162 ttlet current_count = count.fetch_add(1, std::memory_order_acquire);
166 auto prev_peak = peak_duration.
load(std::memory_order_relaxed);
167 decltype(prev_peak) new_peak;
169 new_peak = d.
count() > prev_peak ? d.
count() : prev_peak;
172 version.store(current_count + 1, std::memory_order_release);
174 return current_count == 0;
189 r.peak_duration = {};
191 r.count = count.load(std::memory_order_acquire);
193 r.duration =
decltype(r.duration){duration.
load(std::memory_order_relaxed)};
195 auto tmp = peak_duration.
exchange(0, std::memory_order_relaxed);
196 if (tmp > r.peak_duration.
count()) {
197 r.peak_duration =
decltype(r.duration){tmp};
201 }
while (r.count != version.
load(std::memory_order_relaxed));
203 r.last_count = r.count - prev_count;
204 r.last_duration = r.duration - prev_duration;
206 prev_count = r.count;
207 prev_duration = r.duration;
212template<
typename Tag>
213inline trace_statistics_type trace_statistics;
215inline wfree_unordered_map<std::type_index,trace_statistics_type *,MAX_NR_TRACES> trace_statistics_map;
218template<
typename Tag,
typename... InfoTags>
227 tt_no_inline
static void add_to_map() {
228 trace_statistics_map.insert(
std::type_index(
typeid(Tag)), &trace_statistics<Tag>);
245 tt_force_inline
~trace() {
246 ttlet end_timestamp = cpu_counter_clock::now();
248 if(tt_unlikely(trace_statistics<Tag>.write(end_timestamp - data.
timestamp))) {
252 ttlet [id, is_recording] = stack->pop(data.
parent_id);
255 if (tt_unlikely(is_recording)) {
256 logger.log<log_level::Trace>(end_timestamp,
"id={} {}", id,
std::move(data));
265 template<
typename InfoTag,
typename T>
266 trace &set(T &&value) {
267 data.template get<InfoTag>() = std::forward<T>(value);
Definition cpu_counter_clock.hpp:18
A fixed size (64 bits) class for a generic value type.
Definition datum.hpp:106
static time_point convert(typename fast_clock::time_point fast_time) noexcept
Definition sync_clock.hpp:252
Definition tagged_map.hpp:14
int64_t top_trace_id
Definition trace.hpp:32
std::pair< int64_t, bool > pop(int64_t parent_id) noexcept
Definition trace.hpp:60
int8_t depth
Definition trace.hpp:36
int64_t push() noexcept
Definition trace.hpp:47
int8_t record_depth
Definition trace.hpp:40
int64_t parent_id
Definition trace.hpp:83
cpu_counter_clock::time_point timestamp
Definition trace.hpp:87
bool write(cpu_counter_clock::duration const &d)
Definition trace.hpp:159
trace()
Definition trace.hpp:237
Definition version.hpp:10
T atomic_thread_fence(T... args)
T compare_exchange_weak(T... args)