0
0
mirror of https://github.com/yse/easy_profiler.git synced 2024-12-26 08:01:51 +08:00

(profiler_core) Simplifying API: there are ~1.5 times lower macros number for using profiler.

This commit is contained in:
Victor Zarubkin 2016-08-28 23:40:23 +03:00
parent 988d9da391
commit 71f95f2c87
7 changed files with 153 additions and 178 deletions

View File

@ -16,8 +16,8 @@ You should have received a copy of the GNU General Public License
along with this program.If not, see <http://www.gnu.org/licenses/>.
**/
#ifndef ____PROFILER____H_______
#define ____PROFILER____H_______
#ifndef EASY_PROFILER____H_______
#define EASY_PROFILER____H_______
#if defined ( WIN32 )
#define __func__ __FUNCTION__
@ -25,26 +25,34 @@ along with this program.If not, see <http://www.gnu.org/licenses/>.
#ifndef FULL_DISABLE_PROFILER
#define TOKEN_JOIN(x, y) x ## y
#define TOKEN_CONCATENATE(x, y) TOKEN_JOIN(x, y)
#define PROFILER_UNIQUE_BLOCK(x) TOKEN_CONCATENATE(unique_profiler_mark_name_, x)
#define PROFILER_UNIQUE_DESC(x) TOKEN_CONCATENATE(unique_profiler_descriptor_, x)
#include <type_traits>
#define EASY_TOKEN_JOIN(x, y) x ## y
#define EASY_TOKEN_CONCATENATE(x, y) EASY_TOKEN_JOIN(x, y)
#define EASY_UNIQUE_BLOCK(x) EASY_TOKEN_CONCATENATE(unique_profiler_mark_name_, x)
#define EASY_UNIQUE_DESC(x) EASY_TOKEN_CONCATENATE(unique_profiler_descriptor_, x)
/**
\defgroup profiler Profiler
*/
/** Macro used to check compile-time strings.
namespace profiler {
template <bool IS_REF> struct NameSwitch final {
static const char* runtime_name(const char*) { return ""; }
static const char* compiletime_name(const char* name) { return name; }
};
Compiler automatically concatenates "A" "B" into "AB" if both A and B strings
can be identified at compile-time.
template <> struct NameSwitch<true> final {
static const char* runtime_name(const char* name) { return name; }
static const char* compiletime_name(const char*) { return ""; }
};
} // END of namespace profiler.
\ingroup profiler
*/
#define COMPILETIME_TEST "_compiletime_test"
#define EASY_COMPILETIME_NAME(name) ::profiler::NameSwitch<::std::is_reference<decltype(name)>::value>::compiletime_name(name)
#define EASY_RUNTIME_NAME(name) ::profiler::NameSwitch<::std::is_reference<decltype(name)>::value>::runtime_name(name)
/** Macro of beginning of block with custom name and default identification
/** Macro of beginning of block with custom name and color.
\code
#include "profiler/profiler.h"
@ -52,161 +60,126 @@ can be identified at compile-time.
{
// some code ...
if(something){
PROFILER_BEGIN_BLOCK("Calling someThirdPartyLongFunction()");
someThirdPartyLongFunction();
return;
EASY_BLOCK("Calling bar()"); // Block with default color
bar();
}
else{
EASY_BLOCK("Calling baz()", profiler::colors::Red); // Red block
baz();
}
}
\endcode
Block will be automatically completed by destructor
Block will be automatically completed by destructor.
\ingroup profiler
*/
#define PROFILER_BEGIN_BLOCK(compiletime_name)\
static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_BLOCK, ::profiler::DefaultBlockColor);\
::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_BLOCK,\
PROFILER_UNIQUE_DESC(__LINE__).id());\
::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
#define EASY_BLOCK(name, ...)\
static const ::profiler::StaticBlockDescriptor EASY_UNIQUE_DESC(__LINE__)(EASY_COMPILETIME_NAME(name), __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_BLOCK , ## __VA_ARGS__);\
::profiler::Block EASY_UNIQUE_BLOCK(__LINE__)(::profiler::BLOCK_TYPE_BLOCK, EASY_UNIQUE_DESC(__LINE__).id(), EASY_RUNTIME_NAME(name));\
::profiler::beginBlock(EASY_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
#define EASY_BLOCK(compiletime_name)\
static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_BLOCK, ::profiler::DefaultBlockColor);\
::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_BLOCK,\
PROFILER_UNIQUE_DESC(__LINE__).id());\
::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
#define EASY_BLOCK_RUNTIME(runtime_name)\
static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)("", __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_BLOCK, ::profiler::DefaultBlockColor);\
::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(nullptr, ::profiler::BLOCK_TYPE_BLOCK,\
PROFILER_UNIQUE_DESC(__LINE__).id(), runtime_name);\
::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
/** Macro of beginning of block with custom name and custom identification
/** Macro of beginning of block with function name and custom color.
\code
#include "profiler/profiler.h"
void foo()
{
// some code ...
if(something){
PROFILER_BEGIN_BLOCK("Calling someThirdPartyLongFunction()", ::profiler::colors::Red);
someThirdPartyLongFunction();
return;
}
}
\endcode
Block will be automatically completed by destructor
\ingroup profiler
*/
#define PROFILER_BEGIN_BLOCK_GROUPED(compiletime_name, block_group)\
static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_BLOCK, block_group);\
::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_BLOCK,\
PROFILER_UNIQUE_DESC(__LINE__).id());\
::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
/** Macro of beginning of function block with default identification
\code
#include "profiler/profiler.h"
void foo()
{
PROFILER_BEGIN_FUNCTION_BLOCK;
void foo(){
EASY_FUNCTION(); // Block with name="foo" and default color
//some code...
}
void bar(){
EASY_FUNCTION(profiler::colors::Green); // Green block with name="bar"
//some code...
}
\endcode
Name of block automatically created with function name
Name of the block automatically created with function name.
\ingroup profiler
*/
#define PROFILER_BEGIN_FUNCTION_BLOCK PROFILER_BEGIN_BLOCK(__func__)
#define EASY_FUNCTION(...) EASY_BLOCK(__func__ , ## __VA_ARGS__)
/** Macro of beginning of function block with custom identification
\code
#include "profiler/profiler.h"
void foo()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
//some code...
}
\endcode
Name of block automatically created with function name
\ingroup profiler
*/
#define PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(block_color) PROFILER_BEGIN_BLOCK_GROUPED(__func__, block_color)
/** Macro of completion of last nearest open block
/** Macro of completion of last nearest open block.
\code
#include "profiler/profiler.h"
void foo()
int foo()
{
// some code ...
// some code ...
int sum = 0;
PROFILER_BEGIN_BLOCK("Calculating summ");
for(int i = 0; i < 10; i++){
EASY_BLOCK("Calculating sum");
for (int i = 0; i < 10; ++i){
sum += i;
}
PROFILER_END_BLOCK;
EASY_END_BLOCK;
// some antoher code here ...
return sum;
}
\endcode
\ingroup profiler
*/
#define PROFILER_END_BLOCK ::profiler::endBlock();
#define EASY_END_BLOCK ::profiler::endBlock();
#define PROFILER_ADD_EVENT(compiletime_name) \
static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__, ::profiler::BLOCK_TYPE_EVENT);\
::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_EVENT,\
PROFILER_UNIQUE_DESC(__LINE__).id());\
::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
/** Macro of creating event with custom name and color.
#define PROFILER_ADD_EVENT_GROUPED(compiletime_name, block_group)\
static const ::profiler::StaticBlockDescriptor PROFILER_UNIQUE_DESC(__LINE__)(compiletime_name, __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_EVENT, block_group);\
::profiler::Block PROFILER_UNIQUE_BLOCK(__LINE__)(compiletime_name COMPILETIME_TEST, ::profiler::BLOCK_TYPE_EVENT,\
PROFILER_UNIQUE_DESC(__LINE__).id());\
::profiler::beginBlock(PROFILER_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
Event is a block with zero duration and special type.
\warning Event ends immidiately and calling EASY_END_BLOCK after EASY_EVENT
will end previously opened EASY_BLOCK or EASY_FUNCTION.
\ingroup profiler
*/
#define EASY_EVENT(name, ...)\
static const ::profiler::StaticBlockDescriptor EASY_UNIQUE_DESC(__LINE__)(EASY_COMPILETIME_NAME(name), __FILE__, __LINE__,\
::profiler::BLOCK_TYPE_EVENT , ## __VA_ARGS__);\
::profiler::Block EASY_UNIQUE_BLOCK(__LINE__)(::profiler::BLOCK_TYPE_EVENT, EASY_UNIQUE_DESC(__LINE__).id(), EASY_RUNTIME_NAME(name));\
::profiler::beginBlock(EASY_UNIQUE_BLOCK(__LINE__)); // this is to avoid compiler warning about unused variable
/** Macro enabling profiler
\ingroup profiler
*/
#define PROFILER_ENABLE ::profiler::setEnabled(true);
#define EASY_PROFILER_ENABLE ::profiler::setEnabled(true);
/** Macro disabling profiler
\ingroup profiler
*/
#define PROFILER_DISABLE ::profiler::setEnabled(false);
#define EASY_PROFILER_DISABLE ::profiler::setEnabled(false);
/** Macro of naming current thread.
If this thread has been already named then nothing changes.
\ingroup profiler
*/
#ifdef WIN32
#define PROFILER_SET_THREAD_NAME(name) ::profiler::setThreadName(name);
#define EASY_THREAD(name) ::profiler::setThreadName(name, __FILE__, __func__, __LINE__);
#else
#define PROFILER_SET_THREAD_NAME(name) thread_local static const ::profiler::ThreadNameSetter TOKEN_CONCATENATE(unique_profiler_thread_name_setter_, __LINE__)(name);
#define EASY_THREAD(name) thread_local static const ::profiler::ThreadNameSetter EASY_TOKEN_CONCATENATE(unique_profiler_thread_name_setter_, __LINE__)(name, __FILE__, __func__, __LINE__);
#endif
#define PROFILER_SET_MAIN_THREAD PROFILER_SET_THREAD_NAME("Main")
/** Macro of naming main thread.
This is only for user comfort. There is no difference for EasyProfiler GUI between different threads.
\ingroup profiler
*/
#define EASY_MAIN_THREAD EASY_THREAD("Main")
#else
#define PROFILER_BEGIN_BLOCK(name)
#define PROFILER_BEGIN_BLOCK_GROUPED(name, block_group)
#define PROFILER_BEGIN_FUNCTION_BLOCK
#define PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(block_group)
#define PROFILER_END_BLOCK
#define PROFILER_ENABLE
#define PROFILER_DISABLE
#define PROFILER_ADD_EVENT(name)
#define PROFILER_ADD_EVENT_GROUPED(name, block_group)
#define PROFILER_SET_THREAD_NAME(name)
#define PROFILER_SET_MAIN_THREAD
#define EASY_BLOCK(...)
#define EASY_FUNCTION(...)
#define EASY_END_BLOCK
#define EASY_PROFILER_ENABLE
#define EASY_PROFILER_DISABLE
#define EASY_EVENT(...)
#define EASY_THREAD(...)
#define EASY_MAIN_THREAD
#endif
#include <stdint.h>
@ -236,7 +209,7 @@ namespace profiler {
void PROFILER_API endBlock();
void PROFILER_API setEnabled(bool isEnable);
unsigned int PROFILER_API dumpBlocksToFile(const char* filename);
void PROFILER_API setThreadName(const char* name);
void PROFILER_API setThreadName(const char* name, const char* filename, const char* _funcname, int line);
}
typedef uint64_t timestamp_t;
@ -320,7 +293,7 @@ namespace profiler {
public:
Block(const char*, block_type_t _block_type, block_id_t _id, const char* _name = "");
Block(block_type_t _block_type, block_id_t _id, const char* _name = "");
~Block();
inline const char* name() const { return m_name; }
@ -334,16 +307,16 @@ namespace profiler {
public:
StaticBlockDescriptor(const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color = colors::Random);
StaticBlockDescriptor(const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color = DefaultBlockColor);
block_id_t id() const { return m_id; }
};
#ifndef WIN32
struct PROFILER_API ThreadNameSetter final
{
ThreadNameSetter(const char* _name)
ThreadNameSetter(const char* _name, const char* _filename, const char* _funcname, int _line)
{
setThreadName(_name);
setThreadName(_name, _filename, _funcname, _line);
}
};
#endif
@ -352,4 +325,4 @@ namespace profiler {
} // END of namespace profiler.
#endif
#endif // EASY_PROFILER____H_______

View File

@ -99,7 +99,7 @@ int main(int argc, char* argv[])
if (dump_filename.size() > 2)
{
PROFILER_ENABLE
EASY_PROFILER_ENABLE;
std::cout << "Will dump reader prof file to " << dump_filename << std::endl;
}
else

View File

@ -26,13 +26,13 @@ void localSleep(int magic=200000)
}
void loadingResources(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Darkcyan);
EASY_FUNCTION(profiler::colors::Darkcyan);
localSleep();
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
}
void prepareMath(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue);
EASY_FUNCTION(profiler::colors::Blue);
int* intarray = new int[OBJECTS];
for (int i = 0; i < OBJECTS; ++i)
intarray[i] = i * i;
@ -41,7 +41,7 @@ void prepareMath(){
}
void calcIntersect(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue);
EASY_FUNCTION(profiler::colors::Blue);
//int* intarray = new int[OBJECTS * OBJECTS];
int* intarray = new int[OBJECTS];
for (int i = 0; i < OBJECTS; ++i)
@ -56,12 +56,12 @@ void calcIntersect(){
double multModel(double i)
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue);
EASY_FUNCTION(profiler::colors::Blue);
return i * sin(i) * cos(i);
}
void calcPhys(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue);
EASY_FUNCTION(profiler::colors::Blue);
double* intarray = new double[OBJECTS];
for (int i = 0; i < OBJECTS; ++i)
intarray[i] = multModel(double(i)) + double(i / 3) - double((OBJECTS - i) / 2);
@ -71,12 +71,12 @@ void calcPhys(){
double calcSubbrain(int i)
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue);
EASY_FUNCTION(profiler::colors::Blue);
return i * i * i - i / 10 + (OBJECTS - i) * 7 ;
}
void calcBrain(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Blue);
EASY_FUNCTION(profiler::colors::Blue);
double* intarray = new double[OBJECTS];
for (int i = 0; i < OBJECTS; ++i)
intarray[i] = calcSubbrain(i) + double(i * 180 / 3);
@ -85,19 +85,19 @@ void calcBrain(){
}
void calculateBehavior(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Darkblue);
EASY_FUNCTION(profiler::colors::Darkblue);
calcPhys();
calcBrain();
}
void modellingStep(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Navy);
EASY_FUNCTION(profiler::colors::Navy);
prepareMath();
calculateBehavior();
}
void prepareRender(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Darkred);
EASY_FUNCTION(profiler::colors::Darkred);
localSleep();
//std::this_thread::sleep_for(std::chrono::milliseconds(8));
@ -105,18 +105,18 @@ void prepareRender(){
int multPhys(int i)
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
return i * i * i * i / 100;
}
int calcPhysicForObject(int i)
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
return multPhys(i) + i / 3 - (OBJECTS - i) * 15;
}
void calculatePhysics(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
unsigned int* intarray = new unsigned int[OBJECTS];
for (int i = 0; i < OBJECTS; ++i)
intarray[i] = calcPhysicForObject(i);
@ -125,7 +125,7 @@ void calculatePhysics(){
}
void frame(){
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Magenta);
EASY_FUNCTION(profiler::colors::Magenta);
prepareRender();
calculatePhysics();
}
@ -133,10 +133,10 @@ void frame(){
void loadingResourcesThread(){
//std::unique_lock<std::mutex> lk(cv_m);
//cv.wait(lk, []{return g_i == 1; });
PROFILER_SET_THREAD_NAME("Resource loading")
EASY_THREAD("Resource loading");
for(int i = 0; i < RESOURCE_LOADING_COUNT; i++){
loadingResources();
PROFILER_ADD_EVENT_GROUPED("Resources Loading!",profiler::colors::Cyan);
EASY_EVENT("Resources Loading!", profiler::colors::Cyan);
localSleep(1200000);
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
@ -145,8 +145,8 @@ void loadingResourcesThread(){
void modellingThread(){
//std::unique_lock<std::mutex> lk(cv_m);
//cv.wait(lk, []{return g_i == 1; });
PROFILER_SET_THREAD_NAME("Modelling")
for (int i = 0; i < RENDER_SPEPS; i++){
EASY_THREAD("Modelling");
for (int i = 0; i < RENDER_SPEPS; i++){
modellingStep();
localSleep(1200000);
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
@ -156,7 +156,7 @@ void modellingThread(){
void renderThread(){
//std::unique_lock<std::mutex> lk(cv_m);
//cv.wait(lk, []{return g_i == 1; });
PROFILER_SET_THREAD_NAME("Render")
EASY_THREAD("Render");
for (int i = 0; i < MODELLING_STEPS; i++){
frame();
localSleep(1200000);
@ -166,24 +166,24 @@ void renderThread(){
void four()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
std::this_thread::sleep_for(std::chrono::milliseconds(37));
}
void five()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
std::this_thread::sleep_for(std::chrono::milliseconds(20));
}
void six()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
std::this_thread::sleep_for(std::chrono::milliseconds(42));
}
void three()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
four();
five();
six();
@ -191,19 +191,19 @@ void three()
void seven()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
std::this_thread::sleep_for(std::chrono::milliseconds(147));
}
void two()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
std::this_thread::sleep_for(std::chrono::milliseconds(26));
}
void one()
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(profiler::colors::Red);
EASY_FUNCTION(profiler::colors::Red);
two();
three();
seven();
@ -240,8 +240,8 @@ int main(int argc, char* argv[])
std::cout << "Resource loading count: " << RESOURCE_LOADING_COUNT << std::endl;
auto start = std::chrono::system_clock::now();
PROFILER_ENABLE;
PROFILER_SET_MAIN_THREAD;
EASY_PROFILER_ENABLE;
EASY_MAIN_THREAD;
//one();
//one();
/**/

View File

@ -38,7 +38,7 @@ BaseBlockData::BaseBlockData(timestamp_t _begin_time, block_id_t _descriptor_id)
}
Block::Block(const char*, block_type_t _block_type, block_id_t _descriptor_id, const char* _name)
Block::Block(block_type_t _block_type, block_id_t _descriptor_id, const char* _name)
: BaseBlockData(getCurrentTime(), _descriptor_id)
, m_name(_name)
{

View File

@ -31,9 +31,9 @@ extern "C"{
return MANAGER.dumpBlocksToFile(filename);
}
void PROFILER_API setThreadName(const char* name)
void PROFILER_API setThreadName(const char* name, const char* filename, const char* _funcname, int line)
{
return MANAGER.setThreadName(name);
return MANAGER.setThreadName(name, filename, _funcname, line);
}
}
@ -66,7 +66,7 @@ BlockDescriptor::BlockDescriptor(uint64_t& _used_mem, const char* _name, const c
, m_name(_name)
, m_filename(_filename)
{
_used_mem += sizeof(profiler::BaseBlockDescriptor) + strlen(_name) + strlen(_filename) + 2;
_used_mem += sizeof(profiler::SerializedBlockDescriptor) + strlen(_name) + strlen(_filename) + 2;
}
//////////////////////////////////////////////////////////////////////////
@ -185,7 +185,7 @@ uint32_t ProfileManager::dumpBlocksToFile(const char* filename)
{
const auto name_size = static_cast<uint16_t>(strlen(descriptor.name()) + 1);
const auto filename_size = static_cast<uint16_t>(strlen(descriptor.file()) + 1);
const auto size = static_cast<uint16_t>(sizeof(profiler::BaseBlockDescriptor) + name_size + filename_size + sizeof(uint16_t));
const auto size = static_cast<uint16_t>(sizeof(profiler::SerializedBlockDescriptor) + name_size + filename_size);
of.write(size);
of.write<profiler::BaseBlockDescriptor>(descriptor);
@ -212,14 +212,14 @@ uint32_t ProfileManager::dumpBlocksToFile(const char* filename)
return blocks_number;
}
void ProfileManager::setThreadName(const char* name)
void ProfileManager::setThreadName(const char* name, const char* filename, const char* _funcname, int line)
{
auto& thread_storage = threadStorage(getCurrentThreadId());
if (thread_storage.named)
return;
const auto id = addBlockDescriptor("ThreadName", __FILE__, __LINE__, profiler::BLOCK_TYPE_THREAD_SIGN, profiler::colors::Random);
thread_storage.store(profiler::Block(nullptr, profiler::BLOCK_TYPE_THREAD_SIGN, id, name));
const auto id = addBlockDescriptor(_funcname, filename, line, profiler::BLOCK_TYPE_THREAD_SIGN, profiler::colors::Random);
thread_storage.store(profiler::Block(profiler::BLOCK_TYPE_THREAD_SIGN, id, name));
thread_storage.named = true;
}

View File

@ -139,7 +139,7 @@ public:
void endBlock();
void setEnabled(bool isEnable);
uint32_t dumpBlocksToFile(const char* filename);
void setThreadName(const char* name);
void setThreadName(const char* name, const char* filename, const char* _funcname, int line);
private:

View File

@ -260,7 +260,7 @@ extern "C" {
unsigned int fillTreesFromFile(::std::atomic<int>& progress, const char* filename, ::profiler::SerializedData& serialized_blocks, ::profiler::SerializedData& serialized_descriptors, ::profiler::descriptors_list_t& descriptors, ::profiler::thread_blocks_tree_t& threaded_trees, bool gather_statistics)
{
PROFILER_BEGIN_FUNCTION_BLOCK_GROUPED(::profiler::colors::Cyan)
EASY_FUNCTION(::profiler::colors::Cyan);
::std::ifstream inFile(filename, ::std::fstream::binary);
progress.store(0);
@ -299,16 +299,19 @@ extern "C" {
serialized_descriptors.set(new char[descriptors_memory_size]);
uint64_t i = 0;
uint32_t read_number = 0;
while (!inFile.eof() && read_number < total_descriptors_number)
while (!inFile.eof() && descriptors.size() < total_descriptors_number)
{
++read_number;
uint16_t sz = 0;
inFile.read((char*)&sz, sizeof(sz));
if (sz == 0)
return 0;
//if (i + sz > descriptors_memory_size)
//{
// printf("FILE CORRUPTED\n");
// return 0;
//}
char* data = serialized_descriptors[i];
inFile.read(data, sz);
auto descriptor = reinterpret_cast<::profiler::SerializedBlockDescriptor*>(data);
@ -321,10 +324,10 @@ extern "C" {
IdMap identification_table;
i = 0;
read_number = 0;
uint32_t read_number = 0;
while (!inFile.eof() && read_number < total_blocks_number)
{
PROFILER_BEGIN_BLOCK_GROUPED("Read thread from file", ::profiler::colors::Darkgreen)
EASY_BLOCK("Read thread data", ::profiler::colors::Darkgreen);
::profiler::thread_id_t thread_id = 0;
inFile.read((char*)&thread_id, sizeof(decltype(thread_id)));
@ -336,7 +339,7 @@ extern "C" {
const auto threshold = read_number + blocks_number_in_thread;
while (!inFile.eof() && read_number < threshold)
{
PROFILER_BEGIN_BLOCK_GROUPED("Read block from file", ::profiler::colors::Green)
EASY_BLOCK("Read block", ::profiler::colors::Green);
++read_number;
@ -389,7 +392,7 @@ extern "C" {
{
//auto lower = ::std::lower_bound(root.children.begin(), root.children.end(), tree);
/**/
PROFILER_BEGIN_BLOCK_GROUPED("Find children", ::profiler::colors::Blue)
EASY_BLOCK("Find children", ::profiler::colors::Blue);
auto rlower1 = ++root.tree.children.rbegin();
for (; rlower1 != root.tree.children.rend(); ++rlower1)
{
@ -402,12 +405,12 @@ extern "C" {
::std::move(lower, root.tree.children.end(), ::std::back_inserter(tree.children));
root.tree.children.erase(lower, root.tree.children.end());
PROFILER_END_BLOCK
EASY_END_BLOCK;
::profiler::timestamp_t children_duration = 0;
if (gather_statistics)
{
PROFILER_BEGIN_BLOCK_GROUPED("Gather statistic within parent", ::profiler::colors::Magenta)
EASY_BLOCK("Gather statistic within parent", ::profiler::colors::Magenta);
per_parent_statistics.clear();
//per_parent_statistics.reserve(tree.children.size()); // this gives slow-down on Windows
@ -443,7 +446,7 @@ extern "C" {
if (gather_statistics)
{
PROFILER_BEGIN_BLOCK_GROUPED("Gather per thread statistics", ::profiler::colors::Coral)
EASY_BLOCK("Gather per thread statistics", ::profiler::colors::Coral);
auto& current = root.tree.children.back();
current.per_thread_stats = update_statistics(per_thread_statistics, current);
}
@ -461,7 +464,7 @@ extern "C" {
return 0;
}
PROFILER_BEGIN_BLOCK_GROUPED("Gather statistics for roots", ::profiler::colors::Purple)
EASY_BLOCK("Gather statistics for roots", ::profiler::colors::Purple);
if (gather_statistics)
{
::std::vector<::std::thread> statistics_threads;
@ -521,7 +524,6 @@ extern "C" {
progress.store(90 + (10 * ++j) / n);
}
}
PROFILER_END_BLOCK
// No need to delete BlockStatistics instances - they will be deleted inside BlocksTree destructors
return blocks_counter;