diff --git a/CMakeLists.txt b/CMakeLists.txt index 81fb83b..7fd156e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,8 +25,14 @@ include_directories( if(UNIX) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -pedantic" ) +else() + add_definitions( + -D_CRT_SECURE_NO_WARNINGS + ) endif(UNIX) + + add_subdirectory(src) add_subdirectory(sample) add_subdirectory(reader) \ No newline at end of file diff --git a/include/profiler/profiler.h b/include/profiler/profiler.h index f29ece5..8f84019 100644 --- a/include/profiler/profiler.h +++ b/include/profiler/profiler.h @@ -27,26 +27,123 @@ along with this program.If not, see . #endif #ifndef FULL_DISABLE_PROFILER -#define PROFILER_ADD_MARK(name) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,0,profiler::BLOCK_TYPE_MARK);\ - profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); -#define PROFILER_ADD_MARK_GROUPED(name,block_group) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group,profiler::BLOCK_TYPE_MARK);\ - profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); +/** +\defgroup profiler Profiler +*/ +/** Macro of beginning of block with custom name and default identification + +\code + #include "profiler/profiler.h" + void foo() + { + // some code ... + if(something){ + PROFILER_BEGIN_BLOCK("Calling someThirdPartyLongFunction()"); + someThirdPartyLongFunction(); + return; + } + } +\endcode + +Block will be automatically completed by destructor + +\ingroup profiler +*/ #define PROFILER_BEGIN_BLOCK(name) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,0,profiler::BLOCK_TYPE_BLOCK);\ profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); +/** Macro of beginning of block with custom name and custom identification + +\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(name,block_group) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group,profiler::BLOCK_TYPE_BLOCK);\ profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); +/** Macro of beginning of function block with default identification + +\code + #include "profiler/profiler.h" + void foo() + { + PROFILER_BEGIN_FUNCTION_BLOCK; + //some code... + } +\endcode + +Name of block automatically created with function name + +\ingroup profiler +*/ #define PROFILER_BEGIN_FUNCTION_BLOCK PROFILER_BEGIN_BLOCK(__func__) -#define PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(block_group) PROFILER_BEGIN_BLOCK_GROUPED(__func__,block_group) +/** 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 + +\code +#include "profiler/profiler.h" +void foo() +{ +// some code ... + int sum = 0; + PROFILER_BEGIN_BLOCK("Calculating summ"); + for(int i = 0; i < 10; i++){ + sum += i; + } + PROFILER_END_BLOCK; +} +\endcode + +\ingroup profiler +*/ #define PROFILER_END_BLOCK profiler::endBlock(); +#define PROFILER_ADD_EVENT(name) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,0,profiler::BLOCK_TYPE_EVENT);\ + profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); + +#define PROFILER_ADD_EVENT_GROUPED(name,block_group) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group,profiler::BLOCK_TYPE_EVENT);\ + profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); + +/** Macro enabling profiler +\ingroup profiler +*/ #define PROFILER_ENABLE profiler::setEnabled(true); +/** Macro disabling profiler +\ingroup profiler +*/ #define PROFILER_DISABLE profiler::setEnabled(false); #else @@ -86,48 +183,50 @@ namespace profiler typedef uint8_t block_type_t; typedef uint64_t timestamp_t; - typedef uint16_t color_t; + typedef uint16_t color_t; //16-bit RGB format (5-6-5) typedef uint32_t thread_id_t; - const block_type_t BLOCK_TYPE_MARK = 1; + const block_type_t BLOCK_TYPE_EVENT = 1; const block_type_t BLOCK_TYPE_BLOCK = 2; #pragma pack(push,1) - struct PROFILER_API BaseBlockData + class PROFILER_API BaseBlockData { + protected: + block_type_t type; color_t color; timestamp_t begin; timestamp_t end; thread_id_t thread_id; + void tick(timestamp_t& stamp); + public: + BaseBlockData(color_t _color, block_type_t _type); + inline unsigned char getType() const { return type; } + inline color_t getColor() const { return color; } + inline timestamp_t getBegin() const { return begin; } + inline size_t getThreadId() const { return thread_id; } + + inline timestamp_t getEnd() const { return end; } + inline bool isFinished() const { return end != 0; } + inline bool isCleared() const { return end >= begin; } + inline void finish(){ tick(end); } timestamp_t duration() const { return (end - begin); } }; #pragma pack(pop) class PROFILER_API Block : public BaseBlockData { - const char *name; - void tick(timestamp_t& stamp); - - public: + const char *name; + public: - Block(const char* _name, color_t _color = 0, block_type_t _type = BLOCK_TYPE_MARK); + Block(const char* _name, color_t _color = 0, block_type_t _type = BLOCK_TYPE_EVENT); + ~Block(); - inline unsigned char getType() const { return type; } - inline color_t getColor() const { return color; } - inline timestamp_t getBegin() const { return begin; } - inline size_t getThreadId() const { return thread_id; } - inline const char* getName() const { return name; } - - inline timestamp_t getEnd() const { return end; } - inline bool isFinished() const { return end != 0; } - inline bool isCleared() const { return end >= begin; } - inline void finish(){ tick(end); } - - ~Block(); + inline const char* getName() const { return name; } }; class PROFILER_API SerilizedBlock diff --git a/reader/main.cpp b/reader/main.cpp index 74eab41..b70482d 100644 --- a/reader/main.cpp +++ b/reader/main.cpp @@ -32,7 +32,7 @@ int main() blocksList.emplace_back(sz, data); } for (auto& i : blocksList){ - static auto thread_id = i.block()->thread_id; + static auto thread_id = i.block()->getThreadId(); //if (i.block()->thread_id == thread_id) std::cout << i.block()->duration() << "\n"; //std::cout << i.getBlockName() << ":" << (i.block()->end - i.block()->begin)/1000 << " usec." << std::endl; diff --git a/sample/main.cpp b/sample/main.cpp index bdcc2d1..c22bb0b 100644 --- a/sample/main.cpp +++ b/sample/main.cpp @@ -47,7 +47,7 @@ void frame(){ void loadingResourcesThread(){ for(int i = 0; i < 10; i++){ loadingResources(); - PROFILER_ADD_MARK("Resources Loading!"); + PROFILER_ADD_EVENT("Resources Loading!"); std::this_thread::sleep_for(std::chrono::milliseconds(2)); } } diff --git a/src/block.cpp b/src/block.cpp index 7a4d2ae..354de61 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -21,14 +21,14 @@ Block::Block(const char* _name, color_t _color, block_type_t _type) : name(_name) { tick(begin); - if (this->type == BLOCK_TYPE_MARK) + if (this->type == BLOCK_TYPE_EVENT) { end = begin; } thread_id = std::hash()(std::this_thread::get_id()); } -void Block::tick(timestamp_t& stamp) +void BaseBlockData::tick(timestamp_t& stamp) { std::chrono::time_point time_point; time_point = std::chrono::time_point_cast(std::chrono::system_clock::now()); diff --git a/src/profile_manager.cpp b/src/profile_manager.cpp index 611b968..da0a14b 100644 --- a/src/profile_manager.cpp +++ b/src/profile_manager.cpp @@ -100,7 +100,7 @@ void ProfileManager::beginBlock(Block* _block) { if (!m_isEnabled) return; - if (_block->getType() != BLOCK_TYPE_MARK){ + if (_block->getType() != BLOCK_TYPE_EVENT){ guard_lock_t lock(m_spin); m_openedBracketsMap[_block->getThreadId()].push(_block); }