mirror of
https://github.com/yse/easy_profiler.git
synced 2025-01-14 00:27:55 +08:00
Merge commit
This commit is contained in:
commit
85e7145bf1
@ -302,6 +302,8 @@ namespace profiler {
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Core types
|
||||
|
||||
const uint16_t DEFAULT_PORT = 28077;
|
||||
|
||||
typedef uint64_t timestamp_t;
|
||||
typedef uint32_t thread_id_t;
|
||||
typedef uint32_t block_id_t;
|
||||
@ -553,6 +555,9 @@ namespace profiler {
|
||||
PROFILER_API const char* getContextSwitchLogFilename();
|
||||
#endif
|
||||
|
||||
PROFILER_API void startListenSignalToCapture();
|
||||
PROFILER_API void stopListenSignalToCapture();
|
||||
|
||||
}
|
||||
|
||||
inline void setEnabled(::profiler::EasyEnableFlag _isEnable) {
|
||||
|
@ -9,6 +9,9 @@ set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||
|
||||
find_package(Qt5Widgets REQUIRED)
|
||||
find_package(Qt5Network REQUIRED)
|
||||
|
||||
include_directories(${ROOT}/3rdparty/nanomsg/src)
|
||||
|
||||
add_executable(${PROJECT_NAME}
|
||||
main.cpp
|
||||
@ -45,4 +48,4 @@ if(UNIX)
|
||||
set(SPECIAL_LIB pthread)
|
||||
endif(UNIX)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} Qt5::Widgets easy_profiler ${SPECIAL_LIB})
|
||||
target_link_libraries(${PROJECT_NAME} Qt5::Widgets Qt5::Network easy_profiler ${SPECIAL_LIB})
|
||||
|
@ -49,6 +49,9 @@
|
||||
#include <QProgressDialog>
|
||||
#include <QSignalBlocker>
|
||||
#include <QDebug>
|
||||
#include <QToolBar>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QVBoxLayout>
|
||||
#include "main_window.h"
|
||||
@ -57,6 +60,15 @@
|
||||
#include "descriptors_tree_widget.h"
|
||||
#include "globals.h"
|
||||
|
||||
#include "profiler/easy_net.h"
|
||||
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <fstream>
|
||||
|
||||
|
||||
#undef max
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const int LOADER_TIMER_INTERVAL = 40;
|
||||
@ -111,7 +123,77 @@ EasyMainWindow::EasyMainWindow() : Parent()
|
||||
m_descTreeWidget->setWidget(descTree);
|
||||
addDockWidget(Qt::BottomDockWidgetArea, m_descTreeWidget);
|
||||
#endif
|
||||
QToolBar *fileToolBar = addToolBar(tr("File"));
|
||||
m_connectAct = new QAction(tr("&Connect"), this);
|
||||
SET_ICON(m_connectAct, ":/WiFi");
|
||||
|
||||
QAction *newAct = new QAction(tr("&Capture"), this);
|
||||
SET_ICON(newAct, ":/Start");
|
||||
fileToolBar->addAction(m_connectAct);
|
||||
fileToolBar->addAction(newAct);
|
||||
|
||||
|
||||
connect(newAct, &QAction::triggered, this, &This::onCaptureClicked);
|
||||
connect(m_connectAct, &QAction::triggered, this, &This::onConnectClicked);
|
||||
|
||||
m_hostString = new QLineEdit();
|
||||
QRegExp rx("[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}");
|
||||
|
||||
m_hostString->setInputMask("000.000.000.000;");
|
||||
m_hostString->setValidator(new QRegExpValidator(rx,0));
|
||||
m_hostString->setText("127.0.0.1");
|
||||
|
||||
fileToolBar->addWidget(m_hostString);
|
||||
|
||||
m_portString = new QLineEdit();
|
||||
m_portString->setValidator(new QIntValidator(1024, 65536, this));
|
||||
m_portString->setText(QString::number(profiler::DEFAULT_PORT));
|
||||
|
||||
fileToolBar->addWidget(m_portString);
|
||||
|
||||
|
||||
|
||||
/*m_server = new QTcpSocket( );
|
||||
m_server->setSocketOption(QAbstractSocket::LowDelayOption, 0);
|
||||
m_server->setReadBufferSize(16 * 1024);
|
||||
|
||||
//connect(m_server, SIGNAL(readyRead()), SLOT(readTcpData()));
|
||||
connect(m_server, SIGNAL(connected()), SLOT(onConnected()));
|
||||
connect(m_server, SIGNAL(error(QAbstractSocket::SocketError)), SLOT(onErrorConnection(QAbstractSocket::SocketError)), Qt::UniqueConnection);
|
||||
connect(m_server, SIGNAL(disconnected()), SLOT(onDisconnect()), Qt::UniqueConnection);
|
||||
|
||||
m_receiver = new TcpReceiverThread(this, this);
|
||||
|
||||
connect(m_receiver, &TcpReceiverThread::resultReady, this, &This::handleResults);
|
||||
connect(m_receiver, &TcpReceiverThread::finished, m_receiver, &QObject::deleteLater);
|
||||
|
||||
m_receiver->start();
|
||||
*/
|
||||
|
||||
//m_thread = std::thread(&This::listen, this);
|
||||
|
||||
//connect(m_server, &QAbstractSocket::readyRead, m_receiver, &TcpReceiverThread::readTcpData);
|
||||
|
||||
//m_receiver->run();
|
||||
|
||||
//m_server->connectToHost(m_hostString->text(), m_portString->text().toUShort());
|
||||
//TODO:
|
||||
//connected
|
||||
//error
|
||||
|
||||
/*if (!m_server->listen(QHostAddress(QHostAddress::Any), 28077)) {
|
||||
QMessageBox::critical(0,
|
||||
"Server Error",
|
||||
"Unable to start the server:"
|
||||
+ m_server->errorString()
|
||||
);
|
||||
m_server->close();
|
||||
}
|
||||
|
||||
connect(m_server, SIGNAL(newConnection()),
|
||||
this, SLOT(onNewConnection())
|
||||
);
|
||||
*/
|
||||
loadSettings();
|
||||
|
||||
|
||||
@ -249,7 +331,8 @@ EasyMainWindow::EasyMainWindow() : Parent()
|
||||
|
||||
connect(graphicsView->view(), &EasyGraphicsView::intervalChanged, treeWidget, &EasyTreeWidget::setTreeBlocks);
|
||||
connect(&m_readerTimer, &QTimer::timeout, this, &This::onFileReaderTimeout);
|
||||
|
||||
connect(&m_downloadedTimer, &QTimer::timeout, this, &This::onDownloadTimeout);
|
||||
|
||||
|
||||
m_progress = new QProgressDialog("Loading file...", "Cancel", 0, 100, this);
|
||||
m_progress->setFixedWidth(300);
|
||||
@ -260,6 +343,13 @@ EasyMainWindow::EasyMainWindow() : Parent()
|
||||
connect(m_progress, &QProgressDialog::canceled, this, &This::onFileReaderCancel);
|
||||
|
||||
|
||||
m_downloadingProgress = new QProgressDialog("Loading file...", "Cancel", 0, 100, this);
|
||||
m_downloadingProgress->setFixedWidth(300);
|
||||
m_downloadingProgress->setWindowTitle("EasyProfiler");
|
||||
m_downloadingProgress->setModal(true);
|
||||
m_downloadingProgress->setValue(100);
|
||||
//m_downloadedTimer.start(10);
|
||||
|
||||
loadGeometry();
|
||||
|
||||
if(QCoreApplication::arguments().size() > 1)
|
||||
@ -269,11 +359,165 @@ EasyMainWindow::EasyMainWindow() : Parent()
|
||||
}
|
||||
}
|
||||
|
||||
void EasyMainWindow::listen()
|
||||
{
|
||||
profiler::net::Message request(profiler::net::MESSAGE_TYPE_REQUEST_START_CAPTURE);
|
||||
|
||||
|
||||
//std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
const int buffer_size = 8 * 1024 * 1024;
|
||||
char* buffer = new char[buffer_size];
|
||||
int seek = 0;
|
||||
int bytes = 0;
|
||||
|
||||
static auto timeBegin = std::chrono::system_clock::now();
|
||||
bool isListen = true;
|
||||
while (isListen)
|
||||
{
|
||||
if ((bytes - seek) == 0){
|
||||
bytes = m_easySocket.receive(buffer, buffer_size);
|
||||
if(bytes == -1)
|
||||
{
|
||||
if(m_easySocket.state() == EasySocket::CONNECTION_STATE_DISCONNECTED)
|
||||
{
|
||||
isListen = false;
|
||||
}
|
||||
seek = 0;
|
||||
bytes = 0;
|
||||
continue;
|
||||
}
|
||||
seek = 0;
|
||||
}
|
||||
|
||||
char *buf = &buffer[seek];
|
||||
|
||||
if(bytes == 0){
|
||||
isListen = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bytes > 0)
|
||||
{
|
||||
profiler::net::Message* message = (profiler::net::Message*)buf;
|
||||
if (!message->isEasyNetMessage()){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
switch (message->type) {
|
||||
case profiler::net::MESSAGE_TYPE_ACCEPTED_CONNECTION:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_ACCEPTED_CONNECTION";
|
||||
|
||||
//m_easySocket.send(&request, sizeof(request));
|
||||
|
||||
seek += sizeof(profiler::net::Message);
|
||||
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_START_CAPTURING";
|
||||
seek += sizeof(profiler::net::Message);
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_PREPARE_BLOCKS:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_PREPARE_BLOCKS";
|
||||
m_isClientPreparedBlocks = true;
|
||||
|
||||
seek += sizeof(profiler::net::Message);
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_END_SEND_BLOCKS:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_END_SEND_BLOCKS";
|
||||
seek += sizeof(profiler::net::Message);
|
||||
|
||||
auto timeEnd = std::chrono::system_clock::now();
|
||||
auto dT = std::chrono::duration_cast<std::chrono::milliseconds>(timeEnd - timeBegin);
|
||||
auto dTsec = std::chrono::duration_cast<std::chrono::seconds>(timeEnd - timeBegin);
|
||||
qInfo() << "recieve" << m_receivedProfileData.str().size() << dT.count() << "ms" << double(m_receivedProfileData.str().size())*1000.0 / double(dT.count()) / 1024.0 << "kBytes/sec";
|
||||
m_recFrames = false;
|
||||
|
||||
|
||||
qInfo() << "Write FILE";
|
||||
std::string tempfilename = "test_rec.prof";
|
||||
std::ofstream of(tempfilename, std::fstream::binary);
|
||||
of << m_receivedProfileData.str();
|
||||
of.close();
|
||||
|
||||
m_receivedProfileData.str(std::string());
|
||||
m_receivedProfileData.clear();
|
||||
//loadFile(QString(tempfilename.c_str()));
|
||||
m_recFrames = false;
|
||||
isListen = false;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_BLOCKS:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_BLOCKS";
|
||||
|
||||
seek += sizeof(profiler::net::DataMessage);
|
||||
profiler::net::DataMessage* dm = (profiler::net::DataMessage*)message;
|
||||
timeBegin = std::chrono::system_clock::now();
|
||||
|
||||
int neededSize = dm->size;
|
||||
|
||||
|
||||
buf = &buffer[seek];
|
||||
m_receivedProfileData.write(buf, bytes - seek);
|
||||
neededSize -= bytes - seek;
|
||||
seek = 0;
|
||||
bytes = 0;
|
||||
|
||||
|
||||
int loaded = 0;
|
||||
while (neededSize > 0)
|
||||
{
|
||||
bytes = m_easySocket.receive(buffer, buffer_size);
|
||||
|
||||
if(bytes == -1)
|
||||
{
|
||||
if(m_easySocket.state() == EasySocket::CONNECTION_STATE_DISCONNECTED)
|
||||
{
|
||||
isListen = false;
|
||||
neededSize = 0;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
buf = &buffer[0];
|
||||
int toWrite = std::min(bytes, neededSize);
|
||||
m_receivedProfileData.write(buf, toWrite);
|
||||
neededSize -= toWrite;
|
||||
loaded += toWrite;
|
||||
seek = toWrite;
|
||||
|
||||
m_downloadedBytes.store((loaded / (neededSize+1)) * 100);
|
||||
}
|
||||
} break;
|
||||
|
||||
default:
|
||||
//qInfo() << "Receive unknown " << message->type;
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
EasyMainWindow::~EasyMainWindow()
|
||||
{
|
||||
if (m_descTreeDialog != nullptr)
|
||||
delete m_descTreeDialog;
|
||||
delete m_progress;
|
||||
if (m_thread.joinable())
|
||||
m_thread.join();
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -453,33 +697,47 @@ void EasyMainWindow::loadSettings()
|
||||
|
||||
auto last_file = settings.value("last_file");
|
||||
if (!last_file.isNull())
|
||||
{
|
||||
m_lastFile = last_file.toString();
|
||||
}
|
||||
|
||||
|
||||
auto val = settings.value("chrono_text_position");
|
||||
if (!val.isNull())
|
||||
{
|
||||
EASY_GLOBALS.chrono_text_position = static_cast<::profiler_gui::ChronometerTextPosition>(val.toInt());
|
||||
}
|
||||
|
||||
|
||||
auto flag = settings.value("draw_graphics_items_borders");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
EASY_GLOBALS.draw_graphics_items_borders = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("collapse_items_on_tree_close");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
EASY_GLOBALS.collapse_items_on_tree_close = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("all_items_expanded_by_default");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
EASY_GLOBALS.all_items_expanded_by_default = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("bind_scene_and_tree_expand_status");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
EASY_GLOBALS.bind_scene_and_tree_expand_status = flag.toBool();
|
||||
}
|
||||
|
||||
flag = settings.value("enable_statistics");
|
||||
if (!flag.isNull())
|
||||
{
|
||||
EASY_GLOBALS.enable_statistics = flag.toBool();
|
||||
}
|
||||
|
||||
QString encoding = settings.value("encoding", "UTF-8").toString();
|
||||
auto default_codec_mib = QTextCodec::codecForName(encoding.toStdString().c_str())->mibEnum();
|
||||
@ -526,6 +784,19 @@ void EasyMainWindow::saveSettingsAndGeometry()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyMainWindow::onDownloadTimeout()
|
||||
{
|
||||
if (!m_downloading){
|
||||
m_downloadingProgress->setValue(100);
|
||||
//m_downloadingProgress->hide();
|
||||
m_downloadedTimer.stop();
|
||||
}
|
||||
else{
|
||||
m_downloadingProgress->setValue(m_downloadedBytes.load());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void EasyMainWindow::onFileReaderTimeout()
|
||||
{
|
||||
if (m_reader.done())
|
||||
@ -680,3 +951,215 @@ void EasyFileReader::get(::profiler::SerializedData& _serializedBlocks, ::profil
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void EasyMainWindow::onConnectClicked(bool)
|
||||
{
|
||||
if(m_isConnected)
|
||||
return;
|
||||
m_easySocket.flush();
|
||||
m_easySocket.init();
|
||||
int res = m_easySocket.setAddress(m_hostString->text().toStdString().c_str(), m_portString->text().toUShort());
|
||||
|
||||
//TODO: flush socket after disconenct
|
||||
res = m_easySocket.connect();
|
||||
if (res == -1)
|
||||
{
|
||||
QMessageBox::warning(this, "Warning", "Cannot connect with application", QMessageBox::Close);
|
||||
return;
|
||||
}
|
||||
qInfo() << "Connect with application successful";
|
||||
m_isConnected = true;
|
||||
|
||||
auto _sender = qobject_cast<QAction*>(sender());
|
||||
if (_sender)
|
||||
SET_ICON(_sender, ":/WiFi-on");
|
||||
|
||||
}
|
||||
|
||||
void EasyMainWindow::onCaptureClicked(bool)
|
||||
{
|
||||
|
||||
if (!m_isConnected)
|
||||
{
|
||||
QMessageBox::warning(this, "Warning", "No connection with profiling app", QMessageBox::Close);
|
||||
return;
|
||||
}
|
||||
|
||||
profiler::net::Message request(profiler::net::MESSAGE_TYPE_REQUEST_START_CAPTURE);
|
||||
m_easySocket.send(&request, sizeof(request));
|
||||
|
||||
|
||||
m_thread = std::thread(&This::listen, this);
|
||||
|
||||
QMessageBox::information(this,"Capturing frames..." ,"Close this window to stop capturing.",QMessageBox::Close);
|
||||
|
||||
request.type = profiler::net::MESSAGE_TYPE_REQUEST_STOP_CAPTURE;
|
||||
m_easySocket.send(&request, sizeof(request));
|
||||
|
||||
m_thread.join();
|
||||
|
||||
m_downloading = false;
|
||||
|
||||
if(m_easySocket.state() == EasySocket::CONNECTION_STATE_DISCONNECTED)
|
||||
{
|
||||
QMessageBox::warning(this,"Warning" ,"Application was disconnected",QMessageBox::Close);
|
||||
m_isConnected = false;
|
||||
SET_ICON(m_connectAct, ":/WiFi");
|
||||
return;
|
||||
}
|
||||
|
||||
std::string tempfilename = "test_rec.prof";
|
||||
loadFile(QString(tempfilename.c_str()));
|
||||
|
||||
}
|
||||
|
||||
void EasyMainWindow::handleResults(const QString &s)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void EasyMainWindow::readTcpData()
|
||||
{
|
||||
static qint64 necessarySize = 0;
|
||||
static qint64 loadedSize = 0;
|
||||
static auto timeBegin = std::chrono::system_clock::now();
|
||||
while(m_server->bytesAvailable())
|
||||
{
|
||||
auto bytesExpected = necessarySize - loadedSize;
|
||||
QByteArray data;
|
||||
if (m_recFrames){
|
||||
data = m_server->read(qMin(bytesExpected, m_server->bytesAvailable()));
|
||||
}
|
||||
else
|
||||
{
|
||||
data = m_server->readAll();
|
||||
}
|
||||
|
||||
|
||||
profiler::net::Message* message = (profiler::net::Message*)data.data();
|
||||
//qInfo() << "rec size: " << data.size() << " " << QString(data);;
|
||||
if(!m_recFrames && !message->isEasyNetMessage()){
|
||||
return;
|
||||
}
|
||||
else if (m_recFrames){
|
||||
|
||||
if (m_receivedProfileData.str().size() == necessarySize)
|
||||
{
|
||||
m_recFrames = false;
|
||||
|
||||
auto timeEnd = std::chrono::system_clock::now();
|
||||
auto dT = std::chrono::duration_cast<std::chrono::milliseconds>(timeEnd - timeBegin);
|
||||
auto dTsec = std::chrono::duration_cast<std::chrono::seconds>(timeEnd - timeBegin);
|
||||
qInfo() << "recieve" << m_receivedProfileData.str().size() << dT.count() << "ms" << double(m_receivedProfileData.str().size())*1000.0 / double(dT.count()) / 1024.0 << "kBytes/sec";
|
||||
m_recFrames = false;
|
||||
|
||||
|
||||
qInfo() << "Write FILE";
|
||||
std::string tempfilename = "test_rec.prof";
|
||||
std::ofstream of(tempfilename, std::fstream::binary);
|
||||
of << m_receivedProfileData.str();
|
||||
of.close();
|
||||
|
||||
m_receivedProfileData.str(std::string());
|
||||
m_receivedProfileData.clear();
|
||||
loadFile(QString(tempfilename.c_str()));
|
||||
m_recFrames = false;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (m_receivedProfileData.str().size() > necessarySize)
|
||||
{
|
||||
qInfo() << "recieve more than necessary d=" << m_receivedProfileData.str().size() - necessarySize;
|
||||
}
|
||||
if (m_recFrames)
|
||||
{
|
||||
m_receivedProfileData.write(data.data(), data.size());
|
||||
loadedSize += data.size();
|
||||
continue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
switch (message->type) {
|
||||
case profiler::net::MESSAGE_TYPE_ACCEPTED_CONNECTION:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_ACCEPTED_CONNECTION";
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_START_CAPTURING:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_START_CAPTURING";
|
||||
|
||||
m_isClientCaptured = true;
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_PREPARE_BLOCKS:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_PREPARE_BLOCKS";
|
||||
m_isClientPreparedBlocks = true;
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_END_SEND_BLOCKS:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_END_SEND_BLOCKS";
|
||||
|
||||
}
|
||||
break;
|
||||
case profiler::net::MESSAGE_TYPE_REPLY_BLOCKS:
|
||||
{
|
||||
qInfo() << "Receive MESSAGE_TYPE_REPLY_BLOCKS";
|
||||
m_recFrames = true;
|
||||
profiler::net::DataMessage* dm = (profiler::net::DataMessage*)message;
|
||||
necessarySize = dm->size;
|
||||
loadedSize = 0;
|
||||
m_receivedProfileData.write(data.data()+sizeof(profiler::net::DataMessage),data.size() - sizeof(profiler::net::DataMessage));
|
||||
loadedSize += data.size() - sizeof(profiler::net::DataMessage);
|
||||
//std::this_thread::sleep_for(std::chrono::seconds(2));
|
||||
|
||||
timeBegin = std::chrono::system_clock::now();
|
||||
} break;
|
||||
|
||||
default:
|
||||
//qInfo() << "Receive unknown " << message->type;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void EasyMainWindow::onConnected()
|
||||
{
|
||||
qInfo() << "onConnected()";
|
||||
|
||||
m_isConnected = true;
|
||||
}
|
||||
void EasyMainWindow::onErrorConnection(QAbstractSocket::SocketError socketError)
|
||||
{
|
||||
qInfo() << m_server->error();
|
||||
}
|
||||
|
||||
void EasyMainWindow::onDisconnect()
|
||||
{
|
||||
qInfo() << "onDisconnect()";
|
||||
m_isConnected = false;
|
||||
}
|
||||
|
||||
void EasyMainWindow::onNewConnection()
|
||||
{
|
||||
//m_client = m_server->nextPendingConnection();
|
||||
|
||||
//qInfo() << "New connection!" << m_client;
|
||||
|
||||
//connect(m_client, SIGNAL(disconnected()), this, SLOT(onDisconnection())) ;
|
||||
//connect(m_client, SIGNAL(readyRead()), this, SLOT(readTcpData()) );
|
||||
}
|
||||
|
||||
void EasyMainWindow::onDisconnection()
|
||||
{
|
||||
//m_client = nullptr;
|
||||
}
|
@ -35,7 +35,15 @@
|
||||
#include <atomic>
|
||||
#include <QMainWindow>
|
||||
#include <QTimer>
|
||||
#include <QTcpServer>
|
||||
#include <QTcpSocket>
|
||||
#include <QThread>
|
||||
#include <QLineEdit>
|
||||
#include "profiler/easy_socket.h"
|
||||
#undef max
|
||||
#undef min
|
||||
#include "profiler/reader.h"
|
||||
#include <sstream>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -90,6 +98,7 @@ protected:
|
||||
QString m_lastFile;
|
||||
QDockWidget* m_treeWidget;
|
||||
QDockWidget* m_graphicsView;
|
||||
class QProgressDialog* m_downloadingProgress;
|
||||
|
||||
#if EASY_GUI_USE_DESCRIPTORS_DOCK_WINDOW != 0
|
||||
QDockWidget* m_descTreeWidget;
|
||||
@ -100,10 +109,28 @@ protected:
|
||||
class QDialog* m_descTreeDialog;
|
||||
class EasyDescWidget* m_dialogDescTree;
|
||||
QTimer m_readerTimer;
|
||||
QTimer m_downloadedTimer;
|
||||
::profiler::SerializedData m_serializedBlocks;
|
||||
::profiler::SerializedData m_serializedDescriptors;
|
||||
EasyFileReader m_reader;
|
||||
|
||||
QTcpSocket* m_server = nullptr;
|
||||
|
||||
std::stringstream m_receivedProfileData;
|
||||
bool m_recFrames = false;
|
||||
|
||||
QLineEdit* m_hostString = nullptr;
|
||||
QLineEdit* m_portString = nullptr;
|
||||
bool m_isConnected = false;
|
||||
|
||||
std::thread m_thread;
|
||||
|
||||
EasySocket m_easySocket;
|
||||
|
||||
bool m_downloading = false;
|
||||
::std::atomic<int> m_downloadedBytes;
|
||||
|
||||
QAction *m_connectAct = nullptr;
|
||||
public:
|
||||
|
||||
explicit EasyMainWindow();
|
||||
@ -113,6 +140,8 @@ public:
|
||||
|
||||
void closeEvent(QCloseEvent* close_event) override;
|
||||
|
||||
void listen();
|
||||
|
||||
protected slots:
|
||||
|
||||
void onOpenFileClicked(bool);
|
||||
@ -128,10 +157,21 @@ protected slots:
|
||||
void onExpandAllClicked(bool);
|
||||
void onCollapseAllClicked(bool);
|
||||
void onFileReaderTimeout();
|
||||
void onDownloadTimeout();
|
||||
void onFileReaderCancel();
|
||||
void onEditBlocksClicked(bool);
|
||||
void onDescTreeDialogClose(int);
|
||||
void onCaptureClicked(bool);
|
||||
|
||||
void readTcpData();
|
||||
void onNewConnection();
|
||||
void onDisconnection();
|
||||
void onConnected();
|
||||
void onErrorConnection(QAbstractSocket::SocketError socketError);
|
||||
void onDisconnect();
|
||||
void onConnectClicked(bool);
|
||||
|
||||
void handleResults(const QString &s);
|
||||
private:
|
||||
|
||||
// Private non-virtual methods
|
||||
@ -142,6 +182,9 @@ private:
|
||||
void loadGeometry();
|
||||
void saveSettingsAndGeometry();
|
||||
|
||||
bool m_isClientPreparedBlocks = false;
|
||||
bool m_isClientCaptured = false;
|
||||
|
||||
}; // END of class EasyMainWindow.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -189,8 +189,12 @@ int main(int argc, char* argv[])
|
||||
auto start = std::chrono::system_clock::now();
|
||||
EASY_PROFILER_ENABLE;
|
||||
EASY_MAIN_THREAD;
|
||||
|
||||
profiler::startListenSignalToCapture();
|
||||
//one();
|
||||
//one();
|
||||
/**/
|
||||
std::vector<std::thread> threads;
|
||||
|
||||
std::thread render = std::thread(renderThread);
|
||||
std::thread modelling = std::thread(modellingThread);
|
||||
|
||||
@ -227,5 +231,7 @@ int main(int argc, char* argv[])
|
||||
|
||||
std::cout << "Blocks count: " << blocks_count << std::endl;
|
||||
|
||||
|
||||
profiler::stopListenSignalToCapture();
|
||||
return 0;
|
||||
}
|
||||
|
@ -5,11 +5,14 @@ set(CPP_FILES
|
||||
profile_manager.cpp
|
||||
reader.cpp
|
||||
event_trace_win.cpp
|
||||
easy_socket.cpp
|
||||
)
|
||||
|
||||
set(H_FILES
|
||||
${ROOT}/include/profiler/profiler.h
|
||||
${ROOT}/include/profiler/reader.h
|
||||
${ROOT}/include/profiler/easy_net.h
|
||||
${ROOT}/include/profiler/easy_socket.h
|
||||
profile_manager.h
|
||||
spin_lock.h
|
||||
event_trace_win.h
|
||||
@ -22,5 +25,11 @@ set(SOURCES
|
||||
add_definitions(
|
||||
-D_BUILD_PROFILER
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} SHARED ${SOURCES})
|
||||
|
||||
if(UNIX)
|
||||
set(PLATFORM_LIBS pthread)
|
||||
endif(UNIX)
|
||||
|
||||
target_link_libraries(${PROJECT_NAME} ${PLATFORM_LIBS})
|
||||
|
@ -1,35 +1,35 @@
|
||||
/************************************************************************
|
||||
* file name : event_trace_win.cpp
|
||||
* ----------------- :
|
||||
* creation time : 2016/09/04
|
||||
* author : Victor Zarubkin
|
||||
* email : v.s.zarubkin@gmail.com
|
||||
* ----------------- :
|
||||
* description : The file contains implementation of EasyEventTracer class used for tracing
|
||||
* : Windows system events to get context switches.
|
||||
* ----------------- :
|
||||
* change log : * 2016/09/04 Victor Zarubkin: initial commit.
|
||||
* :
|
||||
* : * 2016/09/13 Victor Zarubkin: get process id and process name
|
||||
* : of the owner of thread with id == CSwitch::NewThreadId.
|
||||
* :
|
||||
* : * 2016/09/17 Victor Zarubkin: added log messages printing.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : This program is free software : you can redistribute it and / or modify
|
||||
* : it under the terms of the GNU General Public License as published by
|
||||
* : the Free Software Foundation, either version 3 of the License, or
|
||||
* : (at your option) any later version.
|
||||
* :
|
||||
* : This program is distributed in the hope that it will be useful,
|
||||
* : but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* : GNU General Public License for more details.
|
||||
* :
|
||||
* : You should have received a copy of the GNU General Public License
|
||||
* : along with this program.If not, see <http://www.gnu.org/licenses/>.
|
||||
/************************************************************************
|
||||
* file name : event_trace_win.cpp
|
||||
* ----------------- :
|
||||
* creation time : 2016/09/04
|
||||
* author : Victor Zarubkin
|
||||
* email : v.s.zarubkin@gmail.com
|
||||
* ----------------- :
|
||||
* description : The file contains implementation of EasyEventTracer class used for tracing
|
||||
* : Windows system events to get context switches.
|
||||
* ----------------- :
|
||||
* change log : * 2016/09/04 Victor Zarubkin: initial commit.
|
||||
* :
|
||||
* : * 2016/09/13 Victor Zarubkin: get process id and process name
|
||||
* : of the owner of thread with id == CSwitch::NewThreadId.
|
||||
* :
|
||||
* : * 2016/09/17 Victor Zarubkin: added log messages printing.
|
||||
* ----------------- :
|
||||
* license : Lightweight profiler library for c++
|
||||
* : Copyright(C) 2016 Sergey Yagovtsev, Victor Zarubkin
|
||||
* :
|
||||
* : This program is free software : you can redistribute it and / or modify
|
||||
* : it under the terms of the GNU General Public License as published by
|
||||
* : the Free Software Foundation, either version 3 of the License, or
|
||||
* : (at your option) any later version.
|
||||
* :
|
||||
* : This program is distributed in the hope that it will be useful,
|
||||
* : but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
|
||||
* : GNU General Public License for more details.
|
||||
* :
|
||||
* : You should have received a copy of the GNU General Public License
|
||||
* : along with this program.If not, see <http://www.gnu.org/licenses/>.
|
||||
************************************************************************/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -35,7 +35,8 @@
|
||||
|
||||
#define INITGUID // This is to enable using SystemTraceControlGuid in evntrace.h.
|
||||
#include <Windows.h>
|
||||
//#include <Strsafe.h>
|
||||
#include <Strsafe.h>
|
||||
#include <Shellapi.h>
|
||||
#include <wmistr.h>
|
||||
#include <evntrace.h>
|
||||
#include <evntcons.h>
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,9 @@ along with this program.If not, see <http://www.gnu.org/licenses/>.
|
||||
#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"
|
||||
@ -29,6 +32,8 @@ along with this program.If not, see <http://www.gnu.org/licenses/>.
|
||||
#include <unordered_map>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <string.h>
|
||||
#include <thread>
|
||||
#include <atomic>
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@ -213,12 +218,12 @@ public:
|
||||
do {
|
||||
const int8_t* data = current->data;
|
||||
uint16_t i = 0;
|
||||
do {
|
||||
while (i + 1 < N && *(uint16_t*)data != 0) {
|
||||
const uint16_t size = sizeof(uint16_t) + *(uint16_t*)data;
|
||||
_outputStream.write((const char*)data, size);
|
||||
data = data + size;
|
||||
i += size;
|
||||
} while (i + 1 < N && *(uint16_t*)data != 0);
|
||||
}
|
||||
current = current->prev;
|
||||
} while (current != nullptr);
|
||||
|
||||
@ -336,6 +341,13 @@ class ProfileManager final
|
||||
uint32_t dumpBlocksToStream(profiler::OStream& _outputStream);
|
||||
void setBlockEnabled(profiler::block_id_t _id, const profiler::hashed_stdstring& _key, bool _enabled);
|
||||
|
||||
std::thread m_listenThread;
|
||||
bool m_isAlreadyListened = false;
|
||||
void startListen();
|
||||
|
||||
int m_socket = 0;//TODO crossplatform
|
||||
|
||||
std::atomic_bool m_stopListen;
|
||||
public:
|
||||
|
||||
static ProfileManager& instance();
|
||||
@ -389,7 +401,8 @@ public:
|
||||
void beginContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _time, profiler::thread_id_t _target_thread_id, const char* _target_process, bool _lockSpin = true);
|
||||
void storeContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _time, profiler::thread_id_t _target_thread_id, bool _lockSpin = true);
|
||||
void endContextSwitch(profiler::thread_id_t _thread_id, profiler::timestamp_t _endtime, bool _lockSpin = true);
|
||||
|
||||
void startListenSignalToCapture();
|
||||
void stopListenSignalToCapture();
|
||||
private:
|
||||
|
||||
void markExpired(profiler::block_id_t _id);
|
||||
|
1030
src/reader.cpp
1030
src/reader.cpp
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user