@@ -82,8 +82,16 @@ static thread_local xpti_tracepoint_t *g_tls_tracepoint_scope_data;
8282// / Default stream for the trace framework, if none is provided by the user.
8383constexpr const char *g_default_stream = " xpti.framework" ;
8484
85+ // / @brief Flag to ensure the default stream is initialized only once.
86+ // / @details Used with `std::call_once` to initialize the default stream in a
87+ // / thread-safe manner.
8588static std::once_flag g_initialize_default_stream_flag;
8689
90+ // / @brief Flag to ensure the default stream is finalized only once.
91+ // / @details Used with `std::call_once` to finalize the default stream in a
92+ // / thread-safe manner.
93+ static std::once_flag g_finalize_default_stream_flag;
94+
8795namespace xpti {
8896// / @var env_subscribers
8997// / @brief A constant character pointer initialized with the string
@@ -1379,15 +1387,15 @@ class Notifications {
13791387 // / @brief Maps a trace type to its associated callback entries.
13801388 // / @details This unordered map uses a uint16_t as the key to represent the
13811389 // / trace point type, and cb_entries_t to store the associated callbacks.
1382- using cb_t = std::unordered_map <uint16_t , cb_entries_t >;
1390+ using cb_t = emhash7::HashMap <uint16_t , cb_entries_t >;
13831391
13841392 // / @typedef stream_cb_t
13851393 // / @brief Maps a stream ID to its corresponding callbacks for different
13861394 // / trace types
13871395 // / @details This unordered map uses a uint16_t as the key for the stream
13881396 // / ID, and cb_t to map the stream to registered callbacks for each trace
13891397 // / type
1390- using stream_cb_t = std::unordered_map <uint16_t , cb_t >;
1398+ using stream_cb_t = emhash7::HashMap <uint16_t , cb_t >;
13911399
13921400 // / @typedef statistics_t
13931401 // / @brief Keeps track of statistics, typically counts, associated with
@@ -1396,13 +1404,13 @@ class Notifications {
13961404 // / the type of statistical data and usually not defined by default. To
13971405 // / enable it, XPTI_STATISTICS has to be defined while compiling the
13981406 // / frmaework library.
1399- using statistics_t = std::unordered_map <uint16_t , uint64_t >;
1407+ using statistics_t = emhash7::HashMap <uint16_t , uint64_t >;
14001408 // / @typedef trace_flags_t
14011409 // / @brief Maps an trace type to a boolean flag indicating its state.
14021410 // / @details This unordered map uses a uint16_t as the key for the trace
14031411 // / type, and a boolean value to indicate whether callbacks are registered
14041412 // / for this trace type (e.g., registered or unregisterted/no callback).
1405- using trace_flags_t = std::unordered_map <uint16_t , bool >;
1413+ using trace_flags_t = emhash7::HashMap <uint16_t , bool >;
14061414
14071415 // / @typedef stream_flags_t
14081416 // / @brief Maps a stream ID to its corresponding trace flags for different
@@ -1411,7 +1419,7 @@ class Notifications {
14111419 // / and trace_flags_t to map the trace type to their boolean that indiciates
14121420 // / whether a callback has been registered for this trace type in the given
14131421 // / stream.
1414- using stream_flags_t = std::unordered_map <uint8_t , trace_flags_t >;
1422+ using stream_flags_t = emhash7::HashMap <uint8_t , trace_flags_t >;
14151423
14161424 // / @brief Registers a callback function for a specific trace type and stream
14171425 // / ID.
@@ -2290,6 +2298,9 @@ class Framework {
22902298 }
22912299
22922300 static Framework &instance () {
2301+ // Using std::call_once has the same overhead as the original approach
2302+ // std::call_once(g_initialize_framework_flag,
2303+ // [&]() { MInstance = new Framework(); });
22932304 Framework *TmpFramework = MInstance.load (std::memory_order_relaxed);
22942305 std::atomic_thread_fence (std::memory_order_acquire);
22952306 if (TmpFramework == nullptr ) {
@@ -2309,6 +2320,11 @@ class Framework {
23092320 friend void ::xptiFrameworkFinalize ();
23102321
23112322 static void release () {
2323+ // Using std::call_once has the same overhead as the original approach
2324+ // std::call_once(g_release_framework_flag, [&]() {
2325+ // delete MInstance;
2326+ // MInstance = nullptr;
2327+ // });
23122328 Framework *TmpFramework = MInstance.load (std::memory_order_relaxed);
23132329 MInstance.store (nullptr , std::memory_order_relaxed);
23142330 delete TmpFramework;
@@ -2482,7 +2498,10 @@ XPTI_EXPORT_API xpti::result_t xptiInitialize(const char *Stream, uint32_t maj,
24822498// / when the stream is no longer in use.
24832499
24842500XPTI_EXPORT_API void xptiFinalize (const char *Stream) {
2485- xpti::Framework::instance ().finalizeStream (Stream);
2501+ auto &FW = xpti::Framework::instance ();
2502+ std::call_once (g_finalize_default_stream_flag,
2503+ [&]() { FW.finalizeStream (g_default_stream); });
2504+ FW.finalizeStream (Stream);
24862505}
24872506
24882507// / @brief Retrieves the 64-bit universal ID for the current scope, if published
0 commit comments