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