mirror of
https://github.com/yse/easy_profiler.git
synced 2024-12-27 08:41:02 +08:00
Added menu Settings->Remote to control profiler event tracing and other future options
This commit is contained in:
parent
d099aa28bb
commit
eca7061fd0
@ -13,7 +13,7 @@ const uint32_t EASY_MESSAGE_SIGN = 20160909;
|
|||||||
|
|
||||||
enum MessageType : uint8_t
|
enum MessageType : uint8_t
|
||||||
{
|
{
|
||||||
MESSAGE_TYPE_ZERO,
|
MESSAGE_TYPE_ZERO = 0,
|
||||||
|
|
||||||
MESSAGE_TYPE_REQUEST_START_CAPTURE,
|
MESSAGE_TYPE_REQUEST_START_CAPTURE,
|
||||||
MESSAGE_TYPE_REPLY_START_CAPTURING,
|
MESSAGE_TYPE_REPLY_START_CAPTURING,
|
||||||
@ -29,6 +29,9 @@ enum MessageType : uint8_t
|
|||||||
MESSAGE_TYPE_REPLY_BLOCKS_DESCRIPTION_END,
|
MESSAGE_TYPE_REPLY_BLOCKS_DESCRIPTION_END,
|
||||||
|
|
||||||
MESSAGE_TYPE_EDIT_BLOCK_STATUS,
|
MESSAGE_TYPE_EDIT_BLOCK_STATUS,
|
||||||
|
|
||||||
|
MESSAGE_TYPE_EVENT_TRACING_STATUS,
|
||||||
|
MESSAGE_TYPE_EVENT_TRACING_PRIORITY,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Message
|
struct Message
|
||||||
@ -45,40 +48,44 @@ struct Message
|
|||||||
Message(MessageType _t):type(_t){}
|
Message(MessageType _t):type(_t){}
|
||||||
};
|
};
|
||||||
|
|
||||||
struct DataMessage : public Message
|
struct DataMessage : public Message {
|
||||||
{
|
|
||||||
uint32_t size = 0; // bytes
|
uint32_t size = 0; // bytes
|
||||||
|
DataMessage(MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) : Message(_t) {}
|
||||||
DataMessage(MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) :
|
DataMessage(uint32_t _s, MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) : Message(_t), size(_s) {}
|
||||||
Message(_t)
|
const char* data() const { return reinterpret_cast<const char*>(this) + sizeof(DataMessage); }
|
||||||
{}
|
|
||||||
|
|
||||||
DataMessage(uint32_t _s, MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) :
|
|
||||||
Message(_t)
|
|
||||||
, size(_s)
|
|
||||||
{}
|
|
||||||
|
|
||||||
const char* data() const
|
|
||||||
{
|
|
||||||
return reinterpret_cast<const char*>(this) + sizeof(DataMessage);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct BlockStatusMessage : public Message
|
struct BlockStatusMessage : public Message {
|
||||||
{
|
|
||||||
uint32_t id;
|
uint32_t id;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
|
BlockStatusMessage(uint32_t _id, uint8_t _status) : Message(MESSAGE_TYPE_EDIT_BLOCK_STATUS), id(_id), status(_status) { }
|
||||||
|
private:
|
||||||
|
BlockStatusMessage() = delete;
|
||||||
|
};
|
||||||
|
|
||||||
BlockStatusMessage(uint32_t _id, uint8_t _status)
|
struct EasyProfilerStatus : public Message
|
||||||
: Message(MESSAGE_TYPE_EDIT_BLOCK_STATUS)
|
{
|
||||||
, id(_id)
|
bool isProfilerEnabled;
|
||||||
, status(_status)
|
bool isEventTracingEnabled;
|
||||||
|
bool isLowPriorityEventTracing;
|
||||||
|
|
||||||
|
EasyProfilerStatus(bool _enabled, bool _ETenabled, bool _ETlowp)
|
||||||
|
: Message(MESSAGE_TYPE_ACCEPTED_CONNECTION)
|
||||||
|
, isProfilerEnabled(_enabled)
|
||||||
|
, isEventTracingEnabled(_ETenabled)
|
||||||
|
, isLowPriorityEventTracing(_ETlowp)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
BlockStatusMessage() = delete;
|
EasyProfilerStatus() = delete;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BoolMessage : public Message {
|
||||||
|
bool flag = false;
|
||||||
|
BoolMessage(MessageType _t, bool _flag = false) : Message(_t), flag(_flag) { }
|
||||||
|
BoolMessage() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
@ -442,8 +442,9 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr
|
|||||||
{
|
{
|
||||||
children_duration = setTree(item, t.children, h, y, 0);
|
children_duration = setTree(item, t.children, h, y, 0);
|
||||||
}
|
}
|
||||||
else if (!t.sync.empty())
|
else
|
||||||
{
|
{
|
||||||
|
if (!t.sync.empty())
|
||||||
children_duration = time2position(blocksTree(t.sync.back()).node->end()) - x;
|
children_duration = time2position(blocksTree(t.sync.back()).node->end()) - x;
|
||||||
h = ::profiler_gui::GRAPHICS_ROW_SIZE;
|
h = ::profiler_gui::GRAPHICS_ROW_SIZE;
|
||||||
}
|
}
|
||||||
|
@ -244,6 +244,20 @@ EasyMainWindow::EasyMainWindow() : Parent()
|
|||||||
SET_ICON(action, ":/Stats-off");
|
SET_ICON(action, ":/Stats-off");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
|
submenu = menu->addMenu("&Remote");
|
||||||
|
m_eventTracingEnableAction = submenu->addAction("Event tracing enabled");
|
||||||
|
m_eventTracingEnableAction->setCheckable(true);
|
||||||
|
m_eventTracingEnableAction->setEnabled(false);
|
||||||
|
connect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange);
|
||||||
|
|
||||||
|
m_eventTracingPriorityAction = submenu->addAction("Low priority event tracing");
|
||||||
|
m_eventTracingPriorityAction->setCheckable(true);
|
||||||
|
m_eventTracingPriorityAction->setChecked(EASY_LOW_PRIORITY_EVENT_TRACING);
|
||||||
|
m_eventTracingPriorityAction->setEnabled(false);
|
||||||
|
connect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange);
|
||||||
|
|
||||||
|
menu->addSeparator();
|
||||||
submenu = menu->addMenu("&Encoding");
|
submenu = menu->addMenu("&Encoding");
|
||||||
actionGroup = new QActionGroup(this);
|
actionGroup = new QActionGroup(this);
|
||||||
actionGroup->setExclusive(true);
|
actionGroup->setExclusive(true);
|
||||||
@ -655,6 +669,9 @@ void EasyMainWindow::onListenerDialogClose(int)
|
|||||||
m_captureAction->setEnabled(false);
|
m_captureAction->setEnabled(false);
|
||||||
SET_ICON(m_connectAction, ":/Connection");
|
SET_ICON(m_connectAction, ":/Connection");
|
||||||
|
|
||||||
|
m_eventTracingEnableAction->setEnabled(false);
|
||||||
|
m_eventTracingPriorityAction->setEnabled(false);
|
||||||
|
|
||||||
emit EASY_GLOBALS.events.connectionChanged(false);
|
emit EASY_GLOBALS.events.connectionChanged(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -847,6 +864,20 @@ QString EasyFileReader::getError()
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void EasyMainWindow::onEventTracingPriorityChange(bool _checked)
|
||||||
|
{
|
||||||
|
if (EASY_GLOBALS.connected)
|
||||||
|
m_listener.send(profiler::net::BoolMessage(profiler::net::MESSAGE_TYPE_EVENT_TRACING_PRIORITY, _checked));
|
||||||
|
}
|
||||||
|
|
||||||
|
void EasyMainWindow::onEventTracingEnableChange(bool _checked)
|
||||||
|
{
|
||||||
|
if (EASY_GLOBALS.connected)
|
||||||
|
m_listener.send(profiler::net::BoolMessage(profiler::net::MESSAGE_TYPE_EVENT_TRACING_STATUS, _checked));
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void EasyMainWindow::onConnectClicked(bool)
|
void EasyMainWindow::onConnectClicked(bool)
|
||||||
{
|
{
|
||||||
if(EASY_GLOBALS.connected)
|
if(EASY_GLOBALS.connected)
|
||||||
@ -878,7 +909,9 @@ void EasyMainWindow::onConnectClicked(bool)
|
|||||||
m_lastAddress = parts.join(QChar('.'));
|
m_lastAddress = parts.join(QChar('.'));
|
||||||
m_lastPort = m_portEdit->text().toUShort();
|
m_lastPort = m_portEdit->text().toUShort();
|
||||||
m_ipEdit->setText(m_lastAddress);
|
m_ipEdit->setText(m_lastAddress);
|
||||||
if (!m_listener.connect(m_lastAddress.toStdString().c_str(), m_lastPort))
|
|
||||||
|
profiler::net::EasyProfilerStatus reply(false, false, false);
|
||||||
|
if (!m_listener.connect(m_lastAddress.toStdString().c_str(), m_lastPort, reply))
|
||||||
{
|
{
|
||||||
QMessageBox::warning(this, "Warning", "Cannot connect with application", QMessageBox::Close);
|
QMessageBox::warning(this, "Warning", "Cannot connect with application", QMessageBox::Close);
|
||||||
return;
|
return;
|
||||||
@ -889,6 +922,18 @@ void EasyMainWindow::onConnectClicked(bool)
|
|||||||
m_captureAction->setEnabled(true);
|
m_captureAction->setEnabled(true);
|
||||||
SET_ICON(m_connectAction, ":/Connection-on");
|
SET_ICON(m_connectAction, ":/Connection-on");
|
||||||
|
|
||||||
|
disconnect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange);
|
||||||
|
disconnect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange);
|
||||||
|
|
||||||
|
m_eventTracingEnableAction->setEnabled(true);
|
||||||
|
m_eventTracingPriorityAction->setEnabled(true);
|
||||||
|
|
||||||
|
m_eventTracingEnableAction->setChecked(reply.isEventTracingEnabled);
|
||||||
|
m_eventTracingPriorityAction->setChecked(reply.isLowPriorityEventTracing);
|
||||||
|
|
||||||
|
connect(m_eventTracingEnableAction, &QAction::triggered, this, &This::onEventTracingEnableChange);
|
||||||
|
connect(m_eventTracingPriorityAction, &QAction::triggered, this, &This::onEventTracingPriorityChange);
|
||||||
|
|
||||||
emit EASY_GLOBALS.events.connectionChanged(true);
|
emit EASY_GLOBALS.events.connectionChanged(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -986,6 +1031,9 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
|
|||||||
m_captureAction->setEnabled(false);
|
m_captureAction->setEnabled(false);
|
||||||
SET_ICON(m_connectAction, ":/Connection");
|
SET_ICON(m_connectAction, ":/Connection");
|
||||||
|
|
||||||
|
m_eventTracingEnableAction->setEnabled(false);
|
||||||
|
m_eventTracingPriorityAction->setEnabled(false);
|
||||||
|
|
||||||
emit EASY_GLOBALS.events.connectionChanged(false);
|
emit EASY_GLOBALS.events.connectionChanged(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -995,7 +1043,7 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool)
|
|||||||
void EasyMainWindow::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status)
|
void EasyMainWindow::onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status)
|
||||||
{
|
{
|
||||||
if (EASY_GLOBALS.connected)
|
if (EASY_GLOBALS.connected)
|
||||||
m_listener.sendBlockStatus(_id, _status);
|
m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast<uint8_t>(_status)));
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
@ -1040,7 +1088,7 @@ void EasySocketListener::clearData()
|
|||||||
m_receivedSize = 0;
|
m_receivedSize = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EasySocketListener::connect(const char* _ipaddress, uint16_t _port)
|
bool EasySocketListener::connect(const char* _ipaddress, uint16_t _port, profiler::net::EasyProfilerStatus& _reply)
|
||||||
{
|
{
|
||||||
if (connected())
|
if (connected())
|
||||||
return true;
|
return true;
|
||||||
@ -1050,9 +1098,55 @@ bool EasySocketListener::connect(const char* _ipaddress, uint16_t _port)
|
|||||||
int res = m_easySocket.setAddress(_ipaddress, _port);
|
int res = m_easySocket.setAddress(_ipaddress, _port);
|
||||||
res = m_easySocket.connect();
|
res = m_easySocket.connect();
|
||||||
|
|
||||||
bool isConnected = res == 0;
|
const bool isConnected = res == 0;
|
||||||
m_bConnected.store(isConnected, ::std::memory_order_release);
|
if (isConnected)
|
||||||
|
{
|
||||||
|
static const size_t buffer_size = sizeof(profiler::net::EasyProfilerStatus) << 1;
|
||||||
|
char buffer[buffer_size] = {};
|
||||||
|
int bytes = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
bytes = m_easySocket.receive(buffer, buffer_size);
|
||||||
|
|
||||||
|
if (bytes == -1)
|
||||||
|
{
|
||||||
|
if (m_easySocket.state() == EasySocket::CONNECTION_STATE_DISCONNECTED)
|
||||||
|
return false;
|
||||||
|
bytes = 0;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bytes == 0)
|
||||||
|
{
|
||||||
|
m_bConnected.store(isConnected, ::std::memory_order_release);
|
||||||
|
return isConnected;
|
||||||
|
}
|
||||||
|
|
||||||
|
int seek = bytes;
|
||||||
|
while (seek < sizeof(profiler::net::EasyProfilerStatus))
|
||||||
|
{
|
||||||
|
bytes = m_easySocket.receive(buffer + seek, buffer_size - seek);
|
||||||
|
|
||||||
|
if (bytes == -1)
|
||||||
|
{
|
||||||
|
if (m_easySocket.state() == EasySocket::CONNECTION_STATE_DISCONNECTED)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
seek += bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto message = reinterpret_cast<const ::profiler::net::EasyProfilerStatus*>(buffer);
|
||||||
|
if (message->isEasyNetMessage() && message->type == profiler::net::MESSAGE_TYPE_ACCEPTED_CONNECTION)
|
||||||
|
_reply = *message;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bConnected.store(isConnected, ::std::memory_order_release);
|
||||||
return isConnected;
|
return isConnected;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1092,12 +1186,6 @@ void EasySocketListener::requestBlocksDescription()
|
|||||||
m_regime = LISTENER_IDLE;
|
m_regime = LISTENER_IDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EasySocketListener::sendBlockStatus(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status)
|
|
||||||
{
|
|
||||||
profiler::net::BlockStatusMessage message(_id, static_cast<uint8_t>(_status));
|
|
||||||
m_easySocket.send(&message, sizeof(message));
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void EasySocketListener::listenCapture()
|
void EasySocketListener::listenCapture()
|
||||||
|
@ -55,6 +55,8 @@
|
|||||||
|
|
||||||
class QDockWidget;
|
class QDockWidget;
|
||||||
|
|
||||||
|
namespace profiler { namespace net { struct EasyProfilerStatus; } }
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
class EasyFileReader Q_DECL_FINAL
|
class EasyFileReader Q_DECL_FINAL
|
||||||
@ -126,13 +128,16 @@ public:
|
|||||||
::std::stringstream& data();
|
::std::stringstream& data();
|
||||||
void clearData();
|
void clearData();
|
||||||
|
|
||||||
bool connect(const char* _ipaddress, uint16_t _port);
|
bool connect(const char* _ipaddress, uint16_t _port, ::profiler::net::EasyProfilerStatus& _reply);
|
||||||
|
|
||||||
void startCapture();
|
void startCapture();
|
||||||
void stopCapture();
|
void stopCapture();
|
||||||
void requestBlocksDescription();
|
void requestBlocksDescription();
|
||||||
|
|
||||||
void sendBlockStatus(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status);
|
template <class T>
|
||||||
|
inline void send(const T& _message) {
|
||||||
|
m_easySocket.send(&_message, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
@ -177,6 +182,8 @@ protected:
|
|||||||
|
|
||||||
class QAction* m_captureAction = nullptr;
|
class QAction* m_captureAction = nullptr;
|
||||||
class QAction* m_connectAction = nullptr;
|
class QAction* m_connectAction = nullptr;
|
||||||
|
class QAction* m_eventTracingEnableAction = nullptr;
|
||||||
|
class QAction* m_eventTracingPriorityAction = nullptr;
|
||||||
|
|
||||||
uint16_t m_lastPort = 0;
|
uint16_t m_lastPort = 0;
|
||||||
|
|
||||||
@ -214,6 +221,8 @@ protected slots:
|
|||||||
void onCaptureClicked(bool);
|
void onCaptureClicked(bool);
|
||||||
void onGetBlockDescriptionsClicked(bool);
|
void onGetBlockDescriptionsClicked(bool);
|
||||||
void onConnectClicked(bool);
|
void onConnectClicked(bool);
|
||||||
|
void onEventTracingPriorityChange(bool _checked);
|
||||||
|
void onEventTracingEnableChange(bool _checked);
|
||||||
|
|
||||||
void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status);
|
void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status);
|
||||||
|
|
||||||
|
@ -293,11 +293,11 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
|||||||
item->setTimeMs(COL_BEGIN, startTime - _beginTime);
|
item->setTimeMs(COL_BEGIN, startTime - _beginTime);
|
||||||
item->setTimeMs(COL_END, endTime - _beginTime);
|
item->setTimeMs(COL_END, endTime - _beginTime);
|
||||||
|
|
||||||
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
|
|
||||||
item->setText(COL_PERCENT_PER_PARENT, "");
|
|
||||||
|
|
||||||
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
||||||
item->setText(COL_PERCENT_PER_FRAME, "");
|
|
||||||
|
auto percentage_per_thread = ::profiler_gui::percent(duration, block.root->active_time);
|
||||||
|
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread);
|
||||||
|
item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread));
|
||||||
|
|
||||||
if (gui_block.tree.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also
|
if (gui_block.tree.per_thread_stats != nullptr) // if there is per_thread_stats then there are other stats also
|
||||||
{
|
{
|
||||||
@ -317,7 +317,7 @@ void FillTreeClass<T>::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI
|
|||||||
item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number);
|
item->setData(COL_NCALLS_PER_THREAD, Qt::UserRole, per_thread_stats->calls_number);
|
||||||
item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number));
|
item->setText(COL_NCALLS_PER_THREAD, QString::number(per_thread_stats->calls_number));
|
||||||
|
|
||||||
auto percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, block.root->active_time);
|
percentage_per_thread = ::profiler_gui::percent(per_thread_stats->total_duration, block.root->active_time);
|
||||||
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread);
|
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, percentage_per_thread);
|
||||||
item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));
|
item->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread));
|
||||||
|
|
||||||
@ -488,9 +488,18 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
item->setData(COL_PERCENT_PER_FRAME, Qt::UserRole, 0);
|
||||||
item->setText(COL_PERCENT_PER_FRAME, "");
|
|
||||||
item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, 0);
|
item->setData(COL_PERCENT_SUM_PER_FRAME, Qt::UserRole, 0);
|
||||||
item->setText(COL_PERCENT_SUM_PER_FRAME, "");
|
|
||||||
|
if (_thread)
|
||||||
|
{
|
||||||
|
auto percentage_per_thread = ::profiler_gui::percent(duration, _thread->selfDuration());
|
||||||
|
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread);
|
||||||
|
item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -537,13 +546,20 @@ size_t FillTreeClass<T>::setTreeInternal(T& _safelocker, Items& _items, const ::
|
|||||||
item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number));
|
item->setText(COL_NCALLS_PER_FRAME, QString::number(per_frame_stats->calls_number));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (_frame == nullptr && _thread != nullptr)
|
||||||
|
{
|
||||||
|
auto percentage_per_thread = ::profiler_gui::percent(duration, _thread->selfDuration());
|
||||||
|
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, percentage_per_thread);
|
||||||
|
item->setText(COL_PERCENT_PER_PARENT, QString::number(percentage_per_thread));
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
|
item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0);
|
||||||
item->setText(COL_PERCENT_PER_PARENT, "");
|
}
|
||||||
|
|
||||||
item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, 0);
|
item->setData(COL_PERCENT_SUM_PER_PARENT, Qt::UserRole, 0);
|
||||||
item->setText(COL_PERCENT_SUM_PER_PARENT, "");
|
|
||||||
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);
|
item->setData(COL_PERCENT_SUM_PER_THREAD, Qt::UserRole, 0);
|
||||||
item->setText(COL_PERCENT_SUM_PER_THREAD, "");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto color = easyDescriptor(child.node->id()).color();
|
const auto color = easyDescriptor(child.node->id()).color();
|
||||||
|
@ -236,7 +236,5 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
std::cout << "Blocks count: " << blocks_count << std::endl;
|
std::cout << "Blocks count: " << blocks_count << std::endl;
|
||||||
|
|
||||||
|
|
||||||
profiler::stopListenSignalToCapture();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -222,6 +222,11 @@ namespace profiler {
|
|||||||
disable();
|
disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EasyEventTracer::isLowPriority() const
|
||||||
|
{
|
||||||
|
return m_lowPriority.load(::std::memory_order_acquire);
|
||||||
|
}
|
||||||
|
|
||||||
void EasyEventTracer::setLowPriority(bool _value)
|
void EasyEventTracer::setLowPriority(bool _value)
|
||||||
{
|
{
|
||||||
m_lowPriority.store(_value, ::std::memory_order_release);
|
m_lowPriority.store(_value, ::std::memory_order_release);
|
||||||
|
@ -78,6 +78,8 @@ namespace profiler {
|
|||||||
static EasyEventTracer& instance();
|
static EasyEventTracer& instance();
|
||||||
~EasyEventTracer();
|
~EasyEventTracer();
|
||||||
|
|
||||||
|
bool isLowPriority() const;
|
||||||
|
|
||||||
::profiler::EventTracingEnableStatus enable(bool _force = false);
|
::profiler::EventTracingEnableStatus enable(bool _force = false);
|
||||||
void disable();
|
void disable();
|
||||||
void setLowPriority(bool _value);
|
void setLowPriority(bool _value);
|
||||||
|
@ -52,6 +52,20 @@ decltype(LARGE_INTEGER::QuadPart) CPU_FREQUENCY = ([](){ LARGE_INTEGER freq; Que
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#define EASY_FORCE_EVENT(timestamp, name, ...)\
|
||||||
|
EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), addBlockDescriptor(\
|
||||||
|
::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\
|
||||||
|
__FILE__, __LINE__, ::profiler::BLOCK_TYPE_EVENT, ::profiler::extract_color(__VA_ARGS__)));\
|
||||||
|
storeBlockForce(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name), timestamp);
|
||||||
|
|
||||||
|
#define EASY_FORCE_EVENT2(timestamp, name, ...)\
|
||||||
|
EASY_LOCAL_STATIC_PTR(const ::profiler::BaseBlockDescriptor*, EASY_UNIQUE_DESC(__LINE__), addBlockDescriptor(\
|
||||||
|
::profiler::extract_enable_flag(__VA_ARGS__), EASY_UNIQUE_LINE_ID, EASY_COMPILETIME_NAME(name),\
|
||||||
|
__FILE__, __LINE__, ::profiler::BLOCK_TYPE_EVENT, ::profiler::extract_color(__VA_ARGS__)));\
|
||||||
|
storeBlockForce2(EASY_UNIQUE_DESC(__LINE__), EASY_RUNTIME_NAME(name), timestamp);
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
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)
|
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)
|
||||||
@ -283,9 +297,6 @@ ProfileManager::~ProfileManager()
|
|||||||
{
|
{
|
||||||
stopListenSignalToCapture();
|
stopListenSignalToCapture();
|
||||||
|
|
||||||
if (m_listenThread.joinable())
|
|
||||||
m_listenThread.join();
|
|
||||||
|
|
||||||
for (auto desc : m_descriptors)
|
for (auto desc : m_descriptors)
|
||||||
{
|
{
|
||||||
if (desc != nullptr)
|
if (desc != nullptr)
|
||||||
@ -367,6 +378,46 @@ void ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, cons
|
|||||||
THREAD_STORAGE->storeBlock(b);
|
THREAD_STORAGE->storeBlock(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProfileManager::storeBlockForce(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t& _timestamp)
|
||||||
|
{
|
||||||
|
if (!(_desc->m_status & profiler::ON))
|
||||||
|
return;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
_timestamp = b.m_begin;
|
||||||
|
THREAD_STORAGE->storeBlock(b);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfileManager::storeBlockForce2(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t _timestamp)
|
||||||
|
{
|
||||||
|
if (!(_desc->m_status & profiler::ON))
|
||||||
|
return;
|
||||||
|
|
||||||
|
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.m_end = b.m_begin = _timestamp;
|
||||||
|
|
||||||
|
THREAD_STORAGE->storeBlock(b);
|
||||||
|
}
|
||||||
|
|
||||||
void ProfileManager::beginBlock(Block& _block)
|
void ProfileManager::beginBlock(Block& _block)
|
||||||
{
|
{
|
||||||
if (!m_isEnabled.load(std::memory_order_acquire))
|
if (!m_isEnabled.load(std::memory_order_acquire))
|
||||||
@ -458,7 +509,7 @@ void ProfileManager::endContextSwitch(profiler::thread_id_t _thread_id, profiler
|
|||||||
ts->sync.openedList.pop();
|
ts->sync.openedList.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ProfileManager::setEnabled(bool isEnable)
|
void ProfileManager::setEnabled(bool isEnable, bool _setTime)
|
||||||
{
|
{
|
||||||
auto time = getCurrentTime();
|
auto time = getCurrentTime();
|
||||||
const bool prev = m_isEnabled.exchange(isEnable, std::memory_order_release);
|
const bool prev = m_isEnabled.exchange(isEnable, std::memory_order_release);
|
||||||
@ -467,20 +518,28 @@ void ProfileManager::setEnabled(bool isEnable)
|
|||||||
|
|
||||||
if (isEnable)
|
if (isEnable)
|
||||||
{
|
{
|
||||||
m_beginTime = time;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
if (m_isEventTracingEnabled.load(std::memory_order_acquire))
|
if (m_isEventTracingEnabled.load(std::memory_order_acquire))
|
||||||
EasyEventTracer::instance().enable(true);
|
EasyEventTracer::instance().enable(true);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_setTime)
|
||||||
|
{
|
||||||
|
guard_lock_t lk(m_spin);
|
||||||
|
m_beginTime = time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_endTime = time;
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
EasyEventTracer::instance().disable();
|
EasyEventTracer::instance().disable();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (_setTime)
|
||||||
|
{
|
||||||
|
guard_lock_t lk(m_spin);
|
||||||
|
m_endTime = time;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -706,7 +765,7 @@ void ProfileManager::startListenSignalToCapture()
|
|||||||
if (!m_isAlreadyListened)
|
if (!m_isAlreadyListened)
|
||||||
{
|
{
|
||||||
m_stopListen.store(false, std::memory_order_release);
|
m_stopListen.store(false, std::memory_order_release);
|
||||||
m_listenThread = std::thread(&ProfileManager::listen, this);
|
m_listenThread = std::move(std::thread(&ProfileManager::listen, this));
|
||||||
m_isAlreadyListened = true;
|
m_isAlreadyListened = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -714,6 +773,8 @@ void ProfileManager::startListenSignalToCapture()
|
|||||||
void ProfileManager::stopListenSignalToCapture()
|
void ProfileManager::stopListenSignalToCapture()
|
||||||
{
|
{
|
||||||
m_stopListen.store(true, std::memory_order_release);
|
m_stopListen.store(true, std::memory_order_release);
|
||||||
|
if (m_listenThread.joinable())
|
||||||
|
m_listenThread.join();
|
||||||
m_isAlreadyListened = false;
|
m_isAlreadyListened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,13 +802,21 @@ void ProfileManager::listen()
|
|||||||
hasConnect = true;
|
hasConnect = true;
|
||||||
|
|
||||||
#ifdef EASY_DEBUG_NET_PRINT
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
printf("Client Accepted!\n");
|
printf("GUI-client connected\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
replyMessage.type = profiler::net::MESSAGE_TYPE_ACCEPTED_CONNECTION;
|
// Send reply
|
||||||
bytes = socket.send(&replyMessage, sizeof(replyMessage));
|
{
|
||||||
|
const bool wasLowPriorityET =
|
||||||
|
#ifdef _WIN32
|
||||||
|
EasyEventTracer::instance().isLowPriority();
|
||||||
|
#else
|
||||||
|
false;
|
||||||
|
#endif
|
||||||
|
profiler::net::EasyProfilerStatus connectionReply(m_isEnabled.load(std::memory_order_acquire), m_isEventTracingEnabled.load(std::memory_order_acquire), wasLowPriorityET);
|
||||||
|
bytes = socket.send(&connectionReply, sizeof(connectionReply));
|
||||||
hasConnect = bytes > 0;
|
hasConnect = bytes > 0;
|
||||||
|
}
|
||||||
|
|
||||||
while (hasConnect && !m_stopListen.load(std::memory_order_acquire))
|
while (hasConnect && !m_stopListen.load(std::memory_order_acquire))
|
||||||
{
|
{
|
||||||
@ -771,11 +840,15 @@ void ProfileManager::listen()
|
|||||||
case profiler::net::MESSAGE_TYPE_REQUEST_START_CAPTURE:
|
case profiler::net::MESSAGE_TYPE_REQUEST_START_CAPTURE:
|
||||||
{
|
{
|
||||||
#ifdef EASY_DEBUG_NET_PRINT
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
printf("RECEIVED MESSAGE_TYPE_REQUEST_START_CAPTURE\n");
|
printf("receive REQUEST_START_CAPTURE\n");
|
||||||
#endif
|
#endif
|
||||||
|
::profiler::timestamp_t t = 0;
|
||||||
|
EASY_FORCE_EVENT(t, "StartCapture", profiler::colors::Green, profiler::OFF);
|
||||||
|
ProfileManager::setEnabled(true, false);
|
||||||
|
|
||||||
ProfileManager::setEnabled(true);
|
m_spin.lock();
|
||||||
EASY_EVENT("StartCapture", profiler::colors::Green, profiler::OFF);
|
m_beginTime = t;
|
||||||
|
m_spin.unlock();
|
||||||
|
|
||||||
replyMessage.type = profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING;
|
replyMessage.type = profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING;
|
||||||
bytes = socket.send(&replyMessage, sizeof(replyMessage));
|
bytes = socket.send(&replyMessage, sizeof(replyMessage));
|
||||||
@ -787,12 +860,15 @@ void ProfileManager::listen()
|
|||||||
case profiler::net::MESSAGE_TYPE_REQUEST_STOP_CAPTURE:
|
case profiler::net::MESSAGE_TYPE_REQUEST_STOP_CAPTURE:
|
||||||
{
|
{
|
||||||
#ifdef EASY_DEBUG_NET_PRINT
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
printf("RECEIVED MESSAGE_TYPE_REQUEST_STOP_CAPTURE\n");
|
printf("receive REQUEST_STOP_CAPTURE\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EASY_EVENT("StopCapture", profiler::colors::Red, profiler::OFF);
|
|
||||||
ProfileManager::setEnabled(false);
|
ProfileManager::setEnabled(false);
|
||||||
|
|
||||||
|
m_spin.lock();
|
||||||
|
::profiler::timestamp_t t = m_endTime;
|
||||||
|
m_spin.unlock();
|
||||||
|
EASY_FORCE_EVENT2(t, "StopCapture", profiler::colors::Red, profiler::OFF);
|
||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
//if connection aborted - ignore this part
|
//if connection aborted - ignore this part
|
||||||
|
|
||||||
@ -829,7 +905,7 @@ void ProfileManager::listen()
|
|||||||
case profiler::net::MESSAGE_TYPE_REQUEST_BLOCKS_DESCRIPTION:
|
case profiler::net::MESSAGE_TYPE_REQUEST_BLOCKS_DESCRIPTION:
|
||||||
{
|
{
|
||||||
#ifdef EASY_DEBUG_NET_PRINT
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
printf("RECEIVED MESSAGE_TYPE_REQUEST_BLOCKS_DESCRIPTION\n");
|
printf("receive REQUEST_BLOCKS_DESCRIPTION\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
profiler::OStream os;
|
profiler::OStream os;
|
||||||
@ -880,16 +956,43 @@ void ProfileManager::listen()
|
|||||||
|
|
||||||
case profiler::net::MESSAGE_TYPE_EDIT_BLOCK_STATUS:
|
case profiler::net::MESSAGE_TYPE_EDIT_BLOCK_STATUS:
|
||||||
{
|
{
|
||||||
|
auto data = reinterpret_cast<const profiler::net::BlockStatusMessage*>(message);
|
||||||
|
|
||||||
#ifdef EASY_DEBUG_NET_PRINT
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
printf("RECEIVED MESSAGE_TYPE_EDIT_BLOCK_STATUS\n");
|
printf("receive EDIT_BLOCK_STATUS id=%u status=%u\n", data->id, data->status);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto data = reinterpret_cast<const profiler::net::BlockStatusMessage*>(message);
|
|
||||||
setBlockStatus(data->id, static_cast<::profiler::EasyBlockStatus>(data->status));
|
setBlockStatus(data->id, static_cast<::profiler::EasyBlockStatus>(data->status));
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case profiler::net::MESSAGE_TYPE_EVENT_TRACING_STATUS:
|
||||||
|
{
|
||||||
|
auto data = reinterpret_cast<const profiler::net::BoolMessage*>(message);
|
||||||
|
|
||||||
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
|
printf("receive EVENT_TRACING_STATUS on=%d\n", data->flag ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_isEventTracingEnabled.store(data->flag, std::memory_order_release);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case profiler::net::MESSAGE_TYPE_EVENT_TRACING_PRIORITY:
|
||||||
|
{
|
||||||
|
auto data = reinterpret_cast<const profiler::net::BoolMessage*>(message);
|
||||||
|
|
||||||
|
#ifdef EASY_DEBUG_NET_PRINT
|
||||||
|
printf("receive EVENT_TRACING_PRIORITY low=%d\n", data->flag ? 1 : 0);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
EasyEventTracer::instance().setLowPriority(data->flag);
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -359,6 +359,7 @@ class ProfileManager
|
|||||||
int m_socket = 0;//TODO crossplatform
|
int m_socket = 0;//TODO crossplatform
|
||||||
|
|
||||||
std::atomic_bool m_stopListen;
|
std::atomic_bool m_stopListen;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
static ProfileManager& instance();
|
static ProfileManager& instance();
|
||||||
@ -375,7 +376,7 @@ public:
|
|||||||
void storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName);
|
void storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName);
|
||||||
void beginBlock(profiler::Block& _block);
|
void beginBlock(profiler::Block& _block);
|
||||||
void endBlock();
|
void endBlock();
|
||||||
void setEnabled(bool isEnable);
|
void setEnabled(bool isEnable, bool _setTime = true);
|
||||||
void setEventTracingEnabled(bool _isEnable);
|
void setEventTracingEnabled(bool _isEnable);
|
||||||
uint32_t dumpBlocksToFile(const char* filename);
|
uint32_t dumpBlocksToFile(const char* filename);
|
||||||
const char* registerThread(const char* name, profiler::ThreadGuard& threadGuard);
|
const char* registerThread(const char* name, profiler::ThreadGuard& threadGuard);
|
||||||
@ -397,8 +398,12 @@ public:
|
|||||||
void endContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _endtime, bool _lockSpin = true);
|
void endContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _endtime, bool _lockSpin = true);
|
||||||
void startListenSignalToCapture();
|
void startListenSignalToCapture();
|
||||||
void stopListenSignalToCapture();
|
void stopListenSignalToCapture();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
void storeBlockForce(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t& _timestamp);
|
||||||
|
void storeBlockForce2(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName, ::profiler::timestamp_t _timestamp);
|
||||||
|
|
||||||
ThreadStorage& threadStorage(profiler::thread_id_t _thread_id);
|
ThreadStorage& threadStorage(profiler::thread_id_t _thread_id);
|
||||||
ThreadStorage* _findThreadStorage(profiler::thread_id_t _thread_id);
|
ThreadStorage* _findThreadStorage(profiler::thread_id_t _thread_id);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user