From 71f95f2c874e24eef0cb627ffc520dbf3f91c007 Mon Sep 17 00:00:00 2001 From: Victor Zarubkin Date: Sun, 28 Aug 2016 23:40:23 +0300 Subject: [PATCH] (profiler_core) Simplifying API: there are ~1.5 times lower macros number for using profiler. --- include/profiler/profiler.h | 225 ++++++++++++++++-------------------- reader/main.cpp | 2 +- sample/main.cpp | 56 ++++----- src/block.cpp | 2 +- src/profile_manager.cpp | 14 +-- src/profile_manager.h | 2 +- src/reader.cpp | 30 ++--- 7 files changed, 153 insertions(+), 178 deletions(-) diff --git a/include/profiler/profiler.h b/include/profiler/profiler.h index 9d666c5..31f1535 100644 --- a/include/profiler/profiler.h +++ b/include/profiler/profiler.h @@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License along with this program.If not, see . **/ -#ifndef ____PROFILER____H_______ -#define ____PROFILER____H_______ +#ifndef EASY_PROFILER____H_______ +#define EASY_PROFILER____H_______ #if defined ( WIN32 ) #define __func__ __FUNCTION__ @@ -25,26 +25,34 @@ along with this program.If not, see . #ifndef FULL_DISABLE_PROFILER -#define TOKEN_JOIN(x, y) x ## y -#define TOKEN_CONCATENATE(x, y) TOKEN_JOIN(x, y) -#define PROFILER_UNIQUE_BLOCK(x) TOKEN_CONCATENATE(unique_profiler_mark_name_, x) -#define PROFILER_UNIQUE_DESC(x) TOKEN_CONCATENATE(unique_profiler_descriptor_, x) +#include + +#define EASY_TOKEN_JOIN(x, y) x ## y +#define EASY_TOKEN_CONCATENATE(x, y) EASY_TOKEN_JOIN(x, y) +#define EASY_UNIQUE_BLOCK(x) EASY_TOKEN_CONCATENATE(unique_profiler_mark_name_, x) +#define EASY_UNIQUE_DESC(x) EASY_TOKEN_CONCATENATE(unique_profiler_descriptor_, x) /** \defgroup profiler Profiler */ -/** Macro used to check compile-time strings. +namespace profiler { + template struct NameSwitch final { + static const char* runtime_name(const char*) { return ""; } + static const char* compiletime_name(const char* name) { return name; } + }; -Compiler automatically concatenates "A" "B" into "AB" if both A and B strings -can be identified at compile-time. + template <> struct NameSwitch final { + static const char* runtime_name(const char* name) { return name; } + static const char* compiletime_name(const char*) { return ""; } + }; +} // END of namespace profiler. -\ingroup profiler -*/ -#define COMPILETIME_TEST "_compiletime_test" +#define EASY_COMPILETIME_NAME(name) ::profiler::NameSwitch<::std::is_reference::value>::compiletime_name(name) +#define EASY_RUNTIME_NAME(name) ::profiler::NameSwitch<::std::is_reference::value>::runtime_name(name) -/** Macro of beginning of block with custom name and default identification +/** Macro of beginning of block with custom name and color. \code #include "profiler/profiler.h" @@ -52,161 +60,126 @@ can be identified at compile-time. { // some code ... if(something){ - PROFILER_BEGIN_BLOCK("Calling someThirdPartyLongFunction()"); - someThirdPartyLongFunction(); - return; + EASY_BLOCK("Calling bar()"); // Block with default color + bar(); } + else{ + EASY_BLOCK("Calling baz()", profiler::colors::Red); // Red block + baz(); + } } \endcode -Block will be automatically completed by destructor +Block will be automatically completed by destructor. \ingroup profiler */ -#define PROFILER_BEGIN_BLOCK(compiletime_name)\ - static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\ - ::profiler::BLOCK_TYPE_BLOCK, ::profiler::DefaultBlockColor);\ - ::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_BLOCK,\ - PROFILER_UNIQUE_DESC(__LINE__).id());\ - ::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable +#define EASY_BLOCK(name, ...)\ + static const ::profiler::StaticBlockDescriptor EASY_UNIQUE_DESC(__LINE__)(EASY_COMPILETIME_NAME(name), __FILE__, __LINE__,\ + ::profiler::BLOCK_TYPE_BLOCK , ## __VA_ARGS__);\ + ::profiler::Block EASY_UNIQUE_BLOCK(__LINE__)(::profiler::BLOCK_TYPE_BLOCK, EASY_UNIQUE_DESC(__LINE__).id(), EASY_RUNTIME_NAME(name));\ + ::profiler::beginBlock(EASY_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable -#define EASY_BLOCK(compiletime_name)\ - static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\ - ::profiler::BLOCK_TYPE_BLOCK, ::profiler::DefaultBlockColor);\ - ::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_BLOCK,\ - PROFILER_UNIQUE_DESC(__LINE__).id());\ - ::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable - -#define EASY_BLOCK_RUNTIME(runtime_name)\ - static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)("", __FILE__, __LINE__,\ - ::profiler::BLOCK_TYPE_BLOCK, ::profiler::DefaultBlockColor);\ - ::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(nullptr, ::profiler::BLOCK_TYPE_BLOCK,\ - PROFILER_UNIQUE_DESC(__LINE__).id(), runtime_name);\ - ::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable - -/** Macro of beginning of block with custom name and custom identification +/** Macro of beginning of block with function name and custom color. \code #include "profiler/profiler.h" - void foo() - { - // some code ... - if(something){ - PROFILER_BEGIN_BLOCK("Calling someThirdPartyLongFunction()", ::profiler::colors::Red); - someThirdPartyLongFunction(); - return; - } - } -\endcode - -Block will be automatically completed by destructor - -\ingroup profiler -*/ -#define PROFILER_BEGIN_BLOCK_GROUPED(compiletime_name, block_group)\ - static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\ - ::profiler::BLOCK_TYPE_BLOCK, block_group);\ - ::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_BLOCK,\ - PROFILER_UNIQUE_DESC(__LINE__).id());\ - ::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable - -/** Macro of beginning of function block with default identification - -\code - #include "profiler/profiler.h" - void foo() - { - PROFILER_BEGIN_FUNCTION_BLOCK; + void foo(){ + EASY_FUNCTION(); // Block with name="foo" and default color //some code... } + + void bar(){ + EASY_FUNCTION(profiler::colors::Green); // Green block with name="bar" + //some code... + } \endcode -Name of block automatically created with function name +Name of the block automatically created with function name. \ingroup profiler */ -#define PROFILER_BEGIN_FUNCTION_BLOCK PROFILER_BEGIN_BLOCK(__func__) +#define EASY_FUNCTION(...) EASY_BLOCK(__func__ , ## __VA_ARGS__) -/** Macro of beginning of function block with custom identification - -\code - #include "profiler/profiler.h" - void foo() - { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); - //some code... - } -\endcode - -Name of block automatically created with function name - -\ingroup profiler -*/ -#define PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(block_color) PROFILER_BEGIN_BLOCK_GROUPED(__func__, block_color) - -/** Macro of completion of last nearest open block +/** Macro of completion of last nearest open block. \code #include "profiler/profiler.h" -void foo() +int foo() { -// some code ... + // some code ... + int sum = 0; - PROFILER_BEGIN_BLOCK("Calculating summ"); - for(int i = 0; i < 10; i++){ + EASY_BLOCK("Calculating sum"); + for (int i = 0; i < 10; ++i){ sum += i; } - PROFILER_END_BLOCK; + EASY_END_BLOCK; + + // some antoher code here ... + + return sum; } \endcode \ingroup profiler */ -#define PROFILER_END_BLOCK ::profiler::endBlock(); +#define EASY_END_BLOCK ::profiler::endBlock(); -#define PROFILER_ADD_EVENT(compiletime_name) \ - static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__, ::profiler::BLOCK_TYPE_EVENT);\ - ::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_EVENT,\ - PROFILER_UNIQUE_DESC(__LINE__).id());\ - ::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable +/** Macro of creating event with custom name and color. -#define PROFILER_ADD_EVENT_GROUPED(compiletime_name, block_group)\ - static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\ - ::profiler::BLOCK_TYPE_EVENT, block_group);\ - ::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_EVENT,\ - PROFILER_UNIQUE_DESC(__LINE__).id());\ - ::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable +Event is a block with zero duration and special type. + +\warning Event ends immidiately and calling EASY_END_BLOCK after EASY_EVENT +will end previously opened EASY_BLOCK or EASY_FUNCTION. + +\ingroup profiler +*/ +#define EASY_EVENT(name, ...)\ + static const ::profiler::StaticBlockDescriptor EASY_UNIQUE_DESC(__LINE__)(EASY_COMPILETIME_NAME(name), __FILE__, __LINE__,\ + ::profiler::BLOCK_TYPE_EVENT , ## __VA_ARGS__);\ + ::profiler::Block EASY_UNIQUE_BLOCK(__LINE__)(::profiler::BLOCK_TYPE_EVENT, EASY_UNIQUE_DESC(__LINE__).id(), EASY_RUNTIME_NAME(name));\ + ::profiler::beginBlock(EASY_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable /** Macro enabling profiler \ingroup profiler */ -#define PROFILER_ENABLE ::profiler::setEnabled(true); +#define EASY_PROFILER_ENABLE ::profiler::setEnabled(true); /** Macro disabling profiler \ingroup profiler */ -#define PROFILER_DISABLE ::profiler::setEnabled(false); +#define EASY_PROFILER_DISABLE ::profiler::setEnabled(false); +/** Macro of naming current thread. + +If this thread has been already named then nothing changes. + +\ingroup profiler +*/ #ifdef WIN32 -#define PROFILER_SET_THREAD_NAME(name) ::profiler::setThreadName(name); +#define EASY_THREAD(name) ::profiler::setThreadName(name, __FILE__, __func__, __LINE__); #else -#define PROFILER_SET_THREAD_NAME(name) thread_local static const ::profiler::ThreadNameSetter TOKEN_CONCATENATE(unique_profiler_thread_name_setter_, __LINE__)(name); +#define EASY_THREAD(name) thread_local static const ::profiler::ThreadNameSetter EASY_TOKEN_CONCATENATE(unique_profiler_thread_name_setter_, __LINE__)(name, __FILE__, __func__, __LINE__); #endif -#define PROFILER_SET_MAIN_THREAD PROFILER_SET_THREAD_NAME("Main") +/** Macro of naming main thread. + +This is only for user comfort. There is no difference for EasyProfiler GUI between different threads. + +\ingroup profiler +*/ +#define EASY_MAIN_THREAD EASY_THREAD("Main") #else -#define PROFILER_BEGIN_BLOCK(name) -#define PROFILER_BEGIN_BLOCK_GROUPED(name, block_group) -#define PROFILER_BEGIN_FUNCTION_BLOCK -#define PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(block_group) -#define PROFILER_END_BLOCK -#define PROFILER_ENABLE -#define PROFILER_DISABLE -#define PROFILER_ADD_EVENT(name) -#define PROFILER_ADD_EVENT_GROUPED(name, block_group) -#define PROFILER_SET_THREAD_NAME(name) -#define PROFILER_SET_MAIN_THREAD +#define EASY_BLOCK(...) +#define EASY_FUNCTION(...) +#define EASY_END_BLOCK +#define EASY_PROFILER_ENABLE +#define EASY_PROFILER_DISABLE +#define EASY_EVENT(...) +#define EASY_THREAD(...) +#define EASY_MAIN_THREAD #endif #include @@ -236,7 +209,7 @@ namespace profiler { void PROFILER_API endBlock(); void PROFILER_API setEnabled(bool isEnable); unsigned int PROFILER_API dumpBlocksToFile(const char* filename); - void PROFILER_API setThreadName(const char* name); + void PROFILER_API setThreadName(const char* name, const char* filename, const char* _funcname, int line); } typedef uint64_t timestamp_t; @@ -320,7 +293,7 @@ namespace profiler { public: - Block(const char*, block_type_t _block_type, block_id_t _id, const char* _name = ""); + Block(block_type_t _block_type, block_id_t _id, const char* _name = ""); ~Block(); inline const char* name() const { return m_name; } @@ -334,16 +307,16 @@ namespace profiler { public: - StaticBlockDescriptor(const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color = colors::Random); + StaticBlockDescriptor(const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color = DefaultBlockColor); block_id_t id() const { return m_id; } }; #ifndef WIN32 struct PROFILER_API ThreadNameSetter final { - ThreadNameSetter(const char* _name) + ThreadNameSetter(const char* _name, const char* _filename, const char* _funcname, int _line) { - setThreadName(_name); + setThreadName(_name, _filename, _funcname, _line); } }; #endif @@ -352,4 +325,4 @@ namespace profiler { } // END of namespace profiler. -#endif +#endif // EASY_PROFILER____H_______ diff --git a/reader/main.cpp b/reader/main.cpp index c356840..ed696d1 100644 --- a/reader/main.cpp +++ b/reader/main.cpp @@ -99,7 +99,7 @@ int main(int argc, char* argv[]) if (dump_filename.size() > 2) { - PROFILER_ENABLE + EASY_PROFILER_ENABLE; std::cout << "Will dump reader prof file to " << dump_filename << std::endl; } else diff --git a/sample/main.cpp b/sample/main.cpp index 3513020..7ef3014 100644 --- a/sample/main.cpp +++ b/sample/main.cpp @@ -26,13 +26,13 @@ void localSleep(int magic=200000) } void loadingResources(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Darkcyan); + EASY_FUNCTION(profiler::colors::Darkcyan); localSleep(); // std::this_thread::sleep_for(std::chrono::milliseconds(50)); } void prepareMath(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + EASY_FUNCTION(profiler::colors::Blue); int* intarray = new int[OBJECTS]; for (int i = 0; i < OBJECTS; ++i) intarray[i] = i * i; @@ -41,7 +41,7 @@ void prepareMath(){ } void calcIntersect(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + EASY_FUNCTION(profiler::colors::Blue); //int* intarray = new int[OBJECTS * OBJECTS]; int* intarray = new int[OBJECTS]; for (int i = 0; i < OBJECTS; ++i) @@ -56,12 +56,12 @@ void calcIntersect(){ double multModel(double i) { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + EASY_FUNCTION(profiler::colors::Blue); return i * sin(i) * cos(i); } void calcPhys(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + EASY_FUNCTION(profiler::colors::Blue); double* intarray = new double[OBJECTS]; for (int i = 0; i < OBJECTS; ++i) intarray[i] = multModel(double(i)) + double(i / 3) - double((OBJECTS - i) / 2); @@ -71,12 +71,12 @@ void calcPhys(){ double calcSubbrain(int i) { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + EASY_FUNCTION(profiler::colors::Blue); return i * i * i - i / 10 + (OBJECTS - i) * 7 ; } void calcBrain(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue); + EASY_FUNCTION(profiler::colors::Blue); double* intarray = new double[OBJECTS]; for (int i = 0; i < OBJECTS; ++i) intarray[i] = calcSubbrain(i) + double(i * 180 / 3); @@ -85,19 +85,19 @@ void calcBrain(){ } void calculateBehavior(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Darkblue); + EASY_FUNCTION(profiler::colors::Darkblue); calcPhys(); calcBrain(); } void modellingStep(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Navy); + EASY_FUNCTION(profiler::colors::Navy); prepareMath(); calculateBehavior(); } void prepareRender(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Darkred); + EASY_FUNCTION(profiler::colors::Darkred); localSleep(); //std::this_thread::sleep_for(std::chrono::milliseconds(8)); @@ -105,18 +105,18 @@ void prepareRender(){ int multPhys(int i) { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); return i * i * i * i / 100; } int calcPhysicForObject(int i) { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); return multPhys(i) + i / 3 - (OBJECTS - i) * 15; } void calculatePhysics(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); unsigned int* intarray = new unsigned int[OBJECTS]; for (int i = 0; i < OBJECTS; ++i) intarray[i] = calcPhysicForObject(i); @@ -125,7 +125,7 @@ void calculatePhysics(){ } void frame(){ - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Magenta); + EASY_FUNCTION(profiler::colors::Magenta); prepareRender(); calculatePhysics(); } @@ -133,10 +133,10 @@ void frame(){ void loadingResourcesThread(){ //std::unique_lock lk(cv_m); //cv.wait(lk, []{return g_i == 1; }); - PROFILER_SET_THREAD_NAME("Resource loading") + EASY_THREAD("Resource loading"); for(int i = 0; i < RESOURCE_LOADING_COUNT; i++){ loadingResources(); - PROFILER_ADD_EVENT_GROUPED("Resources Loading!",profiler::colors::Cyan); + EASY_EVENT("Resources Loading!", profiler::colors::Cyan); localSleep(1200000); //std::this_thread::sleep_for(std::chrono::milliseconds(20)); } @@ -145,8 +145,8 @@ void loadingResourcesThread(){ void modellingThread(){ //std::unique_lock lk(cv_m); //cv.wait(lk, []{return g_i == 1; }); - PROFILER_SET_THREAD_NAME("Modelling") - for (int i = 0; i < RENDER_SPEPS; i++){ + EASY_THREAD("Modelling"); + for (int i = 0; i < RENDER_SPEPS; i++){ modellingStep(); localSleep(1200000); //std::this_thread::sleep_for(std::chrono::milliseconds(20)); @@ -156,7 +156,7 @@ void modellingThread(){ void renderThread(){ //std::unique_lock lk(cv_m); //cv.wait(lk, []{return g_i == 1; }); - PROFILER_SET_THREAD_NAME("Render") + EASY_THREAD("Render"); for (int i = 0; i < MODELLING_STEPS; i++){ frame(); localSleep(1200000); @@ -166,24 +166,24 @@ void renderThread(){ void four() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); std::this_thread::sleep_for(std::chrono::milliseconds(37)); } void five() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); std::this_thread::sleep_for(std::chrono::milliseconds(20)); } void six() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); std::this_thread::sleep_for(std::chrono::milliseconds(42)); } void three() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); four(); five(); six(); @@ -191,19 +191,19 @@ void three() void seven() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); std::this_thread::sleep_for(std::chrono::milliseconds(147)); } void two() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); std::this_thread::sleep_for(std::chrono::milliseconds(26)); } void one() { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red); + EASY_FUNCTION(profiler::colors::Red); two(); three(); seven(); @@ -240,8 +240,8 @@ int main(int argc, char* argv[]) std::cout << "Resource loading count: " << RESOURCE_LOADING_COUNT << std::endl; auto start = std::chrono::system_clock::now(); - PROFILER_ENABLE; - PROFILER_SET_MAIN_THREAD; + EASY_PROFILER_ENABLE; + EASY_MAIN_THREAD; //one(); //one(); /**/ diff --git a/src/block.cpp b/src/block.cpp index 2acd3d5..7acad7b 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -38,7 +38,7 @@ BaseBlockData::BaseBlockData(timestamp_t _begin_time, block_id_t _descriptor_id) } -Block::Block(const char*, block_type_t _block_type, block_id_t _descriptor_id, const char* _name) +Block::Block(block_type_t _block_type, block_id_t _descriptor_id, const char* _name) : BaseBlockData(getCurrentTime(), _descriptor_id) , m_name(_name) { diff --git a/src/profile_manager.cpp b/src/profile_manager.cpp index 85e5e52..ffce286 100644 --- a/src/profile_manager.cpp +++ b/src/profile_manager.cpp @@ -31,9 +31,9 @@ extern "C"{ return MANAGER.dumpBlocksToFile(filename); } - void PROFILER_API setThreadName(const char* name) + void PROFILER_API setThreadName(const char* name, const char* filename, const char* _funcname, int line) { - return MANAGER.setThreadName(name); + return MANAGER.setThreadName(name, filename, _funcname, line); } } @@ -66,7 +66,7 @@ BlockDescriptor::BlockDescriptor(uint64_t& _used_mem, const char* _name, const c , m_name(_name) , m_filename(_filename) { - _used_mem += sizeof(profiler::BaseBlockDescriptor) + strlen(_name) + strlen(_filename) + 2; + _used_mem += sizeof(profiler::SerializedBlockDescriptor) + strlen(_name) + strlen(_filename) + 2; } ////////////////////////////////////////////////////////////////////////// @@ -185,7 +185,7 @@ uint32_t ProfileManager::dumpBlocksToFile(const char* filename) { const auto name_size = static_cast(strlen(descriptor.name()) + 1); const auto filename_size = static_cast(strlen(descriptor.file()) + 1); - const auto size = static_cast(sizeof(profiler::BaseBlockDescriptor) + name_size + filename_size + sizeof(uint16_t)); + const auto size = static_cast(sizeof(profiler::SerializedBlockDescriptor) + name_size + filename_size); of.write(size); of.write(descriptor); @@ -212,14 +212,14 @@ uint32_t ProfileManager::dumpBlocksToFile(const char* filename) return blocks_number; } -void ProfileManager::setThreadName(const char* name) +void ProfileManager::setThreadName(const char* name, const char* filename, const char* _funcname, int line) { auto& thread_storage = threadStorage(getCurrentThreadId()); if (thread_storage.named) return; - const auto id = addBlockDescriptor("ThreadName", __FILE__, __LINE__, profiler::BLOCK_TYPE_THREAD_SIGN, profiler::colors::Random); - thread_storage.store(profiler::Block(nullptr, profiler::BLOCK_TYPE_THREAD_SIGN, id, name)); + const auto id = addBlockDescriptor(_funcname, filename, line, profiler::BLOCK_TYPE_THREAD_SIGN, profiler::colors::Random); + thread_storage.store(profiler::Block(profiler::BLOCK_TYPE_THREAD_SIGN, id, name)); thread_storage.named = true; } diff --git a/src/profile_manager.h b/src/profile_manager.h index abc1da5..df72031 100644 --- a/src/profile_manager.h +++ b/src/profile_manager.h @@ -139,7 +139,7 @@ public: void endBlock(); void setEnabled(bool isEnable); uint32_t dumpBlocksToFile(const char* filename); - void setThreadName(const char* name); + void setThreadName(const char* name, const char* filename, const char* _funcname, int line); private: diff --git a/src/reader.cpp b/src/reader.cpp index 893148e..aee8d86 100644 --- a/src/reader.cpp +++ b/src/reader.cpp @@ -260,7 +260,7 @@ extern "C" { unsigned int fillTreesFromFile(::std::atomic& progress, const char* filename, ::profiler::SerializedData& serialized_blocks, ::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics) { - PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(::profiler::colors::Cyan) + EASY_FUNCTION(::profiler::colors::Cyan); ::std::ifstream inFile(filename, ::std::fstream::binary); progress.store(0); @@ -299,16 +299,19 @@ extern "C" { serialized_descriptors.set(new char[descriptors_memory_size]); uint64_t i = 0; - uint32_t read_number = 0; - while (!inFile.eof() && read_number < total_descriptors_number) + while (!inFile.eof() && descriptors.size() < total_descriptors_number) { - ++read_number; - uint16_t sz = 0; inFile.read((char*)&sz, sizeof(sz)); if (sz == 0) return 0; + //if (i + sz > descriptors_memory_size) + //{ + // printf("FILE CORRUPTED\n"); + // return 0; + //} + char* data = serialized_descriptors[i]; inFile.read(data, sz); auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data); @@ -321,10 +324,10 @@ extern "C" { IdMap identification_table; i = 0; - read_number = 0; + uint32_t read_number = 0; while (!inFile.eof() && read_number < total_blocks_number) { - PROFILER_BEGIN_BLOCK_GROUPED("Read thread from file", ::profiler::colors::Darkgreen) + EASY_BLOCK("Read thread data", ::profiler::colors::Darkgreen); ::profiler::thread_id_t thread_id = 0; inFile.read((char*)&thread_id, sizeof(decltype(thread_id))); @@ -336,7 +339,7 @@ extern "C" { const auto threshold = read_number + blocks_number_in_thread; while (!inFile.eof() && read_number < threshold) { - PROFILER_BEGIN_BLOCK_GROUPED("Read block from file", ::profiler::colors::Green) + EASY_BLOCK("Read block", ::profiler::colors::Green); ++read_number; @@ -389,7 +392,7 @@ extern "C" { { //auto lower = ::std::lower_bound(root.children.begin(), root.children.end(), tree); /**/ - PROFILER_BEGIN_BLOCK_GROUPED("Find children", ::profiler::colors::Blue) + EASY_BLOCK("Find children", ::profiler::colors::Blue); auto rlower1 = ++root.tree.children.rbegin(); for (; rlower1 != root.tree.children.rend(); ++rlower1) { @@ -402,12 +405,12 @@ extern "C" { ::std::move(lower, root.tree.children.end(), ::std::back_inserter(tree.children)); root.tree.children.erase(lower, root.tree.children.end()); - PROFILER_END_BLOCK + EASY_END_BLOCK; ::profiler::timestamp_t children_duration = 0; if (gather_statistics) { - PROFILER_BEGIN_BLOCK_GROUPED("Gather statistic within parent", ::profiler::colors::Magenta) + EASY_BLOCK("Gather statistic within parent", ::profiler::colors::Magenta); per_parent_statistics.clear(); //per_parent_statistics.reserve(tree.children.size()); // this gives slow-down on Windows @@ -443,7 +446,7 @@ extern "C" { if (gather_statistics) { - PROFILER_BEGIN_BLOCK_GROUPED("Gather per thread statistics", ::profiler::colors::Coral) + EASY_BLOCK("Gather per thread statistics", ::profiler::colors::Coral); auto& current = root.tree.children.back(); current.per_thread_stats = update_statistics(per_thread_statistics, current); } @@ -461,7 +464,7 @@ extern "C" { return 0; } - PROFILER_BEGIN_BLOCK_GROUPED("Gather statistics for roots", ::profiler::colors::Purple) + EASY_BLOCK("Gather statistics for roots", ::profiler::colors::Purple); if (gather_statistics) { ::std::vector<::std::thread> statistics_threads; @@ -521,7 +524,6 @@ extern "C" { progress.store(90 + (10 * ++j) / n); } } - PROFILER_END_BLOCK // No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors return blocks_counter;