diff options
Diffstat (limited to 'tests/manual/x11vkbtest/memorymonitor.cpp')
-rw-r--r-- | tests/manual/x11vkbtest/memorymonitor.cpp | 226 |
1 files changed, 226 insertions, 0 deletions
diff --git a/tests/manual/x11vkbtest/memorymonitor.cpp b/tests/manual/x11vkbtest/memorymonitor.cpp new file mode 100644 index 00000000..db1b53b9 --- /dev/null +++ b/tests/manual/x11vkbtest/memorymonitor.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "memorymonitor.h" + +#include <QtCharts/QAbstractAxis> +#include <QtCharts/QSplineSeries> +#include <QtCharts/QValueAxis> +#include <QtCore/QRandomGenerator> +#include <QLoggingCategory> + +#include <QMainWindow> +#include <QWindow> +#include <QScreen> +#include <QDir> + +#include <QTime> + +extern "C" { +#include <unistd.h> +#include <sys/resource.h> +} +#include <cstdio> + +namespace { +const QString KChartFileName = "MemoryUsageChart"; +const quint8 KYPosition = 15; +const quint8 KReadingMargin = 80; +const quint16 KToKilo = 1024; +} + +Q_LOGGING_CATEGORY(lcMemoryMonitor, "qt.virtualkeyboard.tests.manual.x11vkbtest.memorymonitor") + +MemoryMonitor::MemoryMonitor(QMainWindow &window, QGraphicsItem *parent, Qt::WindowFlags wFlags) : + QChart(QChart::ChartTypeCartesian, parent, wFlags), + m_series(nullptr), + m_axisX(new QValueAxis()), + m_axisY(new QValueAxis()), + m_x(0), + m_y(0), + m_peakMemory(0), + m_minMemory(0), + m_procID(0), + m_MainWindow(window), + m_screen(nullptr), + m_drawInterval(new QTimer()), + m_elapsedTime(0), + m_minMemReading(nullptr), + m_curMemReading(nullptr), + m_peakMemReading(nullptr), + m_elapsedTimeReading(nullptr) +{ + m_series = new QSplineSeries(this); + QPen red(Qt::red); + red.setWidth(3); + m_series->setPen(red); + + this->addSeries(m_series); + + this->addAxis(m_axisX,Qt::AlignBottom); + m_axisX->setTitleText("Time"); + this->addAxis(m_axisY,Qt::AlignLeft); + m_axisY->setTitleText("Memory KB"); + m_series->attachAxis(m_axisX); + m_series->attachAxis(m_axisY); + m_axisX->setTickCount(15); + m_axisX->setLabelFormat("%.1u"); + m_axisY->setTickCount(15); + m_axisY->setLabelFormat("%.1u"); + m_axisX->setRange(0, 500); + m_axisY->setRange(0, 100 * KToKilo); +} + +void MemoryMonitor::init() +{ + QWindow *win = m_MainWindow.windowHandle(); + m_screen = win->screen(); + + m_minMemReading = new QGraphicsSimpleTextItem(this); + m_minMemReading->setPen(QPen(QBrush("black"), 1)); + m_minMemReading->setText("Min mem ----- KB"); + m_minMemReading->setPos(KReadingMargin, KYPosition); + + m_curMemReading = new QGraphicsSimpleTextItem(this); + m_curMemReading->setPen(QPen(QBrush("black"), 1)); + m_curMemReading->setText("Current mem ----- KB"); + m_curMemReading->setPos((this->size().width() / 2) - KReadingMargin, KYPosition); + + m_peakMemReading = new QGraphicsSimpleTextItem(this); + m_peakMemReading->setPen(QPen(QBrush("black"), 1)); + m_peakMemReading->setText("Peak mem ----- KB"); + m_peakMemReading->setPos(this->size().width() - (KReadingMargin * 2), KYPosition); + + m_elapsedTimeReading = new QGraphicsSimpleTextItem(this); + m_elapsedTimeReading->setPen(QPen(QBrush("black"), 1)); + m_elapsedTimeReading->setText("-- s"); + m_elapsedTimeReading->setPos((this->size().width() / 2) + KReadingMargin, this->size().height() - KYPosition * 3); + + QObject::connect(this, &QChart::geometryChanged, [this]() { + m_minMemReading->setPos(KReadingMargin, KYPosition); + m_curMemReading->setPos((this->size().width() / 2) - KReadingMargin, KYPosition); + m_peakMemReading->setPos(this->size().width() - (KReadingMargin * 2), KYPosition); + m_elapsedTimeReading->setPos((this->size().width() / 2) + KReadingMargin, this->size().height() - KYPosition * 3); + }); +} + +void MemoryMonitor::setProcID(const qint64 procID) +{ + m_procID = procID; +} + +void MemoryMonitor::start() +{ + QObject::connect(m_drawInterval, &QTimer::timeout, [&]() { + ulong memUsed = currentMemUsage(); + this->drawMemUsage(memUsed); + this->storeMemValues(memUsed); + }); + m_drawInterval->setInterval(1000); + m_drawInterval->start(); +} + +/** + * @brief currentMemUsage + * @param procID + * @return current memory by procID in kB + * Getting memory usage of a given process using + * Linux proc filesystem. + */ +ulong MemoryMonitor::currentMemUsage() +{ + ulong memSize = 0UL; + QString str = QString("/proc/" + QString::number(m_procID) + "/statm"); + QFile procFile(str); + + if (procFile.open(QIODevice::ReadOnly)) { + QTextStream procStream(&procFile); + ulong mem = procStream.readLine().split(" ").at(1).toULong(); + memSize = mem * static_cast<ulong>(sysconf(_SC_PAGESIZE)); + procFile.close(); + } + auto result = memSize / KToKilo; + qCDebug(lcMemoryMonitor).noquote() << QTime::currentTime().toString() << "memory usage:" << result; + + emit memUsage(m_elapsedTime, result); + + return result; +} + +MemoryMonitor::~MemoryMonitor() +{ + qCDebug(lcMemoryMonitor) << "Destroying MemoryChart"; +} + +void MemoryMonitor::saveChart() +{ + QPixmap pix = m_screen->grabWindow(m_MainWindow.winId()); + + const QString format = "png"; + QString path = QDir::currentPath(); + path += "/" + KChartFileName + "." + format; + pix.save(path); +} + +void MemoryMonitor::stopChart() +{ + this->saveChart(); + m_drawInterval->stop(); + + emit minAndPeakReport(QString("Min process memory: %1 KB\nPeak process memory: %2 KB") + .arg(QString::number(m_minMemory)) + .arg(QString::number(m_peakMemory))); +} + +void MemoryMonitor::storeMemValues(const ulong memValue) +{ + if ((m_minMemory == 0 || m_minMemory > memValue)) { + m_minMemory = memValue; + } + if (m_peakMemory < memValue) { + m_peakMemory = memValue; + } + m_minMemReading->setText(QString("Min mem %1 KB").arg(QString::number(m_minMemory))); + m_curMemReading->setText(QString("Current mem %1 KB").arg(QString::number(memValue))); + m_peakMemReading->setText(QString("Peak mem %1 KB").arg(QString::number(m_peakMemory))); + m_elapsedTimeReading->setText(QString("%1 s").arg(m_elapsedTime += 1)); +} + +void MemoryMonitor::drawMemUsage(const ulong memUsed) +{ + m_x += 1; + m_y = memUsed; + if (m_y >= m_axisY->max()) { + m_axisY->setRange(0, (m_axisY->max() * 2)); + } + if (m_x >= m_axisX->max()) { + m_axisX->setRange(0, (m_axisX->max() * 2)); + } + m_series->append(m_x, m_y); +} |