guanaqo develop
Utilities for scientific software
Loading...
Searching...
No Matches
trace.cpp
Go to the documentation of this file.
1#include <guanaqo/trace.hpp>
2#include <list>
3#include <mutex>
4#include <thread>
5
6#ifdef _POSIX_THREADS
7#include <pthread.h>
8#endif
9
10#if GUANAQO_WITH_ITT
11namespace guanaqo {
12GUANAQO_EXPORT TraceLogger &get_trace_logger() {
13 static TraceLogger instance;
14 return instance;
15}
16} // namespace guanaqo
17
18#else
19namespace guanaqo {
20
21#ifdef _POSIX_THREADS
22template <class T>
23concept pthread_self_converts_to = requires { T{::pthread_self()}; };
24#else
25template <class>
27#endif
28
29GUANAQO_EXPORT std::size_t get_thread_id() {
30 return []<class S = std::size_t>() {
31 // we need template instantiation to discard the non-selected branch
32 if constexpr (pthread_self_converts_to<S>) {
33 static thread_local S self{::pthread_self()};
34 return self;
35 } else {
36 static constexpr std::hash<std::thread::id> hasher;
37 return hasher(std::this_thread::get_id());
38 }
39 }();
40}
41
42TraceLogger::clock::time_point TraceLogger::t0 = clock::now();
43
44static std::mutex trace_loggers_mutex;
45static std::list<std::shared_ptr<TraceLogger>> trace_loggers;
46static std::atomic<size_t> default_trace_logger_size = 16'384;
47
48static auto new_trace_logger(size_t size) {
49 auto logger = std::make_shared<TraceLogger>(size);
50 std::lock_guard lock(trace_loggers_mutex);
51 trace_loggers.push_back(logger);
52 return logger;
53}
54
55GUANAQO_EXPORT size_t trace_logger_set_default_size(size_t size) {
56 return default_trace_logger_size.exchange(size, std::memory_order_relaxed);
57}
58
59GUANAQO_EXPORT TraceLogger &get_trace_logger() {
60 static thread_local auto instance = new_trace_logger(
61 default_trace_logger_size.load(std::memory_order_relaxed));
62 return *instance;
63}
64
65GUANAQO_EXPORT void drop_trace_loggers(
66 const std::function<void(std::shared_ptr<TraceLogger>)> &callback) {
67 if (callback) {
68 auto old_loggers = [&] {
69 std::lock_guard lock(trace_loggers_mutex);
70 return std::exchange(trace_loggers, {});
71 }();
72 for (auto &logger : old_loggers)
73 callback(std::move(logger));
74 } else {
75 std::lock_guard lock(trace_loggers_mutex);
76 trace_loggers.clear();
77 }
78}
79
80GUANAQO_EXPORT void
81for_each_trace_logger(const std::function<void(TraceLogger &)> &callback) {
82 std::lock_guard lock(trace_loggers_mutex);
83 for (const auto &logger : trace_loggers)
84 callback(*logger);
85}
86
87} // namespace guanaqo
88#endif
TraceLogger & get_trace_logger()
Get a reference to the global (but thread-local) trace logger instance.
Definition trace.cpp:59
size_t trace_logger_set_default_size(size_t size)
Set the default capacity for trace loggers created by get_trace_logger().
Definition trace.cpp:55
static std::mutex trace_loggers_mutex
Definition trace.cpp:44
void drop_trace_loggers(const std::function< void(std::shared_ptr< TraceLogger >)> &callback=nullptr)
Like for_each_trace_logger, but also forgets about all loggers.
Definition trace.cpp:65
void for_each_trace_logger(const std::function< void(TraceLogger &)> &callback)
Call callback for each trace logger instance.
Definition trace.cpp:81
static std::atomic< size_t > default_trace_logger_size
Definition trace.cpp:46
static std::list< std::shared_ptr< TraceLogger > > trace_loggers
Definition trace.cpp:45
static auto new_trace_logger(size_t size)
Definition trace.cpp:48
std::size_t get_thread_id()
Definition trace.cpp:29
Class for recording trace logs, used when ITT or Perfetto tracing is not enabled.
Definition trace.hpp:136
static clock::time_point t0
Definition trace.hpp:159
Tracing logger and macros (ITT, Perfetto, or fallback).