mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-28 17:28:14 +08:00
Merge branch 'event_tracing' of https://github.com/yse/easy_profiler into event_tracing
This commit is contained in:
commit
68bbd0eef3
@ -2,8 +2,8 @@ project(profiling_tool)
|
|||||||
cmake_minimum_required(VERSION 2.8)
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
set(
|
set(
|
||||||
ROOT
|
ROOT
|
||||||
${CMAKE_CURRENT_LIST_DIR}
|
${CMAKE_CURRENT_LIST_DIR}
|
||||||
)
|
)
|
||||||
|
|
||||||
set(OUTPUT_DIR
|
set(OUTPUT_DIR
|
||||||
@ -23,16 +23,16 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY
|
|||||||
)
|
)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
include
|
include
|
||||||
)
|
)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -Wno-reorder -pedantic -O3" )
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-long-long -Wno-reorder -pedantic -O3" )
|
||||||
else()
|
else()
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-D_CRT_SECURE_NO_WARNINGS
|
-D_CRT_SECURE_NO_WARNINGS
|
||||||
)
|
)
|
||||||
endif(UNIX)
|
endif(UNIX)
|
||||||
|
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
|
@ -26,13 +26,21 @@ along with this program.If not, see <http://www.gnu.org/licenses/>.
|
|||||||
# define EASY_THREAD_LOCAL __declspec(thread)
|
# define EASY_THREAD_LOCAL __declspec(thread)
|
||||||
# endif
|
# endif
|
||||||
#elif defined(__GNUC__)
|
#elif defined(__GNUC__)
|
||||||
|
#ifndef __clang__
|
||||||
# if (__GNUC__ == 4 && __GNUC_MINOR__ < 8) || (__GNUC__ < 4)
|
# if (__GNUC__ == 4 && __GNUC_MINOR__ < 8) || (__GNUC__ < 4)
|
||||||
// There is no support for C++11 thread_local keyword prior to gcc 4.8. Use __thread instead.
|
// There is no support for C++11 thread_local keyword prior to gcc 4.8. Use __thread instead.
|
||||||
# define EASY_THREAD_LOCAL __thread
|
# define EASY_THREAD_LOCAL __thread
|
||||||
|
#endif
|
||||||
# endif
|
# endif
|
||||||
|
#if defined ( __clang__ )
|
||||||
|
# if (__clang_major__ == 3 && __clang_minor__ < 3) || (__clang_major__ < 3)
|
||||||
|
# define EASY_THREAD_LOCAL __thread
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// TODO: Check thread_local support for Clang!
|
#endif
|
||||||
|
|
||||||
|
// TODO: Check thread local support for clanv earlier than 3.3
|
||||||
|
|
||||||
#ifndef EASY_THREAD_LOCAL
|
#ifndef EASY_THREAD_LOCAL
|
||||||
# define EASY_THREAD_LOCAL thread_local
|
# define EASY_THREAD_LOCAL thread_local
|
||||||
@ -76,19 +84,19 @@ namespace profiler {
|
|||||||
/** Macro of beginning of block with custom name and color.
|
/** Macro of beginning of block with custom name and color.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
#include "profiler/profiler.h"
|
#include "profiler/profiler.h"
|
||||||
void foo()
|
void foo()
|
||||||
{
|
{
|
||||||
// some code ...
|
// some code ...
|
||||||
if(something){
|
if(something){
|
||||||
EASY_BLOCK("Calling bar()"); // Block with default color
|
EASY_BLOCK("Calling bar()"); // Block with default color
|
||||||
bar();
|
bar();
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
EASY_BLOCK("Calling baz()", profiler::colors::Red); // Red block
|
EASY_BLOCK("Calling baz()", profiler::colors::Red); // Red block
|
||||||
baz();
|
baz();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
Block will be automatically completed by destructor.
|
Block will be automatically completed by destructor.
|
||||||
@ -104,11 +112,11 @@ Block will be automatically completed by destructor.
|
|||||||
/** Macro of beginning of block with function name and custom color.
|
/** Macro of beginning of block with function name and custom color.
|
||||||
|
|
||||||
\code
|
\code
|
||||||
#include "profiler/profiler.h"
|
#include "profiler/profiler.h"
|
||||||
void foo(){
|
void foo(){
|
||||||
EASY_FUNCTION(); // Block with name="foo" and default color
|
EASY_FUNCTION(); // Block with name="foo" and default color
|
||||||
//some code...
|
//some code...
|
||||||
}
|
}
|
||||||
|
|
||||||
void bar(){
|
void bar(){
|
||||||
EASY_FUNCTION(profiler::colors::Green); // Green block with name="bar"
|
EASY_FUNCTION(profiler::colors::Green); // Green block with name="bar"
|
||||||
@ -134,12 +142,12 @@ int foo()
|
|||||||
{
|
{
|
||||||
// some code ...
|
// some code ...
|
||||||
|
|
||||||
int sum = 0;
|
int sum = 0;
|
||||||
EASY_BLOCK("Calculating sum");
|
EASY_BLOCK("Calculating sum");
|
||||||
for (int i = 0; i < 10; ++i){
|
for (int i = 0; i < 10; ++i){
|
||||||
sum += i;
|
sum += i;
|
||||||
}
|
}
|
||||||
EASY_END_BLOCK;
|
EASY_END_BLOCK;
|
||||||
|
|
||||||
// some antoher code here ...
|
// some antoher code here ...
|
||||||
|
|
||||||
@ -211,10 +219,10 @@ This is only for user comfort. There is no difference for EasyProfiler GUI betwe
|
|||||||
#include "profiler/profiler_colors.h"
|
#include "profiler/profiler_colors.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#ifdef _BUILD_PROFILER
|
#ifdef _BUILD_PROFILER
|
||||||
#define PROFILER_API __declspec(dllexport)
|
#define PROFILER_API __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define PROFILER_API __declspec(dllimport)
|
#define PROFILER_API __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
#else
|
#else
|
||||||
#define PROFILER_API
|
#define PROFILER_API
|
||||||
@ -225,7 +233,7 @@ class ThreadStorage;
|
|||||||
|
|
||||||
namespace profiler {
|
namespace profiler {
|
||||||
|
|
||||||
class Block;
|
class Block;
|
||||||
|
|
||||||
typedef uint64_t timestamp_t;
|
typedef uint64_t timestamp_t;
|
||||||
typedef uint32_t thread_id_t;
|
typedef uint32_t thread_id_t;
|
||||||
@ -241,8 +249,8 @@ namespace profiler {
|
|||||||
BLOCK_TYPES_NUMBER
|
BLOCK_TYPES_NUMBER
|
||||||
};
|
};
|
||||||
typedef BlockType block_type_t;
|
typedef BlockType block_type_t;
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
PROFILER_API block_id_t registerDescription(const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color = DefaultBlockColor);
|
PROFILER_API block_id_t registerDescription(const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color = DefaultBlockColor);
|
||||||
PROFILER_API void beginBlock(Block& _block);
|
PROFILER_API void beginBlock(Block& _block);
|
||||||
PROFILER_API void endBlock();
|
PROFILER_API void endBlock();
|
||||||
@ -251,8 +259,8 @@ namespace profiler {
|
|||||||
PROFILER_API const char* setThreadName(const char* name, const char* filename, const char* _funcname, int line);
|
PROFILER_API const char* setThreadName(const char* name, const char* filename, const char* _funcname, int line);
|
||||||
PROFILER_API void setContextSwitchLogFilename(const char* name);
|
PROFILER_API void setContextSwitchLogFilename(const char* name);
|
||||||
PROFILER_API const char* getContextSwitchLogFilename();
|
PROFILER_API const char* getContextSwitchLogFilename();
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma pack(push,1)
|
#pragma pack(push,1)
|
||||||
class PROFILER_API BaseBlockDescriptor
|
class PROFILER_API BaseBlockDescriptor
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ const QRgb TIMELINE_BACKGROUND = 0x20303030;
|
|||||||
const QRgb SELECTED_ITEM_COLOR = 0x000050a0;
|
const QRgb SELECTED_ITEM_COLOR = 0x000050a0;
|
||||||
const QColor CHRONOMETER_COLOR2 = QColor::fromRgba(0x40408040);
|
const QColor CHRONOMETER_COLOR2 = QColor::fromRgba(0x40408040);
|
||||||
|
|
||||||
const unsigned int TEST_PROGRESSION_BASE = 4;
|
//const unsigned int TEST_PROGRESSION_BASE = 4;
|
||||||
|
|
||||||
const int FLICKER_INTERVAL = 16; // 60Hz
|
const int FLICKER_INTERVAL = 16; // 60Hz
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ public:
|
|||||||
|
|
||||||
void setHover(bool _hover);
|
void setHover(bool _hover);
|
||||||
|
|
||||||
bool contains(const QPointF& _pos) const;
|
bool contains(const QPointF& _pos) const override;
|
||||||
|
|
||||||
inline bool hoverIndicator() const
|
inline bool hoverIndicator() const
|
||||||
{
|
{
|
||||||
|
@ -41,7 +41,7 @@
|
|||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
const qreal SCALING_COEFFICIENT = 1.25;
|
const qreal SCALING_COEFFICIENT = 1.25;
|
||||||
const qreal SCALING_COEFFICIENT_INV = 1.0 / SCALING_COEFFICIENT;
|
//const qreal SCALING_COEFFICIENT_INV = 1.0 / SCALING_COEFFICIENT;
|
||||||
const int DEFAULT_TOP = -40;
|
const int DEFAULT_TOP = -40;
|
||||||
const int DEFAULT_HEIGHT = 80;
|
const int DEFAULT_HEIGHT = 80;
|
||||||
const int INDICATOR_SIZE = 8;
|
const int INDICATOR_SIZE = 8;
|
||||||
@ -490,7 +490,6 @@ void EasyGraphicsScrollbar::mouseMoveEvent(QMouseEvent* _event)
|
|||||||
|
|
||||||
void EasyGraphicsScrollbar::wheelEvent(QWheelEvent* _event)
|
void EasyGraphicsScrollbar::wheelEvent(QWheelEvent* _event)
|
||||||
{
|
{
|
||||||
qreal deltaSign = _event->delta() < 0 ? -1 : 1;
|
|
||||||
auto w = m_slider->halfwidth() * (_event->delta() < 0 ? ::profiler_gui::SCALING_COEFFICIENT : ::profiler_gui::SCALING_COEFFICIENT_INV);
|
auto w = m_slider->halfwidth() * (_event->delta() < 0 ? ::profiler_gui::SCALING_COEFFICIENT : ::profiler_gui::SCALING_COEFFICIENT_INV);
|
||||||
setValue(mapToScene(_event->pos()).x() - m_minimumValue - w);
|
setValue(mapToScene(_event->pos()).x() - m_minimumValue - w);
|
||||||
emit wheeled(w * m_windowScale, _event->delta());
|
emit wheeled(w * m_windowScale, _event->delta());
|
||||||
|
@ -38,17 +38,17 @@ decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; Que
|
|||||||
inline timestamp_t getCurrentTime()
|
inline timestamp_t getCurrentTime()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
//see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx
|
//see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx
|
||||||
LARGE_INTEGER elapsedMicroseconds;
|
LARGE_INTEGER elapsedMicroseconds;
|
||||||
if (!QueryPerformanceCounter(&elapsedMicroseconds))
|
if (!QueryPerformanceCounter(&elapsedMicroseconds))
|
||||||
return 0;
|
return 0;
|
||||||
//elapsedMicroseconds.QuadPart *= 1000000000LL;
|
//elapsedMicroseconds.QuadPart *= 1000000000LL;
|
||||||
//elapsedMicroseconds.QuadPart /= CPU_FREQUENCY;
|
//elapsedMicroseconds.QuadPart /= CPU_FREQUENCY;
|
||||||
return (timestamp_t)elapsedMicroseconds.QuadPart;
|
return (timestamp_t)elapsedMicroseconds.QuadPart;
|
||||||
#else
|
#else
|
||||||
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> time_point;
|
std::chrono::time_point<std::chrono::system_clock, std::chrono::nanoseconds> time_point;
|
||||||
time_point = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now());
|
time_point = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now());
|
||||||
return time_point.time_since_epoch().count();
|
return time_point.time_since_epoch().count();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,19 +68,19 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
|
|
||||||
PROFILER_API void beginBlock(Block& _block)
|
PROFILER_API void beginBlock(Block& _block)
|
||||||
{
|
{
|
||||||
MANAGER.beginBlock(_block);
|
MANAGER.beginBlock(_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILER_API uint32_t dumpBlocksToFile(const char* filename)
|
PROFILER_API uint32_t dumpBlocksToFile(const char* filename)
|
||||||
{
|
{
|
||||||
return MANAGER.dumpBlocksToFile(filename);
|
return MANAGER.dumpBlocksToFile(filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILER_API const char* setThreadName(const char* name, const char* filename, const char* _funcname, int line)
|
PROFILER_API const char* setThreadName(const char* name, const char* filename, const char* _funcname, int line)
|
||||||
{
|
{
|
||||||
return MANAGER.setThreadName(name, filename, _funcname, line);
|
return MANAGER.setThreadName(name, filename, _funcname, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
PROFILER_API void setContextSwitchLogFilename(const char* name)
|
PROFILER_API void setContextSwitchLogFilename(const char* name)
|
||||||
{
|
{
|
||||||
@ -175,7 +175,7 @@ ProfileManager::ProfileManager()
|
|||||||
|
|
||||||
ProfileManager::~ProfileManager()
|
ProfileManager::~ProfileManager()
|
||||||
{
|
{
|
||||||
//dumpBlocksToFile("test.prof");
|
//dumpBlocksToFile("test.prof");
|
||||||
}
|
}
|
||||||
|
|
||||||
ProfileManager& ProfileManager::instance()
|
ProfileManager& ProfileManager::instance()
|
||||||
@ -249,7 +249,7 @@ void ProfileManager::endContextSwitch(profiler::thread_id_t _thread_id, profiler
|
|||||||
|
|
||||||
void ProfileManager::setEnabled(bool isEnable)
|
void ProfileManager::setEnabled(bool isEnable)
|
||||||
{
|
{
|
||||||
m_isEnabled = isEnable;
|
m_isEnabled = isEnable;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -97,55 +97,58 @@ public:
|
|||||||
|
|
||||||
const uint16_t SIZEOF_CSWITCH = sizeof(profiler::BaseBlockData) + 1;
|
const uint16_t SIZEOF_CSWITCH = sizeof(profiler::BaseBlockData) + 1;
|
||||||
|
|
||||||
class ThreadStorage final
|
typedef std::vector<profiler::SerializedBlock*> serialized_list_t;
|
||||||
|
|
||||||
|
template <class T, const uint16_t N>
|
||||||
|
struct BlocksList final
|
||||||
{
|
{
|
||||||
typedef std::vector<profiler::SerializedBlock*> serialized_list_t;
|
BlocksList() = default;
|
||||||
|
|
||||||
template <class T, const uint16_t N>
|
class Stack final {
|
||||||
struct BlocksList final
|
//std::stack<T> m_stack;
|
||||||
{
|
std::vector<T> m_stack;
|
||||||
class Stack final {
|
|
||||||
//std::stack<T> m_stack;
|
|
||||||
std::vector<T> m_stack;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
inline void clear() { m_stack.clear(); }
|
inline void clear() { m_stack.clear(); }
|
||||||
inline bool empty() const { return m_stack.empty(); }
|
inline bool empty() const { return m_stack.empty(); }
|
||||||
|
|
||||||
inline void emplace(profiler::Block& _block) {
|
inline void emplace(profiler::Block& _block) {
|
||||||
//m_stack.emplace(_block);
|
//m_stack.emplace(_block);
|
||||||
m_stack.emplace_back(_block);
|
m_stack.emplace_back(_block);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class ... TArgs> inline void emplace(TArgs ... _args) {
|
template <class ... TArgs> inline void emplace(TArgs ... _args) {
|
||||||
//m_stack.emplace(_args);
|
//m_stack.emplace(_args);
|
||||||
m_stack.emplace_back(_args...);
|
m_stack.emplace_back(_args...);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline T& top() {
|
inline T& top() {
|
||||||
//return m_stack.top();
|
//return m_stack.top();
|
||||||
return m_stack.back();
|
return m_stack.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void pop() {
|
inline void pop() {
|
||||||
//m_stack.pop();
|
//m_stack.pop();
|
||||||
m_stack.pop_back();
|
m_stack.pop_back();
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
chunk_allocator<char, N> alloc;
|
|
||||||
Stack openedList;
|
|
||||||
serialized_list_t closedList;
|
|
||||||
uint64_t usedMemorySize = 0;
|
|
||||||
|
|
||||||
void clearClosed() {
|
|
||||||
serialized_list_t().swap(closedList);
|
|
||||||
alloc.clear();
|
|
||||||
usedMemorySize = 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
chunk_allocator<char, N> alloc;
|
||||||
|
Stack openedList;
|
||||||
|
serialized_list_t closedList;
|
||||||
|
uint64_t usedMemorySize = 0;
|
||||||
|
|
||||||
|
void clearClosed() {
|
||||||
|
serialized_list_t().swap(closedList);
|
||||||
|
alloc.clear();
|
||||||
|
usedMemorySize = 0;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class ThreadStorage final
|
||||||
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
BlocksList<std::reference_wrapper<profiler::Block>, SIZEOF_CSWITCH * (uint16_t)1024U> blocks;
|
BlocksList<std::reference_wrapper<profiler::Block>, SIZEOF_CSWITCH * (uint16_t)1024U> blocks;
|
||||||
@ -156,6 +159,8 @@ public:
|
|||||||
void storeBlock(const profiler::Block& _block);
|
void storeBlock(const profiler::Block& _block);
|
||||||
void storeCSwitch(const profiler::Block& _block);
|
void storeCSwitch(const profiler::Block& _block);
|
||||||
void clearClosed();
|
void clearClosed();
|
||||||
|
|
||||||
|
ThreadStorage() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -182,7 +187,7 @@ class ProfileManager final
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
static ProfileManager& instance();
|
static ProfileManager& instance();
|
||||||
~ProfileManager();
|
~ProfileManager();
|
||||||
|
|
||||||
template <class ... TArgs>
|
template <class ... TArgs>
|
||||||
uint32_t addBlockDescriptor(TArgs ... _args)
|
uint32_t addBlockDescriptor(TArgs ... _args)
|
||||||
@ -194,8 +199,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void beginBlock(profiler::Block& _block);
|
void beginBlock(profiler::Block& _block);
|
||||||
void endBlock();
|
void endBlock();
|
||||||
void setEnabled(bool isEnable);
|
void setEnabled(bool isEnable);
|
||||||
uint32_t dumpBlocksToFile(const char* filename);
|
uint32_t dumpBlocksToFile(const char* filename);
|
||||||
const char* setThreadName(const char* name, const char* filename, const char* _funcname, int line);
|
const char* setThreadName(const char* name, const char* filename, const char* _funcname, int line);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user