Corium 1.1.0
High-Performance Zero-Heap C++20 MPSC Application Runtime
Loading...
Searching...
No Matches
FlightRecorder.hpp
Go to the documentation of this file.
1
7#pragma once
8
9#include <array>
10#include <atomic>
11#include <chrono>
12#include <cstddef>
13#include <cstdint>
14#include <ostream>
15
17
19using ProfilerClock = std::chrono::steady_clock;
20
22struct alignas(32) FlightRecord {
23 std::size_t eventTypeId{0};
24 const char* eventName{nullptr};
25 uint64_t postTimestampNs{0};
27 uint64_t finishTimestampNs{0};
28 uint8_t priority{0};
29
31 [[nodiscard]] double queueLatencyUs() const noexcept
32 {
33 if (dispatchTimestampNs < postTimestampNs) return 0.0;
34 return static_cast<double>(dispatchTimestampNs - postTimestampNs) / 1000.0;
35 }
36
38 [[nodiscard]] double executionDurationUs() const noexcept
39 {
40 if (finishTimestampNs < dispatchTimestampNs) return 0.0;
41 return static_cast<double>(finishTimestampNs - dispatchTimestampNs) / 1000.0;
42 }
43
45 [[nodiscard]] double totalDurationUs() const noexcept
46 {
47 if (finishTimestampNs < postTimestampNs) return 0.0;
48 return static_cast<double>(finishTimestampNs - postTimestampNs) / 1000.0;
49 }
50};
51
56template <std::size_t Capacity = 256>
58 static_assert((Capacity & (Capacity - 1)) == 0, "Capacity must be a power of 2.");
59 static constexpr std::size_t Mask = Capacity - 1;
60
61public:
62 FlightRecorder() = default;
63
65 void record(
66 std::size_t eventTypeId,
67 const char* eventName,
68 uint64_t postTimeNs,
69 uint64_t dispatchTimeNs,
70 uint64_t finishTimeNs,
71 uint8_t priority
72 ) noexcept
73 {
74 const std::size_t idx = _writeIndex.fetch_add(1, std::memory_order_relaxed);
75 FlightRecord& entry = _records[idx & Mask];
76 entry.eventTypeId = eventTypeId;
77 entry.eventName = eventName ? eventName : "UnknownEvent";
78 entry.postTimestampNs = postTimeNs;
79 entry.dispatchTimestampNs = dispatchTimeNs;
80 entry.finishTimestampNs = finishTimeNs;
81 entry.priority = priority;
82 }
83
85 [[nodiscard]] uint64_t totalRecorded() const noexcept
86 {
87 return _writeIndex.load(std::memory_order_relaxed);
88 }
89
91 [[nodiscard]] constexpr std::size_t capacity() const noexcept
92 {
93 return Capacity;
94 }
95
97 [[nodiscard]] FlightRecord recordAt(std::size_t index) const noexcept
98 {
99 return _records[index & Mask];
100 }
101
103 template <typename Callback>
104 void forEach(Callback&& cb) const
105 {
106 const uint64_t current = _writeIndex.load(std::memory_order_acquire);
107 const std::size_t count = current < Capacity ? static_cast<std::size_t>(current) : Capacity;
108 const uint64_t start = current < Capacity ? 0 : current - Capacity;
109
110 for (std::size_t i = 0; i < count; ++i) {
111 cb(_records[(start + i) & Mask]);
112 }
113 }
114
116 void exportChromeTracingJson(std::ostream& os) const
117 {
118 os << "[\n";
119 bool first = true;
120
121 forEach([&](const FlightRecord& rec) {
122 if (!first) os << ",\n";
123 first = false;
124
125 // 1. Queue wait event (phase "X" complete event)
126 const double postUs = static_cast<double>(rec.postTimestampNs) / 1000.0;
127 const double queueDurationUs = rec.queueLatencyUs();
128 const double dispatchUs = static_cast<double>(rec.dispatchTimestampNs) / 1000.0;
129 const double execDurationUs = rec.executionDurationUs();
130
131 os << " {\"name\": \"QueueWait[" << (rec.eventName ? rec.eventName : "Event")
132 << "]\", \"cat\": \"corium\", \"ph\": \"X\", \"ts\": " << postUs
133 << ", \"dur\": " << queueDurationUs << ", \"pid\": 1, \"tid\": 1, \"args\": {\"prio\": "
134 << static_cast<int>(rec.priority) << "}},\n";
135
136 // 2. Dispatch / Handler execution event
137 os << " {\"name\": \"Dispatch[" << (rec.eventName ? rec.eventName : "Event")
138 << "]\", \"cat\": \"corium\", \"ph\": \"X\", \"ts\": " << dispatchUs
139 << ", \"dur\": " << execDurationUs << ", \"pid\": 1, \"tid\": 1, \"args\": {\"type_id\": "
140 << rec.eventTypeId << "}}";
141 });
142
143 os << "\n]\n";
144 }
145
146private:
147 std::atomic<uint64_t> _writeIndex{0};
148 std::array<FlightRecord, Capacity> _records{};
149};
150
151} // namespace corium::profiler
Zero-heap circular flight recorder storing the last N event telemetry records. Thread-safe for multip...
Definition FlightRecorder.hpp:57
void record(std::size_t eventTypeId, const char *eventName, uint64_t postTimeNs, uint64_t dispatchTimeNs, uint64_t finishTimeNs, uint8_t priority) noexcept
Record a completed event execution into the circular buffer.
Definition FlightRecorder.hpp:65
constexpr std::size_t capacity() const noexcept
Get buffer capacity.
Definition FlightRecorder.hpp:91
void exportChromeTracingJson(std::ostream &os) const
Export recorded flight logs in Chrome Tracing JSON format (supported by chrome://tracing and Perfetto...
Definition FlightRecorder.hpp:116
FlightRecord recordAt(std::size_t index) const noexcept
Read a record by logical historical index (0 is oldest available in current window).
Definition FlightRecorder.hpp:97
uint64_t totalRecorded() const noexcept
Get total number of recorded events since creation.
Definition FlightRecorder.hpp:85
void forEach(Callback &&cb) const
Iterate through available historical records in chronological order.
Definition FlightRecorder.hpp:104
Definition FlightRecorder.hpp:16
std::chrono::steady_clock ProfilerClock
Timestamp clock used by the profiler (steady clock in nanoseconds).
Definition FlightRecorder.hpp:19
Represents a single traced event record in the circular flight recorder.
Definition FlightRecorder.hpp:22
uint64_t dispatchTimestampNs
Definition FlightRecorder.hpp:26
double queueLatencyUs() const noexcept
Calculate latency spent waiting in queue before dispatch in microseconds.
Definition FlightRecorder.hpp:31
uint64_t postTimestampNs
Definition FlightRecorder.hpp:25
uint64_t finishTimestampNs
Definition FlightRecorder.hpp:27
uint8_t priority
Definition FlightRecorder.hpp:28
std::size_t eventTypeId
Definition FlightRecorder.hpp:23
const char * eventName
Definition FlightRecorder.hpp:24
double totalDurationUs() const noexcept
Calculate total turnaround time from post to finish in microseconds.
Definition FlightRecorder.hpp:45
double executionDurationUs() const noexcept
Calculate duration of handler execution in microseconds.
Definition FlightRecorder.hpp:38