| 95 | |
| 96 | ScopedTrace::~ScopedTrace() { |
| 97 | std::optional<TraceTimePoint> endTime; |
| 98 | if (_startTime) { |
| 99 | endTime = std::chrono::steady_clock::now(); |
| 100 | } |
| 101 | |
| 102 | // Runs before the name is handed to the Tracer, which may move _ownedTrace out from under |
| 103 | // _trace. |
| 104 | end(); |
| 105 | |
| 106 | if (_startTime) { |
| 107 | std::string trace; |
| 108 | if (_ownedTrace.empty()) { |
| 109 | // Literal name: only worth materializing now that we know a recorder wants it. |
| 110 | trace = std::string(_trace); |
| 111 | } else { |
| 112 | // _trace views _ownedTrace, so this must not read _trace afterwards. |
| 113 | trace = std::move(_ownedTrace); |
| 114 | } |
| 115 | |
| 116 | Tracer::shared().append(std::move(trace), _startTime.value(), endTime.value()); |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | void ScopedTrace::start() { |
| 121 | begin(); |
| 122 | |
| 123 | if (Tracer::shared().isRecording()) { |
| 124 | _startTime = {std::chrono::steady_clock::now()}; |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | void ScopedTrace::begin() { |
| 129 | snap::profiling::TraceBegin traceBegin; |
| 130 | traceBegin.name = _trace; |
| 131 | |
| 132 | _osEmitter.begin(traceBegin); |
| 133 | } |
| 134 | |
| 135 | void ScopedTrace::end() { |
| 136 | snap::profiling::TraceEnd traceEnd; |
| 137 | traceEnd.name = _trace; |
| 138 | |
| 139 | _osEmitter.end(traceEnd); |
| 140 | } |