From f17aa956cd4dca9ecc3437d6b4bf74c3cef535b5 Mon Sep 17 00:00:00 2001 From: Victor Zarubkin Date: Sun, 9 Apr 2017 10:23:59 +0300 Subject: [PATCH] (Core) Add main thread check --- easy_profiler_core/profile_manager.cpp | 34 +++++++++++++++++++---- easy_profiler_core/profile_manager.h | 37 +++++++++++++------------- 2 files changed, 48 insertions(+), 23 deletions(-) diff --git a/easy_profiler_core/profile_manager.cpp b/easy_profiler_core/profile_manager.cpp index 5dbed0a..c1ec268 100644 --- a/easy_profiler_core/profile_manager.cpp +++ b/easy_profiler_core/profile_manager.cpp @@ -658,6 +658,7 @@ ProfileManager::ProfileManager() : m_isAlreadyListening = ATOMIC_VAR_INIT(false); m_stopListen = ATOMIC_VAR_INIT(false); + m_mainThreadId = ATOMIC_VAR_INIT(0); m_frameMax = ATOMIC_VAR_INIT(0); m_frameAvg = ATOMIC_VAR_INIT(0); m_frameCur = ATOMIC_VAR_INIT(0); @@ -1304,6 +1305,8 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream, bo } #endif + bool mainThreadExpired = false; + // Calculate used memory total size and total blocks number uint64_t usedMemorySize = 0; uint32_t blocks_number = 0; @@ -1315,6 +1318,9 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream, bo const char expired = checkThreadExpired(t); if (num == 0 && (expired != 0 || !t.guarded)) { // Remove thread if it contains no profiled information and has been finished or is not guarded. + profiler::thread_id_t id = it->first; + if (!mainThreadExpired && m_mainThreadId.compare_exchange_weak(id, 0, std::memory_order_release, std::memory_order_acquire)) + mainThreadExpired = true; m_threads.erase(it++); continue; } @@ -1399,9 +1405,17 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream, bo t.sync.openedList.clear(); if (t.expired.load(std::memory_order_acquire) != 0) - m_threads.erase(it++); // Remove expired thread after writing all profiled information + { + // Remove expired thread after writing all profiled information + profiler::thread_id_t id = it->first; + if (!mainThreadExpired && m_mainThreadId.compare_exchange_weak(id, 0, std::memory_order_release, std::memory_order_acquire)) + mainThreadExpired = true; + m_threads.erase(it++); + } else + { ++it; + } } m_storedSpin.unlock(); @@ -1450,11 +1464,16 @@ const char* ProfileManager::registerThread(const char* name, ThreadGuard& thread THIS_THREAD = &threadStorage(getCurrentThreadId()); THIS_THREAD->guarded = true; - if (!THIS_THREAD->named) { + if (!THIS_THREAD->named) + { THIS_THREAD->named = true; THIS_THREAD->name = name; + if (THIS_THREAD->name == "Main") - THIS_THREAD_IS_MAIN = true; + { + profiler::thread_id_t id = 0; + THIS_THREAD_IS_MAIN = m_mainThreadId.compare_exchange_weak(id, THIS_THREAD->id, std::memory_order_release, std::memory_order_acquire); + } } threadGuard.m_id = THIS_THREAD->id; @@ -1467,11 +1486,16 @@ const char* ProfileManager::registerThread(const char* name) if (THIS_THREAD == nullptr) THIS_THREAD = &threadStorage(getCurrentThreadId()); - if (!THIS_THREAD->named) { + if (!THIS_THREAD->named) + { THIS_THREAD->named = true; THIS_THREAD->name = name; + if (THIS_THREAD->name == "Main") - THIS_THREAD_IS_MAIN = true; + { + profiler::thread_id_t id = 0; + THIS_THREAD_IS_MAIN = m_mainThreadId.compare_exchange_weak(id, THIS_THREAD->id, std::memory_order_release, std::memory_order_acquire); + } } return THIS_THREAD->name.c_str(); diff --git a/easy_profiler_core/profile_manager.h b/easy_profiler_core/profile_manager.h index 7c18d24..cd02b21 100644 --- a/easy_profiler_core/profile_manager.h +++ b/easy_profiler_core/profile_manager.h @@ -371,25 +371,26 @@ class ProfileManager typedef std::unordered_map descriptors_map_t; #endif - const processid_t m_processId; + const processid_t m_processId; - map_of_threads_stacks m_threads; - block_descriptors_t m_descriptors; - descriptors_map_t m_descriptorsMap; - uint64_t m_usedMemorySize; - profiler::timestamp_t m_beginTime; - profiler::timestamp_t m_endTime; - std::atomic m_frameMax; - std::atomic m_frameAvg; - std::atomic m_frameCur; - profiler::spin_lock m_spin; - profiler::spin_lock m_storedSpin; - profiler::spin_lock m_dumpSpin; - std::atomic m_profilerStatus; - std::atomic_bool m_isEventTracingEnabled; - std::atomic_bool m_isAlreadyListening; - std::atomic_bool m_frameMaxReset; - std::atomic_bool m_frameAvgReset; + map_of_threads_stacks m_threads; + block_descriptors_t m_descriptors; + descriptors_map_t m_descriptorsMap; + uint64_t m_usedMemorySize; + profiler::timestamp_t m_beginTime; + profiler::timestamp_t m_endTime; + std::atomic m_frameMax; + std::atomic m_frameAvg; + std::atomic m_frameCur; + profiler::spin_lock m_spin; + profiler::spin_lock m_storedSpin; + profiler::spin_lock m_dumpSpin; + std::atomic m_mainThreadId; + std::atomic m_profilerStatus; + std::atomic_bool m_isEventTracingEnabled; + std::atomic_bool m_isAlreadyListening; + std::atomic_bool m_frameMaxReset; + std::atomic_bool m_frameAvgReset; std::string m_csInfoFilename = "/tmp/cs_profiling_info.log";