cesium-native 0.43.0
Loading...
Searching...
No Matches
Tracing.h
1#pragma once
2
3#ifndef CESIUM_OVERRIDE_TRACING
4
5// If the build system doesn't enable the tracing support
6// consider it disabled by default.
7#ifndef CESIUM_TRACING_ENABLED
8#define CESIUM_TRACING_ENABLED 0
9#endif
10
11#if !CESIUM_TRACING_ENABLED
12
13#define CESIUM_TRACE_INIT(filename)
14#define CESIUM_TRACE_SHUTDOWN()
15#define CESIUM_TRACE(name)
16#define CESIUM_TRACE_BEGIN(name)
17#define CESIUM_TRACE_END(name)
18#define CESIUM_TRACE_BEGIN_IN_TRACK(name)
19#define CESIUM_TRACE_END_IN_TRACK(name)
20#define CESIUM_TRACE_DECLARE_TRACK_SET(id, name)
21#define CESIUM_TRACE_USE_TRACK_SET(id)
22#define CESIUM_TRACE_LAMBDA_CAPTURE_TRACK() tracingTrack = false
23#define CESIUM_TRACE_USE_CAPTURED_TRACK()
24
25#else
26
27#include <atomic>
28#include <chrono>
29#include <fstream>
30#include <mutex>
31#include <string>
32#include <thread>
33#include <vector>
34
35// helper macros to avoid shadowing variables
36#define TRACE_NAME_AUX1(A, B) A##B
37#define TRACE_NAME_AUX2(A, B) TRACE_NAME_AUX1(A, B)
38
45#define CESIUM_TRACE_INIT(filename) \
46 CesiumUtility::CesiumImpl::Tracer::instance().startTracing(filename)
47
51#define CESIUM_TRACE_SHUTDOWN() \
52 CesiumUtility::CesiumImpl::Tracer::instance().endTracing()
53
64#define CESIUM_TRACE(name) \
65 CesiumUtility::CesiumImpl::ScopedTrace TRACE_NAME_AUX2( \
66 cesiumTrace, \
67 __LINE__)(name)
68
100#define CESIUM_TRACE_BEGIN(name) \
101 CesiumUtility::CesiumImpl::Tracer::instance().writeAsyncEventBegin(name)
102
112#define CESIUM_TRACE_END(name) \
113 CesiumUtility::CesiumImpl::Tracer::instance().writeAsyncEventEnd(name)
114
125#define CESIUM_TRACE_BEGIN_IN_TRACK(name) \
126 if (CesiumUtility::CesiumImpl::TrackReference::current() != nullptr) { \
127 CESIUM_TRACE_BEGIN(name); \
128 }
129
140#define CESIUM_TRACE_END_IN_TRACK(name) \
141 if (CesiumUtility::CesiumImpl::TrackReference::current() != nullptr) { \
142 CESIUM_TRACE_END(name); \
143 }
144
159#define CESIUM_TRACE_DECLARE_TRACK_SET(id, name) \
160 CesiumUtility::CesiumImpl::TrackSet id { name }
161
173#define CESIUM_TRACE_USE_TRACK_SET(id) \
174 CesiumUtility::CesiumImpl::TrackReference TRACE_NAME_AUX2( \
175 cesiumTraceEnlistTrack, \
176 __LINE__)(id);
177
187#define CESIUM_TRACE_LAMBDA_CAPTURE_TRACK() \
188 tracingTrack = CesiumUtility::CesiumImpl::LambdaCaptureTrack()
189
197#define CESIUM_TRACE_USE_CAPTURED_TRACK() \
198 CESIUM_TRACE_USE_TRACK_SET(tracingTrack)
199
200namespace CesiumUtility {
201namespace CesiumImpl {
202
203// The following are internal classes used by the tracing framework, do not use
204// directly.
205
206struct Trace {
207 std::string name;
208 int64_t start;
209 int64_t duration;
210 std::thread::id threadID;
211};
212
213class TrackReference;
214
215class Tracer {
216public:
217 static Tracer& instance();
218
219 ~Tracer();
220
221 void startTracing(const std::string& filePath = "trace.json");
222 void endTracing();
223
224 void writeCompleteEvent(const Trace& trace);
225 void writeAsyncEventBegin(const char* name, int64_t id);
226 void writeAsyncEventBegin(const char* name);
227 void writeAsyncEventEnd(const char* name, int64_t id);
228 void writeAsyncEventEnd(const char* name);
229
230 int64_t allocateTrackID();
231
232private:
233 Tracer();
234
235 int64_t getCurrentThreadTrackID() const;
236 void writeAsyncEvent(
237 const char* category,
238 const char* name,
239 char type,
240 int64_t id);
241
242 std::ofstream _output;
243 uint32_t _numTraces;
244 std::mutex _lock;
245 std::atomic<int64_t> _lastAllocatedID;
246};
247
248class ScopedTrace {
249public:
250 explicit ScopedTrace(const std::string& message);
251 ~ScopedTrace();
252
253 void reset();
254
255 ScopedTrace(const ScopedTrace& rhs) = delete;
256 ScopedTrace(ScopedTrace&& rhs) = delete;
257 ScopedTrace& operator=(const ScopedTrace& rhs) = delete;
258 ScopedTrace& operator=(ScopedTrace&& rhs) = delete;
259
260private:
261 std::string _name;
262 std::chrono::steady_clock::time_point _startTime;
263 std::thread::id _threadId;
264 bool _reset;
265};
266
267class TrackSet {
268public:
269 explicit TrackSet(const char* name);
270 ~TrackSet();
271
272 size_t acquireTrack();
273 void addReference(size_t trackIndex) noexcept;
274 void releaseReference(size_t trackIndex) noexcept;
275
276 int64_t getTracingID(size_t trackIndex) noexcept;
277
278 TrackSet(TrackSet&& rhs) noexcept;
279 TrackSet& operator=(TrackSet&& rhs) noexcept;
280
281private:
282 struct Track {
283 Track(int64_t id_, bool inUse_)
284 : id(id_), referenceCount(0), inUse(inUse_) {}
285
286 int64_t id;
287 int32_t referenceCount;
288 bool inUse;
289 };
290
291 std::string name;
292 std::vector<Track> tracks;
293 std::mutex mutex;
294};
295
296class LambdaCaptureTrack {
297public:
298 LambdaCaptureTrack();
299 LambdaCaptureTrack(LambdaCaptureTrack&& rhs) noexcept;
300 LambdaCaptureTrack(const LambdaCaptureTrack& rhs) noexcept;
301 ~LambdaCaptureTrack();
302 LambdaCaptureTrack& operator=(const LambdaCaptureTrack& rhs) noexcept;
303 LambdaCaptureTrack& operator=(LambdaCaptureTrack&& rhs) noexcept;
304
305private:
306 TrackSet* pSet;
307 size_t index;
308
309 friend class TrackReference;
310};
311
312// An RAII object to reference an async operation track.
313// When the last instance associated with a particular track index is destroyed,
314// the track is released back to the track set.
315class TrackReference {
316public:
317 static TrackReference* current();
318
319 TrackReference(TrackSet& set) noexcept;
320 TrackReference(TrackSet& set, size_t index) noexcept;
321 TrackReference(const LambdaCaptureTrack& lambdaCapture) noexcept;
322 ~TrackReference() noexcept;
323
324 operator bool() const noexcept;
325 int64_t getTracingID() const noexcept;
326
327 TrackReference(const TrackReference& rhs) = delete;
328 TrackReference(TrackReference&& rhs) = delete;
329 TrackReference& operator=(const TrackReference& rhs) = delete;
330 TrackReference& operator=(TrackReference&& rhs) = delete;
331
332private:
333 void enlistCurrentThread();
334 void dismissCurrentThread();
335
336 TrackSet* pSet;
337 size_t index;
338
339 static thread_local std::vector<TrackReference*> _threadEnlistedTracks;
340
341 friend class LambdaCaptureTrack;
342};
343
344} // namespace CesiumImpl
345} // namespace CesiumUtility
346
347#endif // CESIUM_TRACING_ENABLED
348
349#endif
Utility classes for Cesium.
STL namespace.