From eca7061fd0413396c7b99f5ac05813868f65da48 Mon Sep 17 00:00:00 2001 From: Victor Zarubkin Date: Wed, 28 Sep 2016 00:37:20 +0300 Subject: [PATCH] Added menu Settings->Remote to control profiler event tracing and other future options --- include/profiler/easy_net.h | 57 +++++----- profiler_gui/blocks_graphics_view.cpp | 5 +- profiler_gui/main_window.cpp | 110 +++++++++++++++++-- profiler_gui/main_window.h | 13 ++- profiler_gui/tree_widget_loader.cpp | 38 +++++-- sample/main.cpp | 2 - src/event_trace_win.cpp | 5 + src/event_trace_win.h | 2 + src/profile_manager.cpp | 149 ++++++++++++++++++++++---- src/profile_manager.h | 7 +- 10 files changed, 311 insertions(+), 77 deletions(-) diff --git a/include/profiler/easy_net.h b/include/profiler/easy_net.h index 7124730..270f42f 100644 --- a/include/profiler/easy_net.h +++ b/include/profiler/easy_net.h @@ -13,7 +13,7 @@ const uint32_t EASY_MESSAGE_SIGN = 20160909; enum MessageType : uint8_t { - MESSAGE_TYPE_ZERO, + MESSAGE_TYPE_ZERO = 0, MESSAGE_TYPE_REQUEST_START_CAPTURE, MESSAGE_TYPE_REPLY_START_CAPTURING, @@ -29,6 +29,9 @@ enum MessageType : uint8_t MESSAGE_TYPE_REPLY_BLOCKS_DESCRIPTION_END, MESSAGE_TYPE_EDIT_BLOCK_STATUS, + + MESSAGE_TYPE_EVENT_TRACING_STATUS, + MESSAGE_TYPE_EVENT_TRACING_PRIORITY, }; struct Message @@ -45,40 +48,44 @@ struct Message Message(MessageType _t):type(_t){} }; -struct DataMessage : public Message -{ - uint32_t size = 0;//bytes - - DataMessage(MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) : - Message(_t) - {} - - DataMessage(uint32_t _s, MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) : - Message(_t) - , size(_s) - {} - - const char* data() const - { - return reinterpret_cast(this) + sizeof(DataMessage); - } +struct DataMessage : public Message { + uint32_t size = 0; // bytes + DataMessage(MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) : Message(_t) {} + DataMessage(uint32_t _s, MessageType _t = MESSAGE_TYPE_REPLY_BLOCKS) : Message(_t), size(_s) {} + const char* data() const { return reinterpret_cast(this) + sizeof(DataMessage); } }; -struct BlockStatusMessage : public Message -{ +struct BlockStatusMessage : public Message { uint32_t id; 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) - : Message(MESSAGE_TYPE_EDIT_BLOCK_STATUS) - , id(_id) - , status(_status) +struct EasyProfilerStatus : public Message +{ + bool isProfilerEnabled; + bool isEventTracingEnabled; + bool isLowPriorityEventTracing; + + EasyProfilerStatus(bool _enabled, bool _ETenabled, bool _ETlowp) + : Message(MESSAGE_TYPE_ACCEPTED_CONNECTION) + , isProfilerEnabled(_enabled) + , isEventTracingEnabled(_ETenabled) + , isLowPriorityEventTracing(_ETlowp) { } 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) diff --git a/profiler_gui/blocks_graphics_view.cpp b/profiler_gui/blocks_graphics_view.cpp index 03694f4..31d75e4 100644 --- a/profiler_gui/blocks_graphics_view.cpp +++ b/profiler_gui/blocks_graphics_view.cpp @@ -442,9 +442,10 @@ void EasyGraphicsView::setTree(const ::profiler::thread_blocks_tree_t& _blocksTr { children_duration = setTree(item, t.children, h, y, 0); } - else if (!t.sync.empty()) + else { - children_duration = time2position(blocksTree(t.sync.back()).node->end()) - x; + if (!t.sync.empty()) + children_duration = time2position(blocksTree(t.sync.back()).node->end()) - x; h = ::profiler_gui::GRAPHICS_ROW_SIZE; } diff --git a/profiler_gui/main_window.cpp b/profiler_gui/main_window.cpp index 80e1b5c..c57bd31 100644 --- a/profiler_gui/main_window.cpp +++ b/profiler_gui/main_window.cpp @@ -244,6 +244,20 @@ EasyMainWindow::EasyMainWindow() : Parent() 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"); actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); @@ -655,6 +669,9 @@ void EasyMainWindow::onListenerDialogClose(int) m_captureAction->setEnabled(false); SET_ICON(m_connectAction, ":/Connection"); + m_eventTracingEnableAction->setEnabled(false); + m_eventTracingPriorityAction->setEnabled(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) { if(EASY_GLOBALS.connected) @@ -878,7 +909,9 @@ void EasyMainWindow::onConnectClicked(bool) m_lastAddress = parts.join(QChar('.')); m_lastPort = m_portEdit->text().toUShort(); 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); return; @@ -889,6 +922,18 @@ void EasyMainWindow::onConnectClicked(bool) m_captureAction->setEnabled(true); 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); } @@ -986,6 +1031,9 @@ void EasyMainWindow::onGetBlockDescriptionsClicked(bool) m_captureAction->setEnabled(false); SET_ICON(m_connectAction, ":/Connection"); + m_eventTracingEnableAction->setEnabled(false); + m_eventTracingPriorityAction->setEnabled(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) { if (EASY_GLOBALS.connected) - m_listener.sendBlockStatus(_id, _status); + m_listener.send(profiler::net::BlockStatusMessage(_id, static_cast(_status))); } ////////////////////////////////////////////////////////////////////////// @@ -1040,7 +1088,7 @@ void EasySocketListener::clearData() 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()) return true; @@ -1050,9 +1098,55 @@ bool EasySocketListener::connect(const char* _ipaddress, uint16_t _port) int res = m_easySocket.setAddress(_ipaddress, _port); res = m_easySocket.connect(); - bool isConnected = res == 0; - m_bConnected.store(isConnected, ::std::memory_order_release); + const bool isConnected = res == 0; + 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(buffer); + if (message->isEasyNetMessage() && message->type == profiler::net::MESSAGE_TYPE_ACCEPTED_CONNECTION) + _reply = *message; + } + m_bConnected.store(isConnected, ::std::memory_order_release); return isConnected; } @@ -1092,12 +1186,6 @@ void EasySocketListener::requestBlocksDescription() m_regime = LISTENER_IDLE; } -void EasySocketListener::sendBlockStatus(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status) -{ - profiler::net::BlockStatusMessage message(_id, static_cast(_status)); - m_easySocket.send(&message, sizeof(message)); -} - ////////////////////////////////////////////////////////////////////////// void EasySocketListener::listenCapture() diff --git a/profiler_gui/main_window.h b/profiler_gui/main_window.h index 96f439e..a38dd10 100644 --- a/profiler_gui/main_window.h +++ b/profiler_gui/main_window.h @@ -55,6 +55,8 @@ class QDockWidget; +namespace profiler { namespace net { struct EasyProfilerStatus; } } + ////////////////////////////////////////////////////////////////////////// class EasyFileReader Q_DECL_FINAL @@ -126,13 +128,16 @@ public: ::std::stringstream& data(); 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 stopCapture(); void requestBlocksDescription(); - void sendBlockStatus(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); + template + inline void send(const T& _message) { + m_easySocket.send(&_message, sizeof(T)); + } private: @@ -177,6 +182,8 @@ protected: class QAction* m_captureAction = nullptr; class QAction* m_connectAction = nullptr; + class QAction* m_eventTracingEnableAction = nullptr; + class QAction* m_eventTracingPriorityAction = nullptr; uint16_t m_lastPort = 0; @@ -214,6 +221,8 @@ protected slots: void onCaptureClicked(bool); void onGetBlockDescriptionsClicked(bool); void onConnectClicked(bool); + void onEventTracingPriorityChange(bool _checked); + void onEventTracingEnableChange(bool _checked); void onBlockStatusChange(::profiler::block_id_t _id, ::profiler::EasyBlockStatus _status); diff --git a/profiler_gui/tree_widget_loader.cpp b/profiler_gui/tree_widget_loader.cpp index 1a1974f..f258999 100644 --- a/profiler_gui/tree_widget_loader.cpp +++ b/profiler_gui/tree_widget_loader.cpp @@ -293,11 +293,11 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI item->setTimeMs(COL_BEGIN, startTime - _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->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 { @@ -317,7 +317,7 @@ void FillTreeClass::setTreeInternal2(T& _safelocker, Items& _items, ThreadedI 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)); - 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->setText(COL_PERCENT_SUM_PER_THREAD, QString::number(percentage_per_thread)); @@ -488,9 +488,18 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: else { 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->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); + } } @@ -538,12 +547,19 @@ size_t FillTreeClass::setTreeInternal(T& _safelocker, Items& _items, const :: } else { - item->setData(COL_PERCENT_PER_PARENT, Qt::UserRole, 0); - item->setText(COL_PERCENT_PER_PARENT, ""); + 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_SUM_PER_PARENT, Qt::UserRole, 0); - item->setText(COL_PERCENT_SUM_PER_PARENT, ""); 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(); diff --git a/sample/main.cpp b/sample/main.cpp index 4c0ee35..c8a6f64 100644 --- a/sample/main.cpp +++ b/sample/main.cpp @@ -236,7 +236,5 @@ int main(int argc, char* argv[]) std::cout << "Blocks count: " << blocks_count << std::endl; - - profiler::stopListenSignalToCapture(); return 0; } diff --git a/src/event_trace_win.cpp b/src/event_trace_win.cpp index 26f9ccd..7d9277a 100644 --- a/src/event_trace_win.cpp +++ b/src/event_trace_win.cpp @@ -222,6 +222,11 @@ namespace profiler { disable(); } + bool EasyEventTracer::isLowPriority() const + { + return m_lowPriority.load(::std::memory_order_acquire); + } + void EasyEventTracer::setLowPriority(bool _value) { m_lowPriority.store(_value, ::std::memory_order_release); diff --git a/src/event_trace_win.h b/src/event_trace_win.h index 83eba72..ce1d3cf 100644 --- a/src/event_trace_win.h +++ b/src/event_trace_win.h @@ -78,6 +78,8 @@ namespace profiler { static EasyEventTracer& instance(); ~EasyEventTracer(); + bool isLowPriority() const; + ::profiler::EventTracingEnableStatus enable(bool _force = false); void disable(); void setLowPriority(bool _value); diff --git a/src/profile_manager.cpp b/src/profile_manager.cpp index 55c8b2a..1bbe56d 100644 --- a/src/profile_manager.cpp +++ b/src/profile_manager.cpp @@ -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" { 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(); - if (m_listenThread.joinable()) - m_listenThread.join(); - for (auto desc : m_descriptors) { if (desc != nullptr) @@ -367,6 +378,46 @@ void ProfileManager::storeBlock(const profiler::BaseBlockDescriptor* _desc, cons 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) { 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(); } -void ProfileManager::setEnabled(bool isEnable) +void ProfileManager::setEnabled(bool isEnable, bool _setTime) { auto time = getCurrentTime(); const bool prev = m_isEnabled.exchange(isEnable, std::memory_order_release); @@ -467,20 +518,28 @@ void ProfileManager::setEnabled(bool isEnable) if (isEnable) { - m_beginTime = time; - #ifdef _WIN32 if (m_isEventTracingEnabled.load(std::memory_order_acquire)) EasyEventTracer::instance().enable(true); #endif + + if (_setTime) + { + guard_lock_t lk(m_spin); + m_beginTime = time; + } } else { - m_endTime = time; - #ifdef _WIN32 EasyEventTracer::instance().disable(); #endif + + if (_setTime) + { + guard_lock_t lk(m_spin); + m_endTime = time; + } } } @@ -706,7 +765,7 @@ void ProfileManager::startListenSignalToCapture() if (!m_isAlreadyListened) { 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; } } @@ -714,6 +773,8 @@ void ProfileManager::startListenSignalToCapture() void ProfileManager::stopListenSignalToCapture() { m_stopListen.store(true, std::memory_order_release); + if (m_listenThread.joinable()) + m_listenThread.join(); m_isAlreadyListened = false; } @@ -741,13 +802,21 @@ void ProfileManager::listen() hasConnect = true; #ifdef EASY_DEBUG_NET_PRINT - printf("Client Accepted!\n"); + printf("GUI-client connected\n"); #endif - replyMessage.type = profiler::net::MESSAGE_TYPE_ACCEPTED_CONNECTION; - bytes = socket.send(&replyMessage, sizeof(replyMessage)); - - hasConnect = bytes > 0; + // Send reply + { + 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; + } while (hasConnect && !m_stopListen.load(std::memory_order_acquire)) { @@ -771,11 +840,15 @@ void ProfileManager::listen() case profiler::net::MESSAGE_TYPE_REQUEST_START_CAPTURE: { #ifdef EASY_DEBUG_NET_PRINT - printf("RECEIVED MESSAGE_TYPE_REQUEST_START_CAPTURE\n"); + printf("receive REQUEST_START_CAPTURE\n"); #endif + ::profiler::timestamp_t t = 0; + EASY_FORCE_EVENT(t, "StartCapture", profiler::colors::Green, profiler::OFF); + ProfileManager::setEnabled(true, false); - ProfileManager::setEnabled(true); - EASY_EVENT("StartCapture", profiler::colors::Green, profiler::OFF); + m_spin.lock(); + m_beginTime = t; + m_spin.unlock(); replyMessage.type = profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING; bytes = socket.send(&replyMessage, sizeof(replyMessage)); @@ -787,12 +860,15 @@ void ProfileManager::listen() case profiler::net::MESSAGE_TYPE_REQUEST_STOP_CAPTURE: { #ifdef EASY_DEBUG_NET_PRINT - printf("RECEIVED MESSAGE_TYPE_REQUEST_STOP_CAPTURE\n"); + printf("receive REQUEST_STOP_CAPTURE\n"); #endif - - EASY_EVENT("StopCapture", profiler::colors::Red, profiler::OFF); 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 //if connection aborted - ignore this part @@ -829,7 +905,7 @@ void ProfileManager::listen() case profiler::net::MESSAGE_TYPE_REQUEST_BLOCKS_DESCRIPTION: { #ifdef EASY_DEBUG_NET_PRINT - printf("RECEIVED MESSAGE_TYPE_REQUEST_BLOCKS_DESCRIPTION\n"); + printf("receive REQUEST_BLOCKS_DESCRIPTION\n"); #endif profiler::OStream os; @@ -880,16 +956,43 @@ void ProfileManager::listen() case profiler::net::MESSAGE_TYPE_EDIT_BLOCK_STATUS: { + auto data = reinterpret_cast(message); + #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 - auto data = reinterpret_cast(message); setBlockStatus(data->id, static_cast<::profiler::EasyBlockStatus>(data->status)); break; } + case profiler::net::MESSAGE_TYPE_EVENT_TRACING_STATUS: + { + auto data = reinterpret_cast(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(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: break; } diff --git a/src/profile_manager.h b/src/profile_manager.h index 395c30b..6fb4837 100644 --- a/src/profile_manager.h +++ b/src/profile_manager.h @@ -359,6 +359,7 @@ class ProfileManager int m_socket = 0;//TODO crossplatform std::atomic_bool m_stopListen; + public: static ProfileManager& instance(); @@ -375,7 +376,7 @@ public: void storeBlock(const profiler::BaseBlockDescriptor* _desc, const char* _runtimeName); void beginBlock(profiler::Block& _block); void endBlock(); - void setEnabled(bool isEnable); + void setEnabled(bool isEnable, bool _setTime = true); void setEventTracingEnabled(bool _isEnable); uint32_t dumpBlocksToFile(const char* filename); 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 startListenSignalToCapture(); void stopListenSignalToCapture(); + 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* _findThreadStorage(profiler::thread_id_t _thread_id);