mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 08:41:02 +08:00
(profiler core) Prepare for source file and line writing
This commit is contained in:
parent
cdd74503eb
commit
3fd0b77d16
@ -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,7 +51,10 @@ 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);\
|
||||
#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,7 +76,10 @@ 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);\
|
||||
#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,10 +136,16 @@ 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);\
|
||||
#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);\
|
||||
#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
|
||||
@ -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:
|
||||
|
||||
#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,7 +362,7 @@ namespace profiler
|
||||
const char* getBlockName() const;
|
||||
};
|
||||
|
||||
struct PROFILER_API ThreadNameSetter
|
||||
struct PROFILER_API ThreadNameSetter final
|
||||
{
|
||||
ThreadNameSetter(const char* _name)
|
||||
{
|
||||
@ -326,6 +370,17 @@ namespace profiler
|
||||
}
|
||||
};
|
||||
|
||||
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.
|
||||
|
||||
#endif
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -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 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user