Skip to content

Commit

Permalink
Record perf data by launching an application
Browse files Browse the repository at this point in the history
Version 1.0 of the perf record GUI functionality.

Issue: KDAB#11
  • Loading branch information
nwrogers committed Jun 29, 2017
1 parent 1b0abce commit 1c3c44a
Show file tree
Hide file tree
Showing 7 changed files with 336 additions and 20 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ if(Qt5_FOUND AND ECM_FOUND)
CoreAddons
ItemViews
ItemModels
KIO
Solid
REQUIRED
)
endif()
Expand Down
5 changes: 5 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ target_link_libraries(hotspot
KF5::ConfigWidgets
KF5::ItemViews
KF5::ItemModels
KF5::KIOCore
KF5::KIOFileWidgets
KF5::KIOWidgets
KF5::KIONTLM
KF5::Solid
models
)

Expand Down
111 changes: 108 additions & 3 deletions src/mainwindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,16 @@
#include <KFormat>
#include <KConfigGroup>
#include <KRecentFilesAction>
#include <KUrlRequester>
#include <Solid/Device>
#include <Solid/Processor>
#include <KShell>

#include "aboutdialog.h"
#include "flamegraph.h"

#include "parsers/perf/perfparser.h"
#include "perfrecord.h"

#include "models/summarydata.h"
#include "models/hashmodel.h"
Expand Down Expand Up @@ -164,19 +169,47 @@ static const IdeSettings ideSettings[] = {
#else
static const int ideSettingsSize = sizeof(ideSettings) / sizeof(IdeSettings);
#endif

bool isIntel()
{
QList<Solid::Device> list = Solid::Device::listFromType(Solid::DeviceInterface::Processor, QString());
Solid::Device device = list[0];
if(!device.is<Solid::Processor>()) {
return false;
}
Solid::Processor *processor = device.as<Solid::Processor>();

return processor->instructionSets().testFlag(Solid::Processor::IntelMmx) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSse) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSse2) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSse3) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSsse3) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSse4) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSse41) ||
processor->instructionSets().testFlag(Solid::Processor::IntelSse42);
}
}

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_parser(new PerfParser(this)),
m_config(KSharedConfig::openConfig())
m_config(KSharedConfig::openConfig()),
m_perfRecord(new PerfRecord(this))
{
ui->setupUi(this);

ui->lostMessage->setVisible(false);
ui->parserErrorsBox->setVisible(false);
ui->fileMenu->addAction(KStandardAction::open(this, SLOT(on_openFileButton_clicked()), this));

QAction* recordDataAction = new QAction(this);
recordDataAction->setText(QStringLiteral("&Record Data"));
recordDataAction->setIcon(QIcon::fromTheme(QStringLiteral("media-record")));
recordDataAction->setShortcut(Qt::CTRL + Qt::Key_R);
ui->fileMenu->addAction(recordDataAction);
connect(recordDataAction, &QAction::triggered, this, &MainWindow::onRecordDataButtonClicked);

ui->fileMenu->addAction(KStandardAction::open(this, SLOT(onOpenFileButtonClicked()), this));
m_recentFilesAction = KStandardAction::openRecent(this, SLOT(openFile(QUrl)), this);
m_recentFilesAction->loadEntries(m_config->group("RecentFiles"));
ui->fileMenu->addAction(m_recentFilesAction);
Expand All @@ -191,6 +224,21 @@ MainWindow::MainWindow(QWidget *parent) :

ui->mainPageStack->setCurrentWidget(ui->startPage);
ui->openFileButton->setFocus();
ui->workingDirectory->setMode(KFile::Directory);
ui->applicationRecordErrorLabel->hide();
connect(ui->openFileButton, &QPushButton::clicked, this, &MainWindow::onOpenFileButtonClicked);
connect(ui->recordDataButton, &QPushButton::clicked, this, &MainWindow::onRecordDataButtonClicked);
connect(ui->homeButton, &QPushButton::clicked, this, &MainWindow::onHomeButtonClicked);
connect(ui->applicationName, &KUrlRequester::textChanged, this, &MainWindow::onApplicationNameChanged);
connect(ui->startRecordingButton, &QPushButton::toggled, this, &MainWindow::onStartRecordingButtonClicked);

ui->recordTypeComboBox->addItem(tr("Launch Application"), QVariant::fromValue(LaunchApplication));
ui->callGraphComboBox->addItem(tr("None"), QVariant::fromValue(QStringLiteral("")));
ui->callGraphComboBox->addItem(tr("DWARF"), QVariant::fromValue(QStringLiteral("dwarf")));
ui->callGraphComboBox->addItem(tr("Frame Pointer"), QVariant::fromValue(QStringLiteral("fp")));
if (isIntel()) {
ui->callGraphComboBox->addItem(tr("Last Branch Record"), QVariant::fromValue(QStringLiteral("lbr")));
}

auto bottomUpCostModel = new BottomUpModel(this);
setupTreeView(ui->bottomUpTreeView, ui->bottomUpSearch, bottomUpCostModel);
Expand Down Expand Up @@ -362,6 +410,21 @@ MainWindow::MainWindow(QWidget *parent) :
ui->resultsTabWidget->setTabToolTip(i, ui->resultsTabWidget->widget(i)->toolTip());
}

connect(m_perfRecord, &PerfRecord::recordingFinished,
this, [this] (const QString& fileLocation) {
ui->startRecordingButton->setChecked(false);
ui->applicationRecordErrorLabel->hide();
openFile(fileLocation);
});

connect(m_perfRecord, &PerfRecord::recordingFailed,
this, [this] (const QString& errorMessage) {
ui->startRecordingButton->setChecked(false);
ui->applicationRecordErrorLabel->setText(errorMessage);
ui->applicationRecordErrorLabel->show();

});

setupCodeNavigationMenu();
setupPathSettingsMenu();

Expand Down Expand Up @@ -402,7 +465,7 @@ void MainWindow::setArch(const QString& arch)
m_arch = arch;
}

void MainWindow::on_openFileButton_clicked()
void MainWindow::onOpenFileButtonClicked()
{
const auto fileName = QFileDialog::getOpenFileName(this, tr("Open File"), QDir::currentPath(),
tr("Data Files (*.data)"));
Expand All @@ -413,6 +476,48 @@ void MainWindow::on_openFileButton_clicked()
openFile(fileName);
}

void MainWindow::onRecordDataButtonClicked()
{
ui->mainPageStack->setCurrentWidget(ui->recordDataPage);
}

void MainWindow::onHomeButtonClicked()
{
ui->mainPageStack->setCurrentWidget(ui->startPage);
}

void MainWindow::onStartRecordingButtonClicked(bool checked)
{
if (checked) {
ui->startRecordingButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-stop")));
ui->startRecordingButton->setText(tr("Stop Recording"));

QStringList perfOptions;

if (!ui->callGraphComboBox->currentData().toString().isEmpty()) {
perfOptions << QStringLiteral("--call-graph") << ui->callGraphComboBox->currentData().toString();
}

if (!ui->eventTypeBox->text().isEmpty()) {
perfOptions << QStringLiteral("--event") << ui->eventTypeBox->text();
}

m_perfRecord->record(perfOptions, ui->workingDirectory->text() + QStringLiteral("/perf.data"),
ui->applicationName->text(), KShell::splitArgs(ui->applicationParametersBox->text()));
} else {
ui->startRecordingButton->setIcon(QIcon::fromTheme(QStringLiteral("media-playback-start")));
ui->startRecordingButton->setText(tr("Start Recording"));
m_perfRecord->stopRecording();
}
}

void MainWindow::onApplicationNameChanged(const QString& filePath)
{
if (ui->workingDirectory->text().isEmpty()) {
ui->workingDirectory->setPlaceholderText(QFileInfo(filePath).path());
}
}

void MainWindow::paintEvent(QPaintEvent* /*event*/)
{
if (ui->mainPageStack->currentWidget() == ui->resultsPage) {
Expand Down
25 changes: 24 additions & 1 deletion src/mainwindow.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,24 @@ class CallerCalleeModel;
class QSortFilterProxyModel;
class QTreeView;
class KRecentFilesAction;
class PerfRecord;

enum RecordType
{
LaunchApplication,
AttachToProcess,
ProfileSystem
};
Q_DECLARE_METATYPE(RecordType)

enum BacktraceType
{
None,
Dwarf,
FramePointer,
LastBranchRecord
};
Q_DECLARE_METATYPE(BacktraceType)

class MainWindow : public QMainWindow
{
Expand Down Expand Up @@ -75,7 +93,11 @@ public slots:
void aboutHotspot();

private slots:
void on_openFileButton_clicked();
void onOpenFileButtonClicked();
void onRecordDataButtonClicked();
void onHomeButtonClicked();
void onApplicationNameChanged(const QString& filePath);
void onStartRecordingButtonClicked(bool checked);

void customContextMenu(const QPoint &point, QTreeView* view, int symbolRole);
void onBottomUpContextMenu(const QPoint &pos);
Expand Down Expand Up @@ -106,4 +128,5 @@ private slots:
QPixmap m_background;
KRecentFilesAction* m_recentFilesAction = nullptr;
KSharedConfigPtr m_config;
PerfRecord* m_perfRecord;
};
Loading

0 comments on commit 1c3c44a

Please sign in to comment.