0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-30 02:16:55 +08:00
easy_profiler/src/profile_manager.cpp

183 lines
3.7 KiB
C++
Raw Normal View History

2016-02-16 23:21:12 +03:00
#include "profile_manager.h"
2016-02-18 19:27:17 +03:00
#include <thread>
2016-02-20 19:21:14 +03:00
#include <string.h>
2016-02-24 00:08:13 +03:00
#include <fstream>
2016-02-16 23:21:12 +03:00
using namespace profiler;
extern "C"{
void PROFILER_API endBlock()
{
ProfileManager::instance().endBlock();
}
2016-02-18 00:45:13 +03:00
void PROFILER_API setEnabled(bool isEnable)
{
ProfileManager::instance().setEnabled(isEnable);
}
2016-02-18 00:45:13 +03:00
void PROFILER_API beginBlock(Block* _block)
{
ProfileManager::instance().beginBlock(_block);
2016-02-18 00:45:13 +03:00
}
2016-07-04 22:53:02 +03:00
unsigned int PROFILER_API dumpBlocksToFile(const char* filename)
{
return ProfileManager::instance().dumpBlocksToFile(filename);
}
2016-07-31 22:12:11 +03:00
void PROFILER_API setThreadName(const char* name)
{
return ProfileManager::instance().setThreadName(name);
}
2016-02-16 23:21:12 +03:00
}
SerilizedBlock::SerilizedBlock(Block* block):
m_size(0),
m_data(nullptr)
{
m_size += sizeof(BaseBlockData);
2016-06-22 23:58:07 +03:00
uint16_t name_len = (uint16_t)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);
2016-02-24 06:31:05 +03:00
}
2016-06-25 23:10:05 +03:00
SerilizedBlock::SerilizedBlock(uint16_t _size, char* _data) :
2016-02-24 06:31:05 +03:00
m_size(_size),
2016-06-25 23:10:05 +03:00
m_data(_data)
2016-02-24 06:31:05 +03:00
{
2016-06-25 23:10:05 +03:00
//m_data = new char[m_size];
//memcpy(&m_data[0], _data, m_size);
}
SerilizedBlock::~SerilizedBlock()
{
if (m_data){
delete[] m_data;
m_data = nullptr;
}
}
2016-06-17 16:31:09 +03:00
SerilizedBlock::SerilizedBlock(const SerilizedBlock& other)
{
m_size = other.m_size;
m_data = new char[m_size];
memcpy(&m_data[0], other.m_data, m_size);
}
2016-02-24 06:31:05 +03:00
SerilizedBlock::SerilizedBlock(SerilizedBlock&& that)
{
m_size = that.m_size;
m_data = that.m_data;
that.m_size = 0;
that.m_data = nullptr;
}
2016-06-26 02:12:27 +03:00
const BaseBlockData * SerilizedBlock::block() const
2016-02-24 06:31:05 +03:00
{
2016-06-26 02:12:27 +03:00
return (const BaseBlockData*)m_data;
2016-02-24 06:31:05 +03:00
}
2016-06-26 02:12:27 +03:00
const char* SerilizedBlock::getBlockName() const
2016-02-24 06:31:05 +03:00
{
return (const char*)&m_data[sizeof(profiler::BaseBlockData)];
}
2016-02-16 23:21:12 +03:00
ProfileManager::ProfileManager()
{
}
ProfileManager::~ProfileManager()
{
2016-07-04 22:53:02 +03:00
//dumpBlocksToFile("test.prof");
}
ProfileManager& ProfileManager::instance()
2016-02-16 23:21:12 +03:00
{
///C++11 makes possible to create Singleton without any warry about thread-safeness
///http://preshing.com/20130930/double-checked-locking-is-fixed-in-cpp11/
static ProfileManager m_profileManager;
return m_profileManager;
2016-02-16 23:21:12 +03:00
}
2016-02-18 19:27:17 +03:00
void ProfileManager::beginBlock(Block* _block)
2016-02-18 00:45:13 +03:00
{
2016-02-18 19:27:17 +03:00
if (!m_isEnabled)
return;
2016-06-17 16:31:09 +03:00
if (BLOCK_TYPE_BLOCK == _block->getType()){
guard_lock_t lock(m_spin);
m_openedBracketsMap[_block->getThreadId()].push(_block);
}
else{
_internalInsertBlock(_block);
}
2016-02-18 00:45:13 +03:00
}
2016-02-16 23:21:12 +03:00
void ProfileManager::endBlock()
{
2016-02-24 00:08:13 +03:00
2016-02-18 19:27:17 +03:00
if (!m_isEnabled)
return;
2016-06-20 23:21:54 +03:00
uint32_t threadId = getCurrentThreadId();
2016-06-20 23:10:14 +03:00
2016-02-18 19:27:17 +03:00
guard_lock_t lock(m_spin);
auto& stackOfOpenedBlocks = m_openedBracketsMap[threadId];
if (stackOfOpenedBlocks.empty())
return;
Block* lastBlock = stackOfOpenedBlocks.top();
if (lastBlock && !lastBlock->isFinished()){
lastBlock->finish();
}
_internalInsertBlock(lastBlock);
2016-02-18 19:27:17 +03:00
stackOfOpenedBlocks.pop();
2016-02-16 23:21:12 +03:00
}
void ProfileManager::setEnabled(bool isEnable)
{
m_isEnabled = isEnable;
2016-02-16 23:25:12 +03:00
}
void ProfileManager::_internalInsertBlock(profiler::Block* _block)
{
guard_lock_t lock(m_storedSpin);
m_blocks.emplace_back(new SerilizedBlock(_block));
2016-02-20 19:21:14 +03:00
}
2016-07-04 22:53:02 +03:00
unsigned int ProfileManager::dumpBlocksToFile(const char* filename)
{
std::ofstream of(filename, std::fstream::binary);
for (auto* b : m_blocks){
uint16_t sz = b->size();
of.write((const char*)&sz, sizeof(uint16_t));
of.write(b->data(), b->size());
delete b;
}
unsigned int size = (unsigned int)m_blocks.size();
m_blocks.clear();
return size;
}
2016-07-31 22:12:11 +03:00
void ProfileManager::setThreadName(const char* name)
{
profiler::Block block(name, 0, profiler::BLOCK_TYPE_THREAD_SIGN);
auto find_it = m_namedThreades.find(block.getThreadId());
if (find_it != m_namedThreades.end())
return;
_internalInsertBlock(&block);
m_namedThreades.insert(block.getThreadId());
}