0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-27 00:31:02 +08:00

(profiler core) Prepare for source file and line writing

This commit is contained in:
Victor Zarubkin 2016-08-11 23:52:33 +03:00
parent cdd74503eb
commit 3fd0b77d16
5 changed files with 125 additions and 31 deletions

View File

@ -1,6 +1,6 @@
/**
Lightweight profiler library for c++
Copyright(C) 2016 Sergey Yagovtsev
Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
@ -51,8 +51,11 @@ Block will be automatically completed by destructor
\ingroup profiler
*/
#define PROFILER_BEGIN_BLOCK(name) profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,profiler::colors::Clay,profiler::BLOCK_TYPE_BLOCK);\
profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__));
#define PROFILER_BEGIN_BLOCK(name)\
static const profiler::BlockSourceInfo TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__)(__FILE__, __LINE__);\
profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,profiler::colors::Clay,profiler::BLOCK_TYPE_BLOCK,\
TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__).id());\
profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__));
/** Macro of beginning of block with custom name and custom identification
@ -73,8 +76,11 @@ 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__));
#define PROFILER_BEGIN_BLOCK_GROUPED(name,block_group)\
static const profiler::BlockSourceInfo TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__)(__FILE__, __LINE__);\
profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group,profiler::BLOCK_TYPE_BLOCK,\
TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__).id());\
profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__));
/** Macro of beginning of function block with default identification
@ -130,11 +136,17 @@ void foo()
*/
#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(name) \
static const profiler::BlockSourceInfo TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__)(__FILE__, __LINE__);\
profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,0,profiler::BLOCK_TYPE_EVENT,\
TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__).id());\
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__));
#define PROFILER_ADD_EVENT_GROUPED(name,block_group)\
static const profiler::BlockSourceInfo TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__)(__FILE__, __LINE__);\
profiler::Block TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__)(name,block_group,profiler::BLOCK_TYPE_EVENT,\
TOKEN_CONCATENATE(unique_profiler_source_name_,__LINE__).id());\
profiler::beginBlock(&TOKEN_CONCATENATE(unique_profiler_mark_name_,__LINE__));
/** Macro enabling profiler
\ingroup profiler
@ -237,6 +249,7 @@ namespace profiler
class Block;
class BlockSourceInfo;
extern "C"{
void PROFILER_API beginBlock(Block* _block);
@ -249,32 +262,50 @@ namespace profiler
typedef uint8_t block_type_t;
typedef uint64_t timestamp_t;
typedef uint32_t thread_id_t;
typedef uint32_t source_id_t;
const block_type_t BLOCK_TYPE_EVENT = 1;
const block_type_t BLOCK_TYPE_BLOCK = 2;
const block_type_t BLOCK_TYPE_THREAD_SIGN = 3;
#define EASY_USE_OLD_FILE_FORMAT
#pragma pack(push,1)
class PROFILER_API BaseBlockData
{
protected:
block_type_t type;
color_t color;
timestamp_t begin;
timestamp_t end;
thread_id_t thread_id;
#ifdef EASY_USE_OLD_FILE_FORMAT
block_type_t type;
color_t color;
timestamp_t begin;
timestamp_t end;
thread_id_t thread_id;
#else
timestamp_t begin;
timestamp_t end;
thread_id_t thread_id;
source_id_t source_id;
block_type_t type;
color_t color;
#endif
void tick(timestamp_t& stamp);
public:
BaseBlockData(color_t _color, block_type_t _type, thread_id_t _thread_id = 0);
BaseBlockData(source_id_t _source_id, color_t _color, block_type_t _type, thread_id_t _thread_id = 0);
inline block_type_t getType() const { return type; }
inline color_t getColor() const { return color; }
inline timestamp_t getBegin() const { return begin; }
inline thread_id_t getThreadId() const { return thread_id; }
#ifdef EASY_USE_OLD_FILE_FORMAT
inline source_id_t getSourceId() const { return -1; }
#else
inline source_id_t getSourceId() const { return source_id; }
#endif
inline timestamp_t getEnd() const { return end; }
inline bool isFinished() const { return end != 0; }
inline bool isCleared() const { return end >= begin; }
@ -288,19 +319,32 @@ namespace profiler
};
#pragma pack(pop)
class PROFILER_API Block : public BaseBlockData
class PROFILER_API Block final : public BaseBlockData
{
const char *name;
public:
Block(const char* _name, color_t _color, block_type_t _type);
Block(const char* _name, thread_id_t _thread_id, color_t _color, block_type_t _type);
Block(const char* _name, color_t _color, block_type_t _type, source_id_t _source_id);
Block(const char* _name, thread_id_t _thread_id, color_t _color, block_type_t _type, source_id_t _source_id);
~Block();
inline const char* getName() const { return name; }
};
class PROFILER_API SerializedBlock
class PROFILER_API SourceBlock final
{
const char* m_filename;
int m_line;
public:
SourceBlock(const char* _filename, int _line);
const char* file() const { return m_filename; }
int line() const { return m_line; }
};
class PROFILER_API SerializedBlock final
{
uint16_t m_size;
char* m_data;
@ -318,13 +362,24 @@ namespace profiler
const char* getBlockName() const;
};
struct PROFILER_API ThreadNameSetter
struct PROFILER_API ThreadNameSetter final
{
ThreadNameSetter(const char* _name)
{
setThreadName(_name);
}
};
class PROFILER_API BlockSourceInfo final
{
unsigned int m_id;
public:
BlockSourceInfo(const char* _filename, int _linenumber);
unsigned int id() const { return m_id; }
};
} // END of namespace profiler.

View File

@ -1,6 +1,6 @@
/**
Lightweight profiler library for c++
Copyright(C) 2016 Sergey Yagovtsev
Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by

View File

@ -13,22 +13,26 @@ struct ProfPerformanceFrequency {
} const WINDOWS_CPU_INFO;
#endif
BaseBlockData::BaseBlockData(color_t _color, block_type_t _type, thread_id_t _thread_id) : type(_type)
, color(_color)
, begin(0)
BaseBlockData::BaseBlockData(source_id_t _source_id, color_t _color, block_type_t _type, thread_id_t _thread_id)
: begin(0)
, end(0)
, thread_id(_thread_id)
#ifndef EASY_USE_OLD_FILE_FORMAT
, source_id(_source_id)
#endif
, type(_type)
, color(_color)
{
}
Block::Block(const char* _name, color_t _color, block_type_t _type)
: Block(_name, getCurrentThreadId(), _color, _type)
Block::Block(const char* _name, color_t _color, block_type_t _type, source_id_t _source_id)
: Block(_name, getCurrentThreadId(), _color, _type, _source_id)
{
}
Block::Block(const char* _name, thread_id_t _thread_id, color_t _color, block_type_t _type)
: BaseBlockData(_color, _type, _thread_id)
Block::Block(const char* _name, thread_id_t _thread_id, color_t _color, block_type_t _type, source_id_t _source_id)
: BaseBlockData(_source_id, _color, _type, _thread_id)
, name(_name)
{
tick(begin);

View File

@ -18,7 +18,7 @@ extern "C"{
{
ProfileManager::instance().setEnabled(isEnable);
}
void PROFILER_API beginBlock(Block* _block)
void PROFILER_API beginBlock(Block* _block)
{
ProfileManager::instance().beginBlock(_block);
}
@ -88,6 +88,20 @@ const char* SerializedBlock::getBlockName() const
return (const char*)&m_data[sizeof(profiler::BaseBlockData)];
}
//////////////////////////////////////////////////////////////////////////
BlockSourceInfo::BlockSourceInfo(const char* _filename, int _linenumber) : m_id(ProfileManager::instance().addSource(_filename, _linenumber))
{
}
SourceBlock::SourceBlock(const char* _filename, int _line) : m_filename(_filename), m_line(_line)
{
}
//////////////////////////////////////////////////////////////////////////
ProfileManager::ProfileManager()
{
@ -183,3 +197,16 @@ void ProfileManager::setThreadName(const char* name)
m_blocks.emplace_back(new SerializedBlock(&block));
m_namedThreades.insert(current_thread_id);
}
//////////////////////////////////////////////////////////////////////////
unsigned int ProfileManager::addSource(const char* _filename, int _line)
{
guard_lock_t lock(m_storedSpin);
const auto id = static_cast<unsigned int>(m_sources.size());
m_sources.emplace_back(_filename, _line);
return id;
}
//////////////////////////////////////////////////////////////////////////

View File

@ -1,6 +1,6 @@
/**
Lightweight profiler library for c++
Copyright(C) 2016 Sergey Yagovtsev
Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
This program is free software : you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
@ -27,6 +27,7 @@ along with this program.If not, see <http://www.gnu.org/licenses/>.
#include <map>
#include <list>
#include <set>
#include <vector>
#ifdef WIN32
#include <Windows.h>
@ -56,6 +57,7 @@ class ProfileManager
typedef std::stack<profiler::Block*> stack_of_blocks_t;
typedef std::map<size_t, stack_of_blocks_t> map_of_threads_stacks;
typedef std::set<size_t> set_of_thread_id;
typedef std::vector<profiler::SourceBlock> sources;
map_of_threads_stacks m_openedBracketsMap;
@ -65,18 +67,24 @@ class ProfileManager
void _internalInsertBlock(profiler::Block* _block);
sources m_sources;
typedef std::list<profiler::SerializedBlock*> serialized_list_t;
serialized_list_t m_blocks;
set_of_thread_id m_namedThreades;
public:
static ProfileManager& instance();
~ProfileManager();
void beginBlock(profiler::Block* _block);
void beginBlock(profiler::Block* _block);
void endBlock();
void setEnabled(bool isEnable);
unsigned int dumpBlocksToFile(const char* filename);
void setThreadName(const char* name);
unsigned int addSource(const char* _filename, int _line);
};
#endif