diff --git a/src/ipc/utils/profiler.cpp b/src/ipc/utils/profiler.cpp index a5e61d7b2..7be8fcbf9 100644 --- a/src/ipc/utils/profiler.cpp +++ b/src/ipc/utils/profiler.cpp @@ -2,12 +2,20 @@ #ifdef IPC_TOOLKIT_WITH_PROFILER +#include + #include #include namespace ipc { -Profiler::Profiler() : m_main_thread_id(std::this_thread::get_id()) { } +Profiler::Profiler() = default; + +bool Profiler::is_recording_thread() const +{ + const int idx = tbb::this_task_arena::current_thread_index(); + return idx == tbb::task_arena::not_initialized || idx == 0; +} Profiler& profiler() { @@ -23,7 +31,7 @@ void Profiler::clear() void Profiler::start(const std::string& name) { - if (std::this_thread::get_id() != m_main_thread_id) { + if (!is_recording_thread()) { return; } @@ -39,7 +47,7 @@ void Profiler::start(const std::string& name) void Profiler::stop(const double time_ms) { - if (std::this_thread::get_id() != m_main_thread_id) { + if (!is_recording_thread()) { return; } @@ -63,9 +71,7 @@ void Profiler::stop(const double time_ms) void Profiler::reset() { - m_main_thread_id = std::this_thread::get_id(); m_data.clear(); - // reset the calling thread's scope m_current_scope = nlohmann::json::json_pointer(); // root } diff --git a/src/ipc/utils/profiler.hpp b/src/ipc/utils/profiler.hpp index de955ad1b..92289bf20 100644 --- a/src/ipc/utils/profiler.hpp +++ b/src/ipc/utils/profiler.hpp @@ -22,7 +22,6 @@ #include #include -#include // Helper macro to stringify/paste after expansion #define IPC_TOOLKIT_PROFILE_BLOCK_CONCAT_IMPL(a, b) a##b @@ -74,10 +73,12 @@ class Profiler { /// @brief Access the profiling data as a JSON object. nlohmann::json& data() { return m_data; } - bool is_recording_thread() const - { - return std::this_thread::get_id() == m_main_thread_id; - } + /// @brief Returns true if the current thread should record profiling data. + /// When the current thread is not in a TBB arena, this returns + /// true. Inside a TBB arena, only the external/coordinator thread + /// (slot 0) records, giving a single-thread estimate of parallel + /// block costs. + bool is_recording_thread() const; protected: /// @brief The profiling data stored as a JSON object. @@ -85,10 +86,6 @@ class Profiler { /// @brief The global scope pointer into the JSON data. nlohmann::json::json_pointer m_current_scope; - - /// @brief The thread that records data; calls from all other threads are - /// silently ignored, giving a single-thread estimate of block costs. - std::thread::id m_main_thread_id; }; Profiler& profiler(); diff --git a/tests/src/tests/utils/test_profiler.cpp b/tests/src/tests/utils/test_profiler.cpp index c24cb20b7..5cd7e91c9 100644 --- a/tests/src/tests/utils/test_profiler.cpp +++ b/tests/src/tests/utils/test_profiler.cpp @@ -17,10 +17,14 @@ #include #include +#include + using namespace ipc; TEST_CASE("Profiler", "[profiler]") { + profiler().reset(); + constexpr int sleep_time_ms = 100; constexpr int num_threads = 10;