From 9cf3ca02b7fdfeaeee2823daa296496b4f067bbf Mon Sep 17 00:00:00 2001 From: Sergey Yagovtsev Date: Sat, 20 Feb 2016 05:24:12 +0300 Subject: [PATCH] 1) Removed Mark entity. Only Block with type 2) Added simple implementation of serializing blocks and storing it. --- include/profiler/profiler.h | 60 ++++++++++++++++++++----------------- src/block.cpp | 43 +++++++++++++------------- src/profile_manager.cpp | 58 ++++++++++++++++++++++++++--------- src/profile_manager.h | 23 ++++++++++++-- 4 files changed, 117 insertions(+), 67 deletions(-) diff --git a/include/profiler/profiler.h b/include/profiler/profiler.h index e0d2b8b..2926132 100644 --- a/include/profiler/profiler.h +++ b/include/profiler/profiler.h @@ -27,16 +27,16 @@ along with this program.If not, see . #endif #ifndef FULL_DISABLE_PROFILER -#define PROFILER_ADD_MARK(name) profiler::Mark TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name);\ - profiler::registerMark(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); - -#define PROFILER_ADD_MARK_GROUPED(name,block_group) profiler::Mark TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group);\ - profiler::registerMark(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)); - -#define PROFILER_BEGIN_BLOCK(name) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name);\ +#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_BEGIN_BLOCK_GROUPED(name,block_group) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group);\ +#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__)); + +#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__)); + +#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__)); #define PROFILER_BEGIN_FUNCTION_BLOCK PROFILER_BEGIN_BLOCK(__func__) @@ -76,32 +76,42 @@ along with this program.If not, see . namespace profiler { - class Mark; class Block; extern "C"{ - void PROFILER_API registerMark(Mark* _mark); void PROFILER_API beginBlock(Block* _block); void PROFILER_API endBlock(); void PROFILER_API setEnabled(bool isEnable); - } + typedef uint8_t block_type_t; typedef uint64_t timestamp_t; - typedef unsigned char color_t; + typedef uint16_t color_t; + typedef uint32_t thread_id_t; - class PROFILER_API Mark + const block_type_t BLOCK_TYPE_MARK = 1; + const block_type_t BLOCK_TYPE_BLOCK = 2; + +#pragma pack(push,1) + struct PROFILER_API BaseBlockData + { + block_type_t type; + color_t color; + timestamp_t begin; + timestamp_t end; + thread_id_t thread_id; + + BaseBlockData(color_t _color, block_type_t _type); + }; +#pragma pack(pop) + + class PROFILER_API Block : public BaseBlockData { - protected: - unsigned char type; - color_t color; - timestamp_t begin; - size_t thread_id; const char *name; void tick(timestamp_t& stamp); public: - Mark(const char* _name, color_t _color = 0); + Block(const char* _name, color_t _color = 0, block_type_t _type = BLOCK_TYPE_MARK); inline unsigned char getType() const { return type; } inline color_t getColor() const { return color; } @@ -109,19 +119,13 @@ namespace profiler inline size_t getThreadId() const { return thread_id; } inline const char* getName() const { return name; } - }; - - class PROFILER_API Block : public Mark - { - timestamp_t end; - public: - Block(const char* _name, color_t _color = 0); - ~Block(); - 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(); + }; } diff --git a/src/block.cpp b/src/block.cpp index 2571038..41cd5eb 100644 --- a/src/block.cpp +++ b/src/block.cpp @@ -6,44 +6,41 @@ using namespace profiler; -const int NAME_LENGTH = 64; - -const unsigned char MARK_TYPE_LOCAL_EVENT = 1; -const unsigned char MARK_TYPE_GLOBAL_EVENT = 2; -const unsigned char MARK_TYPE_BEGIN = 3; -const unsigned char MARK_TYPE_END = 4; - -Mark::Mark(const char* _name, color_t _color) : - type(0), +BaseBlockData::BaseBlockData(color_t _color, block_type_t _type) : + type(_type), color(_color), begin(0), - thread_id(0), + end(0), + thread_id(0) +{ + +} + +Block::Block(const char* _name, color_t _color, block_type_t _type) : + BaseBlockData(_color,_type), name(_name) { tick(begin); thread_id = std::hash()(std::this_thread::get_id()); } -void Mark::tick(timestamp_t& stamp) +void Block::tick(timestamp_t& stamp) { std::chrono::time_point time_point; time_point = std::chrono::time_point_cast(std::chrono::system_clock::now()); stamp = time_point.time_since_epoch().count(); } -Block::Block(const char* _name, color_t _color) : - Mark(_name, _color), - end(0) -{ - -} - Block::~Block() { - if (this->isCleared()) - return; - if (!this->isFinished()) - this->finish(); + if (this->type == BLOCK_TYPE_BLOCK) + { + if (this->isCleared())//this block was cleared by END_BLOCK macros + return; + if (!this->isFinished()) + this->finish(); - endBlock(); + endBlock(); + } + } diff --git a/src/profile_manager.cpp b/src/profile_manager.cpp index 53d4d19..7819bcc 100644 --- a/src/profile_manager.cpp +++ b/src/profile_manager.cpp @@ -6,11 +6,6 @@ using namespace profiler; extern "C"{ - void PROFILER_API registerMark(Mark* _mark) - { - ProfileManager::instance().registerMark(_mark); - } - void PROFILER_API endBlock() { ProfileManager::instance().endBlock(); @@ -26,12 +21,41 @@ extern "C"{ } } +SerilizedBlock::SerilizedBlock(Block* block): + m_size(0), + m_data(nullptr) +{ + m_size += sizeof(BaseBlockData); + auto name_len = strlen(block->getName()) + 1; + m_size += name_len; + + m_data = new char[m_size]; + memcpy(&m_data[0], block, sizeof(BaseBlockData)); + strncpy(&m_data[sizeof(BaseBlockData)], block->getName(), name_len); + +} + +SerilizedBlock::~SerilizedBlock() +{ + if (m_data){ + delete[] m_data; + m_data = nullptr; + } +} + ProfileManager::ProfileManager() { } +ProfileManager::~ProfileManager() +{ + for (auto* b : m_blocks){ + delete b; + } +} + ProfileManager& ProfileManager::instance() { ///C++11 makes possible to create Singleton without any warry about thread-safeness @@ -40,19 +64,18 @@ ProfileManager& ProfileManager::instance() return m_profileManager; } -void ProfileManager::registerMark(Mark* _mark) -{ - if (!m_isEnabled) - return; -} - void ProfileManager::beginBlock(Block* _block) { if (!m_isEnabled) return; - - guard_lock_t lock(m_spin); - m_openedBracketsMap[_block->getThreadId()].push(_block); + if (_block->getType() != BLOCK_TYPE_MARK){ + guard_lock_t lock(m_spin); + m_openedBracketsMap[_block->getThreadId()].push(_block); + } + else{ + _internalInsertBlock(_block); + } + } void ProfileManager::endBlock() @@ -73,6 +96,7 @@ void ProfileManager::endBlock() if (lastBlock && !lastBlock->isFinished()){ lastBlock->finish(); } + _internalInsertBlock(lastBlock); stackOfOpenedBlocks.pop(); } @@ -80,3 +104,9 @@ void ProfileManager::setEnabled(bool isEnable) { m_isEnabled = isEnable; } + +void ProfileManager::_internalInsertBlock(profiler::Block* _block) +{ + guard_lock_t lock(m_storedSpin); + m_blocks.emplace_back(new SerilizedBlock(_block)); +} \ No newline at end of file diff --git a/src/profile_manager.h b/src/profile_manager.h index cdffe57..f109e50 100644 --- a/src/profile_manager.h +++ b/src/profile_manager.h @@ -25,6 +25,20 @@ along with this program.If not, see . #include #include +#include + +class SerilizedBlock +{ + uint16_t m_size; + char* m_data; +public: + + SerilizedBlock(profiler::Block* block); + ~SerilizedBlock(); + + const char* const data() { return m_data; } + uint16_t size() const { return m_size; } +}; class ProfileManager { @@ -41,11 +55,16 @@ class ProfileManager map_of_threads_stacks m_openedBracketsMap; profiler::spin_lock m_spin; + profiler::spin_lock m_storedSpin; typedef profiler::guard_lock guard_lock_t; + + void _internalInsertBlock(profiler::Block* _block); + + typedef std::list serialized_list_t; + serialized_list_t m_blocks; public: static ProfileManager& instance(); - - void registerMark(profiler::Mark* _mark); + ~ProfileManager(); void beginBlock(profiler::Block* _block); void endBlock(); void setEnabled(bool isEnable);