From 957265ba5271aef0b14c3bc39fb015c9d1ae7805 Mon Sep 17 00:00:00 2001 From: JosJuice Date: Sat, 29 Mar 2025 15:00:33 +0100 Subject: [PATCH] Common: Make Profiler thread safe --- Source/Core/Common/Profiler.cpp | 19 ++++++++++--------- Source/Core/Common/Profiler.h | 24 +++++++++++++++--------- 2 files changed, 25 insertions(+), 18 deletions(-) diff --git a/Source/Core/Common/Profiler.cpp b/Source/Core/Common/Profiler.cpp index f3903629e6..34aafd38fd 100644 --- a/Source/Core/Common/Profiler.cpp +++ b/Source/Core/Common/Profiler.cpp @@ -29,10 +29,8 @@ std::string Profiler::s_lazy_result; int Profiler::s_lazy_delay = 0; Profiler::Profiler(const std::string& name) - : m_name(name), m_usecs(0), m_usecs_min(UINT64_MAX), m_usecs_max(0), m_usecs_quad(0), - m_calls(0), m_depth(0) + : m_name(name), m_usecs(0), m_usecs_min(UINT64_MAX), m_usecs_max(0), m_usecs_quad(0), m_calls(0) { - m_time = Common::Timer::NowUs(); s_max_length = std::max(s_max_length, u32(m_name.length())); std::lock_guard lk(s_mutex); @@ -97,22 +95,23 @@ std::string Profiler::ToString() return s_lazy_result; } -void Profiler::Start() +void Profiler::Start(u64* time, int* depth) { - if (!m_depth++) + if ((*depth)++ == 0) { - m_time = Common::Timer::NowUs(); + *time = Common::Timer::NowUs(); } } -void Profiler::Stop() +void Profiler::Stop(u64* time, int* depth) { - if (!--m_depth) + if (--(*depth) == 0) { u64 end = Common::Timer::NowUs(); - u64 diff = end - m_time; + u64 diff = end - *time; + std::lock_guard lk(m_mutex); m_usecs += diff; m_usecs_min = std::min(m_usecs_min, diff); m_usecs_max = std::max(m_usecs_max, diff); @@ -123,6 +122,8 @@ void Profiler::Stop() std::string Profiler::Read() { + std::lock_guard lk(m_mutex); + double avg = 0; double stdev = 0; double time_rel = 0; diff --git a/Source/Core/Common/Profiler.h b/Source/Core/Common/Profiler.h index b0255b1ce7..5110e41571 100644 --- a/Source/Core/Common/Profiler.h +++ b/Source/Core/Common/Profiler.h @@ -19,8 +19,8 @@ public: static std::string ToString(); - void Start(); - void Stop(); + void Start(u64* time, int* depth); + void Stop(u64* time, int* depth); std::string Read(); bool operator<(const Profiler& b) const; @@ -35,28 +35,34 @@ private: static std::string s_lazy_result; static int s_lazy_delay; + std::mutex m_mutex; std::string m_name; u64 m_usecs; u64 m_usecs_min; u64 m_usecs_max; u64 m_usecs_quad; u64 m_calls; - u64 m_time; - int m_depth; }; class ProfilerExecuter { public: - ProfilerExecuter(Profiler* _p) : m_p(_p) { m_p->Start(); } - ~ProfilerExecuter() { m_p->Stop(); } + ProfilerExecuter(Profiler* profiler, u64* time, int* depth) + : m_profiler(profiler), m_time(time), m_depth(depth) + { + m_profiler->Start(m_time, m_depth); + } + ~ProfilerExecuter() { m_profiler->Stop(m_time, m_depth); } private: - Profiler* m_p; + Profiler* m_profiler; + u64* m_time; + int* m_depth; }; } // namespace Common -// Warning: This profiler isn't thread safe. Only profile functions which doesn't run simultaneously #define PROFILE(name) \ static Common::Profiler prof_gen(name); \ - Common::ProfilerExecuter prof_e(&prof_gen); + static thread_local u64 prof_time; \ + static thread_local int prof_depth; \ + Common::ProfilerExecuter prof_e(&prof_gen, &prof_time, &prof_depth);