From 65ac892e326bbedd1b5cb397f24f54311b88b8c1 Mon Sep 17 00:00:00 2001 From: Victor Zarubkin Date: Mon, 5 Jun 2017 21:24:01 +0300 Subject: [PATCH] Fixing problems after changing thread_id_t to uint64_t from uint32_t: There is still a big problem with target-thread ids of context-switch events on *nix systems (it has been stored in block_id_t which is uint32_t and now it requires Core API changes to support new thread_id_t). Also there is a problem with statistics displaying (for top-level blocks parent_index had value of thread-id, it requires a work around now). --- easy_profiler_core/include/easy/reader.h | 5 ++++ easy_profiler_core/profile_manager.cpp | 7 ++++-- easy_profiler_core/reader.cpp | 4 ++++ profiler_gui/common_types.h | 29 ++++++++++++------------ 4 files changed, 29 insertions(+), 16 deletions(-) diff --git a/easy_profiler_core/include/easy/reader.h b/easy_profiler_core/include/easy/reader.h index 1958017..5b4f546 100644 --- a/easy_profiler_core/include/easy/reader.h +++ b/easy_profiler_core/include/easy/reader.h @@ -263,7 +263,12 @@ namespace profiler { }; // END of class BlocksTreeRoot. typedef ::profiler::BlocksTree::blocks_t blocks_t; + +#ifdef _WIN64 typedef ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot, ::profiler::passthrough_hash> thread_blocks_tree_t; +#else + typedef ::std::unordered_map<::profiler::thread_id_t, ::profiler::BlocksTreeRoot> thread_blocks_tree_t; +#endif ////////////////////////////////////////////////////////////////////////// diff --git a/easy_profiler_core/profile_manager.cpp b/easy_profiler_core/profile_manager.cpp index 817ba00..f791527 100644 --- a/easy_profiler_core/profile_manager.cpp +++ b/easy_profiler_core/profile_manager.cpp @@ -1041,7 +1041,10 @@ void ProfileManager::beginContextSwitch(profiler::thread_id_t _thread_id, profil if (ts != nullptr) // Dirty hack: _target_thread_id will be written to the field "block_id_t m_id" // and will be available calling method id(). - ts->sync.openedList.emplace_back(_time, _time, _target_thread_id, _target_process); +#ifndef _WIN32 +#pragma message "WARNING: Fix saving thread_id_t as block_id_t for Context-Switch events !!!!" +#endif + ts->sync.openedList.emplace_back(_time, _time, (profiler::block_id_t)_target_thread_id, _target_process); } ////////////////////////////////////////////////////////////////////////// @@ -1284,7 +1287,7 @@ char ProfileManager::checkThreadExpired(ThreadStorage& _registeredThread) // Check thread for Windows DWORD exitCode = 0; - auto hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, _registeredThread.id); + auto hThread = OpenThread(THREAD_QUERY_LIMITED_INFORMATION, FALSE, (DWORD)_registeredThread.id); if (hThread == nullptr || GetExitCodeThread(hThread, &exitCode) == FALSE || exitCode != STILL_ACTIVE) { // Thread has been expired diff --git a/easy_profiler_core/reader.cpp b/easy_profiler_core/reader.cpp index 3a8ca48..0e4578a 100644 --- a/easy_profiler_core/reader.cpp +++ b/easy_profiler_core/reader.cpp @@ -540,7 +540,11 @@ extern "C" { } } +#ifdef _WIN64 typedef ::std::unordered_map<::profiler::thread_id_t, StatsMap, ::profiler::passthrough_hash> PerThreadStats; +#else + typedef ::std::unordered_map<::profiler::thread_id_t, StatsMap> PerThreadStats; +#endif PerThreadStats parent_statistics, frame_statistics; IdMap identification_table; diff --git a/profiler_gui/common_types.h b/profiler_gui/common_types.h index 3c4ef6e..9e14ea8 100644 --- a/profiler_gui/common_types.h +++ b/profiler_gui/common_types.h @@ -100,42 +100,43 @@ inline qreal microseconds2units(qreal _value) namespace profiler_gui { -template -struct no_hasher { - template inline size_t operator () (const T& _data) const { - return (size_t)_data; - } +template +struct no_hasher : public ::std::hash { + using ::std::hash::operator (); + //inline size_t operator () (const T& _data) const { + // return ::std::hash::operator () (_data); + //} }; #ifdef _WIN64 -template <> struct no_hasher<8> { - template inline size_t operator () (T _data) const { +template struct no_hasher { + inline size_t operator () (T _data) const { return (size_t)_data; } }; #endif -template <> struct no_hasher<4> { - template inline size_t operator () (T _data) const { +template struct no_hasher { + inline size_t operator () (T _data) const { return (size_t)_data; } }; -template <> struct no_hasher<2> { - template inline size_t operator () (T _data) const { +template struct no_hasher { + inline size_t operator () (T _data) const { return (size_t)_data; } }; -template <> struct no_hasher<1> { - template inline size_t operator () (T _data) const { +template struct no_hasher { + inline size_t operator () (T _data) const { return (size_t)_data; } }; template struct do_no_hash { - typedef no_hasher hasher_t; + typedef no_hasher hasher_t; }; //////////////////////////////////////////////////////////////////////////