diff --git a/include/profiler/profiler.h b/include/profiler/profiler.h
index 6450be4..3571a68 100644
--- a/include/profiler/profiler.h
+++ b/include/profiler/profiler.h
@@ -42,7 +42,7 @@ along with this program.If not, see .
{
// some code ...
- EASY_BLOCK("Check something", profiler::DISABLED); // Disabled block (There is possibility to enable this block later via GUI)
+ EASY_BLOCK("Check something", profiler::OFF); // Disabled block (There is possibility to enable this block later via GUI)
if(something){
EASY_BLOCK("Calling bar()"); // Block with default color
bar();
@@ -53,8 +53,13 @@ along with this program.If not, see .
}
EASY_END_BLOCK; // End of "Check something" block (Even if "Check something" is disabled, this EASY_END_BLOCK will not end any other block).
- EASY_BLOCK("Some another block", profiler::colors::Blue, profiler::DISABLED); // Disabled block with Blue color
+ EASY_BLOCK("Some another block", profiler::colors::Blue, profiler::ON_WITHOUT_CHILDREN); // Block with Blue color without
// some another code...
+ EASY_BLOCK("Calculate sum"); // This block will not be profiled because it's parent is ON_WITHOUT_CHILDREN
+ int sum = 0;
+ for (int i = 0; i < 10; ++i)
+ sum += i;
+ EASY_END_BLOCK; // End of "Calculate sum" block
}
\endcode
@@ -83,7 +88,7 @@ Block will be automatically completed by destructor.
}
void baz(){
- EASY_FUNCTION(profiler::DISABLED); // Disabled block with name="baz" and default color (There is possibility to enable this block later via GUI)
+ EASY_FUNCTION(profiler::FORCE_ON); // Force enabled block with name="baz" and default color (This block will be profiled even if it's parent is OFF_RECURSIVE)
// som code...
}
\endcode
@@ -158,8 +163,10 @@ will end previously opened EASY_BLOCK or EASY_FUNCTION.
*/
# define EASY_THREAD(name)\
EASY_THREAD_LOCAL static const char* EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = nullptr;\
+ ::profiler::ThreadGuard EASY_TOKEN_CONCATENATE(unique_profiler_thread_guard, __LINE__);\
if (EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) == nullptr)\
- EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = ::profiler::registerThread(name);
+ EASY_TOKEN_CONCATENATE(unique_profiler_thread_name, __LINE__) = ::profiler::registerThread(name,\
+ EASY_TOKEN_CONCATENATE(unique_profiler_thread_guard, __LINE__));
/** Macro for main thread registration.
@@ -295,7 +302,7 @@ Otherwise, no log messages will be printed.
//////////////////////////////////////////////////////////////////////////
class ProfileManager;
-class ThreadStorage;
+struct ThreadStorage;
namespace profiler {
@@ -323,16 +330,17 @@ namespace profiler {
class PROFILER_API BaseBlockDescriptor
{
friend ::ProfileManager;
+ friend ::ThreadStorage;
protected:
- block_id_t m_id; ///< This descriptor id (We can afford this spending because there are much more blocks than descriptors)
- int m_line; ///< Line number in the source file
- color_t m_color; ///< Color of the block packed into 1-byte structure
- block_type_t m_type; ///< Type of the block (See BlockType)
- bool m_enabled; ///< If false then blocks with such id() will not be stored by profiler during profile session
+ block_id_t m_id; ///< This descriptor id (We can afford this spending because there are much more blocks than descriptors)
+ int m_line; ///< Line number in the source file
+ color_t m_color; ///< Color of the block packed into 1-byte structure
+ block_type_t m_type; ///< Type of the block (See BlockType)
+ EasyBlockStatus m_status; ///< If false then blocks with such id() will not be stored by profiler during profile session
- BaseBlockDescriptor(block_id_t _id, bool _enabled, int _line, block_type_t _block_type, color_t _color);
+ BaseBlockDescriptor(block_id_t _id, EasyBlockStatus _status, int _line, block_type_t _block_type, color_t _color);
public:
@@ -340,7 +348,7 @@ namespace profiler {
inline int line() const { return m_line; }
inline color_t color() const { return m_color; }
inline block_type_t type() const { return m_type; }
- inline bool enabled() const { return m_enabled; }
+ inline EasyBlockStatus status() const { return m_status; }
}; // END of class BaseBlockDescriptor.
@@ -381,17 +389,17 @@ namespace profiler {
{
friend ::ProfileManager;
- const char* m_name; ///< Static name of all blocks of the same type (blocks can have dynamic name) which is, in pair with descriptor id, a unique block identifier
- const char* m_filename; ///< Source file name where this block is declared
- bool* m_pEnable; ///< Pointer to the enable flag in unordered_map
- uint16_t m_size; ///< Used memory size
- bool m_expired; ///< Is this descriptor expired
+ const char* m_name; ///< Static name of all blocks of the same type (blocks can have dynamic name) which is, in pair with descriptor id, a unique block identifier
+ const char* m_filename; ///< Source file name where this block is declared
+ EasyBlockStatus* m_pStatus; ///< Pointer to the enable flag in unordered_map
+ uint16_t m_size; ///< Used memory size
+ bool m_expired; ///< Is this descriptor expired
- BlockDescriptor(bool _enabled, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color);
+ BlockDescriptor(EasyBlockStatus _status, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color);
public:
- BlockDescriptor(block_id_t _id, bool _enabled, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color);
+ BlockDescriptor(block_id_t _id, EasyBlockStatus _status, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color);
inline const char* name() const {
return m_name;
@@ -410,8 +418,8 @@ namespace profiler {
friend ::ProfileManager;
friend ::ThreadStorage;
- const char* m_name;
- bool m_enabled;
+ const char* m_name;
+ EasyBlockStatus m_status;
private:
@@ -420,7 +428,8 @@ namespace profiler {
void finish();
void finish(timestamp_t _time);
inline bool finished() const { return m_end >= m_begin; }
- inline bool enabled() const { return m_enabled; }
+ inline EasyBlockStatus status() const { return m_status; }
+ inline void setStatus(EasyBlockStatus _status) { m_status = _status; }
public:
@@ -459,6 +468,13 @@ namespace profiler {
}; // END of class BlockDescRef.
+ class PROFILER_API ThreadGuard final {
+ friend ::ProfileManager;
+ thread_id_t m_id = 0;
+ public:
+ ~ThreadGuard();
+ };
+
//////////////////////////////////////////////////////////////////////
// Core API
// Note: it is better to use macros defined above than a direct calls to API.
@@ -472,7 +488,7 @@ namespace profiler {
\ingroup profiler
*/
- PROFILER_API const BaseBlockDescriptor* registerDescription(bool _enabled, const char* _autogenUniqueId, const char* _compiletimeName, const char* _filename, int _line, block_type_t _block_type, color_t _color);
+ PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _compiletimeName, const char* _filename, int _line, block_type_t _block_type, color_t _color);
/** Stores event in the blocks list.
@@ -517,7 +533,7 @@ namespace profiler {
\ingroup profiler
*/
- PROFILER_API const char* registerThread(const char* _name);
+ PROFILER_API const char* registerThread(const char* _name, ThreadGuard&);
/** Enable or disable event tracing.
@@ -555,15 +571,11 @@ namespace profiler {
PROFILER_API const char* getContextSwitchLogFilename();
#endif
- PROFILER_API void startListenSignalToCapture();
- PROFILER_API void stopListenSignalToCapture();
+ PROFILER_API void startListenSignalToCapture();
+ PROFILER_API void stopListenSignalToCapture();
}
- inline void setEnabled(::profiler::EasyEnableFlag _isEnable) {
- setEnabled(_isEnable == ::profiler::ENABLED);
- }
-
//////////////////////////////////////////////////////////////////////
} // END of namespace profiler.
diff --git a/include/profiler/profiler_aux.h b/include/profiler/profiler_aux.h
index 18c2d95..be73e77 100644
--- a/include/profiler/profiler_aux.h
+++ b/include/profiler/profiler_aux.h
@@ -80,10 +80,13 @@
namespace profiler {
- enum EasyEnableFlag : uint8_t
- {
- DISABLED = 0,
- ENABLED = 1
+ enum EasyBlockStatus : uint8_t {
+ OFF = 0, ///< The block is OFF
+ ON = 1, ///< The block is ON (but if it's parent block is off recursively then this block will be off too)
+ FORCE_ON = ON | 2, ///< The block is ALWAYS ON (even if it's parent has turned off all children)
+ OFF_RECURSIVE = 4, ///< The block is OFF and all of it's children by call-stack are also OFF.
+ ON_WITHOUT_CHILDREN = ON | OFF_RECURSIVE, ///< The block is ON but all of it's children are OFF.
+ FORCE_ON_WITHOUT_CHILDREN = FORCE_ON | OFF_RECURSIVE, ///< The block is ALWAYS ON but all of it's children are OFF.
};
struct passthrough_hash final {
@@ -126,7 +129,7 @@ namespace profiler {
}
template
- inline color_t extract_color(::profiler::EasyEnableFlag, TArgs...) {
+ inline color_t extract_color(::profiler::EasyBlockStatus, TArgs...) {
return ::profiler::colors::Default;
}
@@ -148,24 +151,24 @@ namespace profiler {
//***********************************************
- inline bool extract_enable_flag() {
- return true;
+ inline EasyBlockStatus extract_enable_flag() {
+ return ::profiler::ON;
}
template
- inline bool extract_enable_flag(T, ::profiler::EasyEnableFlag _flag, TArgs...) {
- return _flag == ::profiler::ENABLED;
+ inline EasyBlockStatus extract_enable_flag(T, ::profiler::EasyBlockStatus _flag, TArgs...) {
+ return _flag;
}
template
- inline bool extract_enable_flag(::profiler::EasyEnableFlag _flag, TArgs...) {
- return _flag == ::profiler::ENABLED;
+ inline EasyBlockStatus extract_enable_flag(::profiler::EasyBlockStatus _flag, TArgs...) {
+ return _flag;
}
template
- inline bool extract_enable_flag(TArgs...) {
- static_assert(sizeof...(TArgs) < 2, "No EasyEnableFlag in arguments list for EASY_BLOCK(name, ...)!");
- return true;
+ inline EasyBlockStatus extract_enable_flag(TArgs...) {
+ static_assert(sizeof...(TArgs) < 2, "No EasyBlockStatus in arguments list for EASY_BLOCK(name, ...)!");
+ return ::profiler::ON;
}
//***********************************************
diff --git a/include/profiler/serialized_block.h b/include/profiler/serialized_block.h
index 9e6f592..4ed0c31 100644
--- a/include/profiler/serialized_block.h
+++ b/include/profiler/serialized_block.h
@@ -21,8 +21,6 @@ along with this program.If not, see .
#include "profiler/profiler.h"
-class ThreadStorage;
-
namespace profiler {
//////////////////////////////////////////////////////////////////////////
@@ -69,9 +67,9 @@ namespace profiler {
return name() + m_nameLength;
}
- inline void setEnabled(bool _enabled)
+ inline void setStatus(EasyBlockStatus _status)
{
- m_enabled = _enabled;
+ m_status = _status;
}
private:
diff --git a/profiler_gui/blocks_tree_widget.cpp b/profiler_gui/blocks_tree_widget.cpp
index 89c9313..4e10a2d 100644
--- a/profiler_gui/blocks_tree_widget.cpp
+++ b/profiler_gui/blocks_tree_widget.cpp
@@ -38,6 +38,7 @@
************************************************************************/
#include
+#include
#include
#include
#include
@@ -442,18 +443,24 @@ void EasyTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
}
}
- auto id = item->block().node->id();
- action = menu.addAction("Block enabled");
- action->setCheckable(true);
- action->setChecked(easyDescriptor(id).enabled());
- action->setData(id);
- connect(action, &QAction::triggered, this, &This::onBlockEnableDisable);
+ const auto& desc = easyDescriptor(item->block().node->id());
+ auto submenu = menu.addMenu("Block status");
- if (action->isChecked()) {
- auto f = action->font();
- f.setBold(true);
- action->setFont(f);
- }
+#define ADD_STATUS_ACTION(NameValue, StatusValue)\
+ action = submenu->addAction(NameValue);\
+ action->setCheckable(true);\
+ action->setChecked(desc.status() == StatusValue);\
+ action->setData(static_cast(StatusValue));\
+ connect(action, &QAction::triggered, this, &This::onBlockStatusChangeClicked)
+
+ ADD_STATUS_ACTION("Off", ::profiler::OFF);
+ ADD_STATUS_ACTION("On", ::profiler::ON);
+ ADD_STATUS_ACTION("Force-On", ::profiler::FORCE_ON);
+ ADD_STATUS_ACTION("Off-recursive", ::profiler::OFF_RECURSIVE);
+ ADD_STATUS_ACTION("On-without-children", ::profiler::ON_WITHOUT_CHILDREN);
+ ADD_STATUS_ACTION("Force-On-without-children", ::profiler::FORCE_ON_WITHOUT_CHILDREN);
+
+#undef ADD_STATUS_ACTION
}
menu.addSeparator();
@@ -579,14 +586,21 @@ void EasyTreeWidget::onExpandAllChildrenClicked(bool)
//////////////////////////////////////////////////////////////////////////
-void EasyTreeWidget::onBlockEnableDisable(bool _checked)
+void EasyTreeWidget::onBlockStatusChangeClicked(bool _checked)
{
+ if (!_checked)
+ return;
+
+ auto item = static_cast(currentItem());
+ if (item == nullptr)
+ return;
+
auto action = qobject_cast(sender());
if (action != nullptr)
{
- auto id = action->data().toUInt();
- easyDescriptor(id).setEnabled(_checked);
- emit EASY_GLOBALS.events.enableStatusChanged(id, _checked);
+ auto& desc = easyDescriptor(item->block().node->id());
+ desc.setStatus(static_cast<::profiler::EasyBlockStatus>(action->data().toUInt()));
+ emit EASY_GLOBALS.events.blockStatusChanged(desc.id(), desc.status());
}
}
diff --git a/profiler_gui/blocks_tree_widget.h b/profiler_gui/blocks_tree_widget.h
index 187a436..15c68db 100644
--- a/profiler_gui/blocks_tree_widget.h
+++ b/profiler_gui/blocks_tree_widget.h
@@ -40,7 +40,6 @@
#define EASY__TREE_WIDGET__H_
#include
-#include
#include
#include "tree_widget_loader.h"
#include "profiler/reader.h"
@@ -108,7 +107,7 @@ private slots:
void onSelectedBlockChange(uint32_t _block_index);
- void onBlockEnableDisable(bool _checked);
+ void onBlockStatusChangeClicked(bool);
void resizeColumnsToContents();
diff --git a/profiler_gui/descriptors_tree_widget.cpp b/profiler_gui/descriptors_tree_widget.cpp
index 26bb513..a123118 100644
--- a/profiler_gui/descriptors_tree_widget.cpp
+++ b/profiler_gui/descriptors_tree_widget.cpp
@@ -31,6 +31,7 @@
#include
#include
+#include
#include
#include
#include
@@ -63,14 +64,92 @@
enum DescColumns
{
DESC_COL_FILE_LINE = 0,
+ DESC_COL_TYPE,
DESC_COL_NAME,
DESC_COL_STATUS,
DESC_COL_COLUMNS_NUMBER
};
-const auto ENABLED_COLOR = ::profiler::colors::LightGreen900;
-const auto DISABLED_COLOR = ::profiler::colors::DarkRed;
+//////////////////////////////////////////////////////////////////////////
+
+::profiler::EasyBlockStatus nextStatus(::profiler::EasyBlockStatus _status)
+{
+ switch (_status)
+ {
+ case ::profiler::OFF:
+ return ::profiler::ON;
+
+ case ::profiler::ON:
+ return ::profiler::FORCE_ON;
+
+ case ::profiler::FORCE_ON:
+ return ::profiler::OFF_RECURSIVE;
+
+ case ::profiler::OFF_RECURSIVE:
+ return ::profiler::ON_WITHOUT_CHILDREN;
+
+ case ::profiler::ON_WITHOUT_CHILDREN:
+ return ::profiler::FORCE_ON_WITHOUT_CHILDREN;
+
+ case ::profiler::FORCE_ON_WITHOUT_CHILDREN:
+ return ::profiler::OFF;
+ }
+
+ return ::profiler::OFF;
+}
+
+const char* statusText(::profiler::EasyBlockStatus _status)
+{
+ switch (_status)
+ {
+ case ::profiler::OFF:
+ return "OFF";
+
+ case ::profiler::ON:
+ return "ON";
+
+ case ::profiler::FORCE_ON:
+ return "FORCE_ON";
+
+ case ::profiler::OFF_RECURSIVE:
+ return "OFF_RECURSIVE";
+
+ case ::profiler::ON_WITHOUT_CHILDREN:
+ return "ON_WITHOUT_CHILDREN";
+
+ case ::profiler::FORCE_ON_WITHOUT_CHILDREN:
+ return "FORCE_ON_WITHOUT_CHILDREN";
+ }
+
+ return "";
+}
+
+::profiler::color_t statusColor(::profiler::EasyBlockStatus _status)
+{
+ switch (_status)
+ {
+ case ::profiler::OFF:
+ return ::profiler::colors::Red900;
+
+ case ::profiler::ON:
+ return ::profiler::colors::LightGreen900;
+
+ case ::profiler::FORCE_ON:
+ return ::profiler::colors::LightGreen900;
+
+ case ::profiler::OFF_RECURSIVE:
+ return ::profiler::colors::Red900;
+
+ case ::profiler::ON_WITHOUT_CHILDREN:
+ return ::profiler::colors::Lime900;
+
+ case ::profiler::FORCE_ON_WITHOUT_CHILDREN:
+ return ::profiler::colors::Lime900;
+ }
+
+ return ::profiler::colors::Black;
+}
//////////////////////////////////////////////////////////////////////////
@@ -117,12 +196,13 @@ EasyDescTreeWidget::EasyDescTreeWidget(QWidget* _parent)
auto header_item = new QTreeWidgetItem();
header_item->setText(DESC_COL_FILE_LINE, "File/Line");
+ header_item->setText(DESC_COL_TYPE, "Type");
header_item->setText(DESC_COL_NAME, "Name");
header_item->setText(DESC_COL_STATUS, "Status");
setHeaderItem(header_item);
connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::selectedBlockChanged, this, &This::onSelectedBlockChange);
- connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::enableStatusChanged, this, &This::onEnableStatusChange);
+ connect(&EASY_GLOBALS.events, &::profiler_gui::EasyGlobalSignals::blockStatusChanged, this, &This::onBlockStatusChange);
connect(this, &Parent::itemExpanded, this, &This::onItemExpand);
connect(this, &Parent::itemDoubleClicked, this, &This::onDoubleClick);
connect(this, &Parent::currentItemChanged, this, &This::onCurrentItemChange);
@@ -155,12 +235,40 @@ void EasyDescTreeWidget::contextMenuEvent(QContextMenuEvent* _event)
auto header_item = headerItem();
for (int i = 0; i < DESC_COL_STATUS; ++i)
{
- action = new QAction(header_item->text(i), nullptr);
+ if (i == DESC_COL_TYPE)
+ continue;
+
+ action = submenu->addAction(header_item->text(i));
+ action->setData(i);
action->setCheckable(true);
if (i == m_searchColumn)
action->setChecked(true);
connect(action, &QAction::triggered, this, &This::onSearchColumnChange);
- submenu->addAction(action);
+ }
+
+ auto item = currentItem();
+ if (item != nullptr && item->parent() != nullptr && currentColumn() >= DESC_COL_TYPE)
+ {
+ const auto& desc = easyDescriptor(static_cast(item)->desc());
+
+ menu.addSeparator();
+ auto submenu = menu.addMenu("Change status");
+
+#define ADD_STATUS_ACTION(NameValue, StatusValue)\
+ action = submenu->addAction(NameValue);\
+ action->setCheckable(true);\
+ action->setChecked(desc.status() == StatusValue);\
+ action->setData(static_cast(StatusValue));\
+ connect(action, &QAction::triggered, this, &This::onBlockStatusChangeClicked)
+
+ ADD_STATUS_ACTION("Off", ::profiler::OFF);
+ ADD_STATUS_ACTION("On", ::profiler::ON);
+ ADD_STATUS_ACTION("Force-On", ::profiler::FORCE_ON);
+ ADD_STATUS_ACTION("Off-recursive", ::profiler::OFF_RECURSIVE);
+ ADD_STATUS_ACTION("On-without-children", ::profiler::ON_WITHOUT_CHILDREN);
+ ADD_STATUS_ACTION("Force-On-without-children", ::profiler::FORCE_ON_WITHOUT_CHILDREN);
+
+#undef ADD_STATUS_ACTION
}
menu.exec(QCursor::pos());
@@ -254,6 +362,8 @@ void EasyDescTreeWidget::build()
{
p.item = new QTreeWidgetItem();
p.item->setText(DESC_COL_FILE_LINE, desc->file());
+ p.item->setText(DESC_COL_TYPE, "F");
+ p.item->setToolTip(DESC_COL_TYPE, "File");
}
auto it = p.children.find(desc->line());
@@ -264,21 +374,20 @@ void EasyDescTreeWidget::build()
item->setData(DESC_COL_FILE_LINE, Qt::UserRole, desc->line());
item->setText(DESC_COL_NAME, desc->name());
- item->setFont(DESC_COL_STATUS, f);
-
- QBrush brush;
- if (desc->enabled())
+ if (desc->type() == ::profiler::BLOCK_TYPE_BLOCK)
{
- item->setText(DESC_COL_STATUS, "ON");
- brush.setColor(QColor::fromRgba(ENABLED_COLOR));
+ item->setText(DESC_COL_TYPE, "B");
+ item->setToolTip(DESC_COL_TYPE, "Block");
}
else
{
- item->setText(DESC_COL_STATUS, "OFF");
- brush.setColor(QColor::fromRgba(DISABLED_COLOR));
+ item->setText(DESC_COL_TYPE, "E");
+ item->setToolTip(DESC_COL_TYPE, "Event");
}
- item->setForeground(DESC_COL_STATUS, brush);
+ item->setFont(DESC_COL_STATUS, f);
+ item->setText(DESC_COL_STATUS, statusText(desc->status()));
+ item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc->status())));
m_items[id] = item;
}
@@ -312,29 +421,17 @@ void EasyDescTreeWidget::onItemExpand(QTreeWidgetItem*)
void EasyDescTreeWidget::onDoubleClick(QTreeWidgetItem* _item, int _column)
{
- if (_column >= DESC_COL_NAME && _item->parent() != nullptr)
+ if (_column >= DESC_COL_TYPE && _item->parent() != nullptr)
{
auto item = static_cast(_item);
auto& desc = easyDescriptor(item->desc());
+ desc.setStatus(nextStatus(desc.status()));
- QBrush brush;
- if (desc.enabled())
- {
- desc.setEnabled(false);
- item->setText(DESC_COL_STATUS, "OFF");
- brush.setColor(QColor::fromRgba(DISABLED_COLOR));
- }
- else
- {
- desc.setEnabled(true);
- item->setText(DESC_COL_STATUS, "ON");
- brush.setColor(QColor::fromRgba(ENABLED_COLOR));
- }
-
- item->setForeground(DESC_COL_STATUS, brush);
+ item->setText(DESC_COL_STATUS, statusText(desc.status()));
+ item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc.status())));
m_bLocked = true;
- emit EASY_GLOBALS.events.enableStatusChanged(item->desc(), desc.enabled());
+ emit EASY_GLOBALS.events.blockStatusChanged(desc.id(), desc.status());
m_bLocked = false;
}
}
@@ -361,7 +458,30 @@ void EasyDescTreeWidget::onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidget
//////////////////////////////////////////////////////////////////////////
-void EasyDescTreeWidget::onEnableStatusChange(::profiler::block_id_t _id, bool _enabled)
+void EasyDescTreeWidget::onBlockStatusChangeClicked(bool _checked)
+{
+ if (!_checked)
+ return;
+
+ auto item = currentItem();
+ if (item == nullptr || item->parent() == nullptr)
+ return;
+
+ auto action = qobject_cast(sender());
+ if (action != nullptr)
+ {
+ auto& desc = easyDescriptor(static_cast(item)->desc());
+ desc.setStatus(static_cast<::profiler::EasyBlockStatus>(action->data().toUInt()));
+ item->setText(DESC_COL_STATUS, statusText(desc.status()));
+ item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc.status())));
+
+ m_bLocked = true;
+ emit EASY_GLOBALS.events.blockStatusChanged(desc.id(), desc.status());
+ m_bLocked = false;
+ }
+}
+
+void EasyDescTreeWidget::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status)
{
if (m_bLocked)
return;
@@ -370,19 +490,9 @@ void EasyDescTreeWidget::onEnableStatusChange(::profiler::block_id_t _id, bool _
if (item == nullptr)
return;
- QBrush brush;
- if (_enabled)
- {
- item->setText(DESC_COL_STATUS, "ON");
- brush.setColor(QColor::fromRgba(ENABLED_COLOR));
- }
- else
- {
- item->setText(DESC_COL_STATUS, "OFF");
- brush.setColor(QColor::fromRgba(DISABLED_COLOR));
- }
-
- item->setForeground(DESC_COL_STATUS, brush);
+ auto& desc = easyDescriptor(item->desc());
+ item->setText(DESC_COL_STATUS, statusText(desc.status()));
+ item->setForeground(DESC_COL_STATUS, QColor::fromRgba(statusColor(desc.status())));
}
//////////////////////////////////////////////////////////////////////////
diff --git a/profiler_gui/descriptors_tree_widget.h b/profiler_gui/descriptors_tree_widget.h
index 9ff1adc..671d8e3 100644
--- a/profiler_gui/descriptors_tree_widget.h
+++ b/profiler_gui/descriptors_tree_widget.h
@@ -107,11 +107,12 @@ public slots:
private slots:
void onSearchColumnChange(bool);
+ void onBlockStatusChangeClicked(bool);
void onCurrentItemChange(QTreeWidgetItem* _item, QTreeWidgetItem* _prev);
void onItemExpand(QTreeWidgetItem* _item);
void onDoubleClick(QTreeWidgetItem* _item, int _column);
void onSelectedBlockChange(uint32_t _block_index);
- void onEnableStatusChange(::profiler::block_id_t _id, bool _enabled);
+ void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status);
void resizeColumnsToContents();
private:
diff --git a/profiler_gui/globals_qobjects.h b/profiler_gui/globals_qobjects.h
index fd4fc72..2629ff6 100644
--- a/profiler_gui/globals_qobjects.h
+++ b/profiler_gui/globals_qobjects.h
@@ -52,7 +52,7 @@ namespace profiler_gui {
void itemsExpandStateChanged();
void drawBordersChanged();
void chronoPositionChanged();
- void enableStatusChanged(::profiler::block_id_t _id, bool _enabled);
+ void blockStatusChanged(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status);
}; // END of class EasyGlobalSignals.
diff --git a/sample/main.cpp b/sample/main.cpp
index 7235d64..0b7848b 100644
--- a/sample/main.cpp
+++ b/sample/main.cpp
@@ -14,8 +14,8 @@ std::mutex cv_m;
int g_i = 0;
int OBJECTS = 500;
-int RENDER_STEPS = 1600;
-int MODELLING_STEPS = 1000;
+int MODELLING_STEPS = 1500;
+int RENDER_STEPS = 1500;
int RESOURCE_LOADING_COUNT = 50;
void localSleep(int magic=200000)
@@ -105,7 +105,7 @@ void prepareRender(){
int multPhys(int i)
{
- EASY_FUNCTION(profiler::colors::Red700, profiler::DISABLED);
+ EASY_FUNCTION(profiler::colors::Red700, profiler::ON);
return i * i * i * i / 100;
}
@@ -146,7 +146,7 @@ void modellingThread(){
//std::unique_lock lk(cv_m);
//cv.wait(lk, []{return g_i == 1; });
EASY_THREAD("Modelling");
- for (int i = 0; i < RENDER_STEPS; i++){
+ for (int i = 0; i < MODELLING_STEPS; i++){
modellingStep();
localSleep(1200000);
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
@@ -157,7 +157,7 @@ void renderThread(){
//std::unique_lock lk(cv_m);
//cv.wait(lk, []{return g_i == 1; });
EASY_THREAD("Render");
- for (int i = 0; i < MODELLING_STEPS; i++){
+ for (int i = 0; i < RENDER_STEPS; i++){
frame();
localSleep(1200000);
//std::this_thread::sleep_for(std::chrono::milliseconds(20));
@@ -172,34 +172,27 @@ int main(int argc, char* argv[])
OBJECTS = std::atoi(argv[1]);
}
if (argc > 2 && argv[2]){
- RENDER_STEPS = std::atoi(argv[2]);
+ MODELLING_STEPS = std::atoi(argv[2]);
}
if (argc > 3 && argv[3]){
- MODELLING_STEPS = std::atoi(argv[3]);
+ RENDER_STEPS = std::atoi(argv[3]);
}
if (argc > 4 && argv[4]){
RESOURCE_LOADING_COUNT = std::atoi(argv[4]);
}
std::cout << "Objects count: " << OBJECTS << std::endl;
- std::cout << "Render steps: " << RENDER_STEPS << std::endl;
- std::cout << "Modelling steps: " << MODELLING_STEPS << std::endl;
+ std::cout << "Render steps: " << MODELLING_STEPS << std::endl;
+ std::cout << "Modelling steps: " << RENDER_STEPS << std::endl;
std::cout << "Resource loading count: " << RESOURCE_LOADING_COUNT << std::endl;
auto start = std::chrono::system_clock::now();
EASY_PROFILER_ENABLE;
EASY_MAIN_THREAD;
profiler::startListenSignalToCapture();
- //one();
- //one();
- /**/
+
std::vector threads;
-
- std::thread render = std::thread(renderThread);
- std::thread modelling = std::thread(modellingThread);
-
-
- for(int i=0; i < 3; i++){
+ for (int i=0; i < 3; i++) {
threads.emplace_back(std::thread(loadingResourcesThread));
threads.emplace_back(std::thread(renderThread));
threads.emplace_back(std::thread(modellingThread));
@@ -210,16 +203,10 @@ int main(int argc, char* argv[])
cv_m.unlock();
cv.notify_all();
- for (int i = 0; i < RENDER_STEPS; ++i) {
- modellingStep();
- localSleep(1200000);
- }
+ modellingThread();
- render.join();
- modelling.join();
for(auto& t : threads)
t.join();
- /**/
auto end = std::chrono::system_clock::now();
auto elapsed =
diff --git a/src/block.cpp b/src/block.cpp
index 4f43f01..741ba8f 100644
--- a/src/block.cpp
+++ b/src/block.cpp
@@ -23,35 +23,11 @@
* : You should have received a copy of the GNU General Public License
* : along with this program.If not, see .
************************************************************************/
-#include "profiler/profiler.h"
+
#include "profile_manager.h"
-#include
-#include
-#include
using namespace profiler;
-#ifdef _WIN32
-decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; })();
-#endif
-
-inline timestamp_t getCurrentTime()
-{
-#ifdef _WIN32
- //see https://msdn.microsoft.com/library/windows/desktop/dn553408(v=vs.85).aspx
- LARGE_INTEGER elapsedMicroseconds;
- if (!QueryPerformanceCounter(&elapsedMicroseconds))
- return 0;
- //elapsedMicroseconds.QuadPart *= 1000000000LL;
- //elapsedMicroseconds.QuadPart /= CPU_FREQUENCY;
- return (timestamp_t)elapsedMicroseconds.QuadPart;
-#else
- std::chrono::time_point time_point;
- time_point = std::chrono::time_point_cast(std::chrono::system_clock::now());
- return time_point.time_since_epoch().count();
-#endif
-}
-
BaseBlockData::BaseBlockData(timestamp_t _begin_time, block_id_t _descriptor_id)
: m_begin(_begin_time)
, m_end(0)
@@ -63,23 +39,25 @@ BaseBlockData::BaseBlockData(timestamp_t _begin_time, block_id_t _descriptor_id)
Block::Block(Block&& that)
: BaseBlockData(that.m_begin, that.m_id)
, m_name(that.m_name)
- , m_enabled(that.m_enabled)
+ , m_status(that.m_status)
{
m_end = that.m_end;
}
Block::Block(const BaseBlockDescriptor& _descriptor, const char* _runtimeName)
- : BaseBlockData(_descriptor.enabled() ? getCurrentTime() : 1ULL, _descriptor.id())
+ : BaseBlockData(1ULL, _descriptor.id())
, m_name(_runtimeName)
- , m_enabled(_descriptor.enabled())
+ , m_status(_descriptor.status())
{
+
}
Block::Block(timestamp_t _begin_time, block_id_t _descriptor_id, const char* _runtimeName)
: BaseBlockData(_begin_time, _descriptor_id)
, m_name(_runtimeName)
- , m_enabled(true)
+ , m_status(::profiler::ON)
{
+
}
void Block::start()
diff --git a/src/event_trace_win.cpp b/src/event_trace_win.cpp
index 9352ae8..9eadf0e 100644
--- a/src/event_trace_win.cpp
+++ b/src/event_trace_win.cpp
@@ -103,7 +103,7 @@ namespace profiler {
if (sizeof(CSwitch) != _traceEvent->UserDataLength)
return;
- EASY_FUNCTION(::profiler::colors::White, ::profiler::DISABLED);
+ EASY_FUNCTION(::profiler::colors::White, ::profiler::OFF);
auto _contextSwitchEvent = reinterpret_cast(_traceEvent->UserData);
const auto time = static_cast<::profiler::timestamp_t>(_traceEvent->EventHeader.TimeStamp.QuadPart);
diff --git a/src/profile_manager.cpp b/src/profile_manager.cpp
index b4a7379..db6c98b 100644
--- a/src/profile_manager.cpp
+++ b/src/profile_manager.cpp
@@ -23,41 +23,38 @@
* : You should have received a copy of the GNU General Public License
* : along with this program.If not, see .
************************************************************************/
+
+#include
+#include
#include "profile_manager.h"
#include "profiler/serialized_block.h"
#include "profiler/easy_net.h"
-
#include "profiler/easy_socket.h"
#include "event_trace_win.h"
-#include
-#include
-#include
-
-#include
-#include "profiler/serialized_block.h"
-#include "profile_manager.h"
-#include "event_trace_win.h"
-
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
using namespace profiler;
-#ifdef _WIN32
-extern decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY;
-#endif
-
-extern timestamp_t getCurrentTime();
+const uint8_t FORCE_ON_FLAG = profiler::FORCE_ON & ~profiler::ON;
//auto& MANAGER = ProfileManager::instance();
#define MANAGER ProfileManager::instance()
+EASY_THREAD_LOCAL static ::ThreadStorage* THREAD_STORAGE = nullptr;
+
+#ifdef _WIN32
+decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return freq.QuadPart; })();
+#endif
+
+//////////////////////////////////////////////////////////////////////////
+
extern "C" {
- PROFILER_API const BaseBlockDescriptor* registerDescription(bool _enabled, const char* _autogenUniqueId, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color)
+ PROFILER_API const BaseBlockDescriptor* registerDescription(EasyBlockStatus _status, const char* _autogenUniqueId, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color)
{
- return MANAGER.addBlockDescriptor(_enabled, _autogenUniqueId, _name, _filename, _line, _block_type, _color);
+ return MANAGER.addBlockDescriptor(_status, _autogenUniqueId, _name, _filename, _line, _block_type, _color);
}
PROFILER_API void endBlock()
@@ -85,9 +82,9 @@ extern "C" {
return MANAGER.dumpBlocksToFile(filename);
}
- PROFILER_API const char* registerThread(const char* name)//, const char* filename, const char* _funcname, int line)
+ PROFILER_API const char* registerThread(const char* name, ThreadGuard& threadGuard)
{
- return MANAGER.registerThread(name);// , filename, _funcname, line);
+ return MANAGER.registerThread(name, threadGuard);
}
PROFILER_API void setEventTracingEnabled(bool _isEnable)
@@ -138,31 +135,31 @@ SerializedBlock::SerializedBlock(const Block& block, uint16_t name_length)
//////////////////////////////////////////////////////////////////////////
-BaseBlockDescriptor::BaseBlockDescriptor(block_id_t _id, bool _enabled, int _line, block_type_t _block_type, color_t _color)
+BaseBlockDescriptor::BaseBlockDescriptor(block_id_t _id, EasyBlockStatus _status, int _line, block_type_t _block_type, color_t _color)
: m_id(_id)
, m_line(_line)
, m_type(_block_type)
, m_color(_color)
- , m_enabled(_enabled)
+ , m_status(_status)
{
}
-BlockDescriptor::BlockDescriptor(block_id_t _id, bool _enabled, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color)
- : BaseBlockDescriptor(_id, _enabled, _line, _block_type, _color)
+BlockDescriptor::BlockDescriptor(block_id_t _id, EasyBlockStatus _status, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color)
+ : BaseBlockDescriptor(_id, _status, _line, _block_type, _color)
, m_name(_name)
, m_filename(_filename)
- , m_pEnable(nullptr)
+ , m_pStatus(nullptr)
, m_size(static_cast(sizeof(profiler::SerializedBlockDescriptor) + strlen(_name) + strlen(_filename) + 2))
, m_expired(false)
{
}
-BlockDescriptor::BlockDescriptor(bool _enabled, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color)
- : BaseBlockDescriptor(0, _enabled, _line, _block_type, _color)
+BlockDescriptor::BlockDescriptor(EasyBlockStatus _status, const char* _name, const char* _filename, int _line, block_type_t _block_type, color_t _color)
+ : BaseBlockDescriptor(0, _status, _line, _block_type, _color)
, m_name(_name)
, m_filename(_filename)
- , m_pEnable(nullptr)
+ , m_pStatus(nullptr)
, m_size(static_cast(sizeof(profiler::SerializedBlockDescriptor) + strlen(_name) + strlen(_filename) + 2))
, m_expired(false)
{
@@ -178,14 +175,14 @@ BlockDescRef::~BlockDescRef()
void ThreadStorage::storeBlock(const profiler::Block& block)
{
#if EASY_MEASURE_STORAGE_EXPAND != 0
- static const auto desc = MANAGER.addBlockDescriptor(EASY_STORAGE_EXPAND_ENABLED, EASY_UNIQUE_LINE_ID, "EasyProfiler.ExpandStorage", __FILE__, __LINE__, profiler::BLOCK_TYPE_BLOCK, profiler::colors::White);
+ static const auto desc = MANAGER.addBlockDescriptor(EASY_STORAGE_EXPAND_ENABLED ? profiler::ON : profiler::OFF, EASY_UNIQUE_LINE_ID, "EasyProfiler.ExpandStorage", __FILE__, __LINE__, profiler::BLOCK_TYPE_BLOCK, profiler::colors::White);
#endif
auto name_length = static_cast(strlen(block.name()));
auto size = static_cast(sizeof(BaseBlockData) + name_length + 1);
#if EASY_MEASURE_STORAGE_EXPAND != 0
- const bool expanded = desc->enabled() && blocks.closedList.need_expand(size);
+ const bool expanded = (desc->m_status & profiler::ON) && blocks.closedList.need_expand(size);
profiler::Block b(0ULL, desc->id(), "");
if (expanded) b.start();
#endif
@@ -228,7 +225,17 @@ void ThreadStorage::clearClosed()
//////////////////////////////////////////////////////////////////////////
-EASY_THREAD_LOCAL static ::ThreadStorage* THREAD_STORAGE = nullptr;
+ThreadGuard::~ThreadGuard()
+{
+ if (m_id != 0 && THREAD_STORAGE != nullptr && THREAD_STORAGE->id == m_id)
+ {
+ //printf("%s Thread expired!\n", THREAD_STORAGE->name.c_str());
+ THREAD_STORAGE->expired.store(true, std::memory_order_release);
+ THREAD_STORAGE = nullptr;
+ }
+}
+
+//////////////////////////////////////////////////////////////////////////
ProfileManager::ProfileManager()
{
@@ -239,16 +246,16 @@ ProfileManager::ProfileManager()
ProfileManager::~ProfileManager()
{
-
- stopListenSignalToCapture();
- if(m_listenThread.joinable()){
- m_listenThread.join();
- }
- for (auto desc : m_descriptors)
- {
- if (desc != nullptr)
- delete desc;
- }
+ stopListenSignalToCapture();
+
+ if (m_listenThread.joinable())
+ m_listenThread.join();
+
+ for (auto desc : m_descriptors)
+ {
+ if (desc != nullptr)
+ delete desc;
+ }
}
ProfileManager& ProfileManager::instance()
@@ -282,15 +289,21 @@ ThreadStorage* ProfileManager::_findThreadStorage(profiler::thread_id_t _thread_
void ProfileManager::storeBlock(const profiler::BaseBlockDescriptor& _desc, const char* _runtimeName)
{
- if (!m_isEnabled.load(std::memory_order_acquire) || !_desc.enabled())
+ if (!m_isEnabled.load(std::memory_order_acquire) || !(_desc.m_status & profiler::ON))
return;
- profiler::Block b(_desc, _runtimeName);
- b.finish(b.begin());
-
if (THREAD_STORAGE == nullptr)
THREAD_STORAGE = &threadStorage(getCurrentThreadId());
+#if EASY_ENABLE_BLOCK_STATUS != 0
+ if (!THREAD_STORAGE->allowChildren)
+ return;
+#endif
+
+ profiler::Block b(_desc, _runtimeName);
+ b.start();
+ b.m_end = b.m_begin;
+
THREAD_STORAGE->storeBlock(b);
}
@@ -302,6 +315,26 @@ void ProfileManager::beginBlock(Block& _block)
if (THREAD_STORAGE == nullptr)
THREAD_STORAGE = &threadStorage(getCurrentThreadId());
+#if EASY_ENABLE_BLOCK_STATUS != 0
+ if (THREAD_STORAGE->allowChildren)
+ {
+#endif
+ if (_block.m_status & profiler::ON)
+ _block.start();
+#if EASY_ENABLE_BLOCK_STATUS != 0
+ THREAD_STORAGE->allowChildren = !(_block.m_status & profiler::OFF_RECURSIVE);
+ }
+ else if (_block.m_status & FORCE_ON_FLAG)
+ {
+ _block.start();
+ _block.m_status = profiler::FORCE_ON_WITHOUT_CHILDREN;
+ }
+ else
+ {
+ _block.m_status = profiler::OFF_RECURSIVE;
+ }
+#endif
+
THREAD_STORAGE->blocks.openedList.emplace(_block);
}
@@ -334,14 +367,22 @@ void ProfileManager::endBlock()
return;
Block& lastBlock = THREAD_STORAGE->blocks.openedList.top();
- if (lastBlock.enabled())
+ if (lastBlock.m_status & profiler::ON)
{
if (!lastBlock.finished())
lastBlock.finish();
THREAD_STORAGE->storeBlock(lastBlock);
}
+ else
+ {
+ lastBlock.m_end = lastBlock.m_begin; // this is to restrict endBlock() call inside ~Block()
+ }
THREAD_STORAGE->blocks.openedList.pop();
+
+#if EASY_ENABLE_BLOCK_STATUS != 0
+ THREAD_STORAGE->allowChildren = THREAD_STORAGE->blocks.openedList.empty() || !(lastBlock.m_status & profiler::OFF_RECURSIVE);
+#endif
}
void ProfileManager::endContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _endtime, bool _lockSpin)
@@ -389,8 +430,7 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream)
if (wasEnabled)
::profiler::setEnabled(false);
- //TODO remove it
- std::this_thread::sleep_for(std::chrono::milliseconds(20));
+
// This is to make sure that no new descriptors or new threads will be
// added until we finish sending data.
guard_lock_t lock1(m_storedSpin);
@@ -398,6 +438,12 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream)
// This is the only place using both spins, so no dead-lock will occur
+ // Wait for some time to be sure that all operations which began before setEnabled(false) will be finished.
+ // This is much better than inserting spin-lock or atomic variable check into each store operation.
+ std::this_thread::sleep_for(std::chrono::milliseconds(20));
+ // TODO: think about better solution because this one is not 100% safe...
+
+
#ifndef _WIN32
if (eventTracingEnabled)
{
@@ -416,15 +462,24 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream)
}
#endif
-
// Calculate used memory total size and total blocks number
uint64_t usedMemorySize = 0;
uint32_t blocks_number = 0;
- for (const auto& thread_storage : m_threads)
+ for (auto it = m_threads.begin(), end = m_threads.end(); it != end;)
{
- const auto& t = thread_storage.second;
+ const auto& t = it->second;
+ const uint32_t num = static_cast(t.blocks.closedList.size()) + static_cast(t.sync.closedList.size());
+
+ if (t.expired.load(std::memory_order_acquire) && num == 0) {
+ // Thread has been finished and contains no profiled information.
+ // Remove it now.
+ m_threads.erase(it++);
+ continue;
+ }
+
usedMemorySize += t.blocks.usedMemorySize + t.sync.usedMemorySize;
- blocks_number += static_cast(t.blocks.closedList.size()) + static_cast(t.sync.closedList.size());
+ blocks_number += num;
+ ++it;
}
// Write CPU frequency to let GUI calculate real time value from CPU clocks
@@ -461,11 +516,11 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream)
}
// Write blocks and context switch events for each thread
- for (auto& thread_storage : m_threads)
+ for (auto it = m_threads.begin(), end = m_threads.end(); it != end;)
{
- auto& t = thread_storage.second;
+ auto& t = it->second;
- _outputStream.write(thread_storage.first);
+ _outputStream.write(it->first);
const auto name_size = static_cast(t.name.size() + 1);
_outputStream.write(name_size);
@@ -482,6 +537,11 @@ uint32_t ProfileManager::dumpBlocksToStream(profiler::OStream& _outputStream)
t.clearClosed();
t.blocks.openedList.clear();
t.sync.openedList.clear();
+
+ if (t.expired.load(std::memory_order_acquire))
+ m_threads.erase(it++); // Remove expired thread after writing all profiled information
+ else
+ ++it;
}
// Remove all expired block descriptors (descriptor may become expired if it's .dll/.so have been unloaded during application execution)
@@ -512,15 +572,22 @@ uint32_t ProfileManager::dumpBlocksToFile(const char* _filename)
return blocksNumber;
}
-const char* ProfileManager::registerThread(const char* name)
+const char* ProfileManager::registerThread(const char* name, ThreadGuard& threadGuard)
{
- if (THREAD_STORAGE == nullptr)
+ const bool isNewThread = THREAD_STORAGE == nullptr;
+ if (isNewThread)
{
- THREAD_STORAGE = &threadStorage(getCurrentThreadId());
+ const auto id = getCurrentThreadId();
+ THREAD_STORAGE = &threadStorage(id);
+ threadGuard.m_id = THREAD_STORAGE->id = id;
}
if (!THREAD_STORAGE->named)
{
+ if (!isNewThread) {
+ threadGuard.m_id = THREAD_STORAGE->id = getCurrentThreadId();
+ }
+
THREAD_STORAGE->named = true;
THREAD_STORAGE->name = name;
}
@@ -528,7 +595,7 @@ const char* ProfileManager::registerThread(const char* name)
return THREAD_STORAGE->name.c_str();
}
-void ProfileManager::setBlockEnabled(profiler::block_id_t _id, const profiler::hashed_stdstring& _key, bool _enabled)
+void ProfileManager::setBlockStatus(block_id_t _id, const hashed_stdstring& _key, EasyBlockStatus _status)
{
guard_lock_t lock(m_storedSpin);
@@ -537,16 +604,16 @@ void ProfileManager::setBlockEnabled(profiler::block_id_t _id, const profiler::h
{
lock.unlock();
- *desc->m_pEnable = _enabled;
- desc->m_enabled = _enabled; // TODO: possible concurrent access, atomic may be needed
+ *desc->m_pStatus = _status;
+ desc->m_status = _status; // TODO: possible concurrent access, atomic may be needed
}
else
{
#ifdef _WIN32
blocks_enable_status_t::key_type key(_key.c_str(), _key.size(), _key.hcode());
- m_blocksEnableStatus[key] = _enabled;
+ m_blocksEnableStatus[key] = _status;
#else
- m_blocksEnableStatus[_key] = _enabled;
+ m_blocksEnableStatus[_key] = _status;
#endif
}
}
@@ -572,6 +639,7 @@ void ProfileManager::stopListenSignalToCapture()
void ProfileManager::startListen()
{
+ EASY_THREAD("EasyProfiler.Listen");
EasySocket socket;
profiler::net::Message replyMessage(profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING);
@@ -583,9 +651,9 @@ void ProfileManager::startListen()
bool hasConnect = false;
socket.listen();
-
socket.accept();
+ EASY_EVENT("ClientConnected", profiler::colors::White, profiler::OFF);
hasConnect = true;
printf("Client Accepted!\n");
@@ -596,7 +664,6 @@ void ProfileManager::startListen()
while (hasConnect && !m_stopListen.load())
{
-
char buffer[256] = {};
bytes = socket.receive(buffer, 255);
@@ -616,7 +683,8 @@ void ProfileManager::startListen()
case profiler::net::MESSAGE_TYPE_REQUEST_START_CAPTURE:
{
printf("RECEIVED MESSAGE_TYPE_REQUEST_START_CAPTURE\n");
- profiler::setEnabled(true);
+ ProfileManager::setEnabled(true);
+ EASY_EVENT("StartCapture", profiler::colors::Green, profiler::OFF);
replyMessage.type = profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING;
bytes = socket.send(&replyMessage, sizeof(replyMessage));
@@ -626,7 +694,8 @@ void ProfileManager::startListen()
case profiler::net::MESSAGE_TYPE_REQUEST_STOP_CAPTURE:
{
printf("RECEIVED MESSAGE_TYPE_REQUEST_STOP_CAPTURE\n");
- profiler::setEnabled(false);
+ EASY_EVENT("StopCapture", profiler::colors::Red, profiler::OFF);
+ ProfileManager::setEnabled(false);
replyMessage.type = profiler::net::MESSAGE_TYPE_REPLY_PREPARE_BLOCKS;
bytes = socket.send(&replyMessage, sizeof(replyMessage));
diff --git a/src/profile_manager.h b/src/profile_manager.h
index 5cc10e4..d58ab83 100644
--- a/src/profile_manager.h
+++ b/src/profile_manager.h
@@ -20,31 +20,26 @@ along with this program.If not, see .
#define EASY_PROFILER____MANAGER____H______
#include "profiler/profiler.h"
-#include "profiler/serialized_block.h"
-
#include "profiler/easy_socket.h"
#include "spin_lock.h"
#include "outstream.h"
#include "hashed_cstr.h"
#include