diff options
author | Bernd Weimer <bernd.weimer@pelagicore.com> | 2019-10-18 12:30:42 +0200 |
---|---|---|
committer | Bernd Weimer <bernd.weimer@pelagicore.com> | 2019-11-14 09:35:27 +0100 |
commit | 5828dc7a0dabbc8e0ae1414c0bdf18659aac6111 (patch) | |
tree | 54cd2709bf6c6250ba57e63d8751de61800c8118 | |
parent | 689905b4b45349ba9f376d4814851afba4a34165 (diff) |
Fix issues in ProcessStatus
- Moved smaps parsing to dedicated thread
- Made memory reporting optional
- Support CPU loads greater than 1.0
Cherry-picked from 5.13: 7092e70
Task-number: AUTOSUITE-1310
Change-Id: Ib7940911fbeaa92964af26302164d4fa33821daf
Reviewed-by: Robert Griebl <robert.griebl@qt.io>
-rw-r--r-- | src/monitor-lib/processreader.cpp | 56 | ||||
-rw-r--r-- | src/monitor-lib/processreader.h | 4 | ||||
-rw-r--r-- | src/monitor-lib/processstatus.cpp | 66 | ||||
-rw-r--r-- | src/monitor-lib/processstatus.h | 11 |
4 files changed, 100 insertions, 37 deletions
diff --git a/src/monitor-lib/processreader.cpp b/src/monitor-lib/processreader.cpp index b89e9b3c..e8b760a9 100644 --- a/src/monitor-lib/processreader.cpp +++ b/src/monitor-lib/processreader.cpp @@ -50,14 +50,6 @@ # include <unistd.h> #endif -namespace { - static uint parseValue(const char *pl) { - while (*pl && (*pl < '0' || *pl > '9')) - pl++; - return static_cast<uint>(strtoul(pl, nullptr, 10)); - } -} - QT_USE_NAMESPACE_AM void ProcessReader::setProcessId(qint64 pid) @@ -67,32 +59,36 @@ void ProcessReader::setProcessId(qint64 pid) openCpuLoad(); } +void ProcessReader::enableMemoryReporting(bool enabled) +{ + m_memoryReportingEnabled = enabled; + if (!m_memoryReportingEnabled) + zeroMemory(); +} + void ProcessReader::update() { - // read cpu - { - qreal cpuLoadFloat = readCpuLoad(); - quint32 value = ((qreal)std::numeric_limits<quint32>::max()) * cpuLoadFloat; - cpuLoad.store(value); - } + cpuLoad.store(static_cast<quint32>(cpuLoadFactor * readCpuLoad())); - { - if (!readMemory()) { - totalVm.store(0); - totalRss.store(0); - totalPss.store(0); - textVm.store(0); - textRss.store(0); - textPss.store(0); - heapVm.store(0); - heapRss.store(0); - heapPss.store(0); - } - } + if (m_memoryReportingEnabled && !readMemory()) + zeroMemory(); emit updated(); } +void ProcessReader::zeroMemory() +{ + totalVm.store(0); + totalRss.store(0); + totalPss.store(0); + textVm.store(0); + textRss.store(0); + textPss.store(0); + heapVm.store(0); + heapRss.store(0); + heapPss.store(0); +} + #if defined(Q_OS_LINUX) void ProcessReader::openCpuLoad() @@ -144,6 +140,12 @@ bool ProcessReader::readMemory() return readSmaps(smapsFile); } +static uint parseValue(const char *pl) { + while (*pl && (*pl < '0' || *pl > '9')) + pl++; + return static_cast<uint>(strtoul(pl, nullptr, 10)); +} + bool ProcessReader::readSmaps(const QByteArray &smapsFile) { quint32 _totalVm = 0; diff --git a/src/monitor-lib/processreader.h b/src/monitor-lib/processreader.h index 029292a6..e449a62d 100644 --- a/src/monitor-lib/processreader.h +++ b/src/monitor-lib/processreader.h @@ -60,6 +60,7 @@ class ProcessReader : public QObject { public slots: void update(); void setProcessId(qint64 pid); + void enableMemoryReporting(bool enabled); signals: void updated(); @@ -81,11 +82,13 @@ public: // it's public solely for testing purposes bool readSmaps(const QByteArray &smapsFile); #endif + static constexpr qreal cpuLoadFactor = 1000000.0; private: void openCpuLoad(); qreal readCpuLoad(); bool readMemory(); + void zeroMemory(); #if defined(Q_OS_LINUX) QScopedPointer<SysFsReader> m_statReader; @@ -94,6 +97,7 @@ private: quint64 m_lastCpuUsage = 0.0; qint64 m_pid = 0; + bool m_memoryReportingEnabled = true; }; QT_END_NAMESPACE_AM diff --git a/src/monitor-lib/processstatus.cpp b/src/monitor-lib/processstatus.cpp index efb2a9c0..341f50af 100644 --- a/src/monitor-lib/processstatus.cpp +++ b/src/monitor-lib/processstatus.cpp @@ -123,25 +123,53 @@ \endtable */ +/*! + \qmlsignal ProcessStatus::memoryReportingChanged(memoryVirtual, memoryRss, memoryPss) + + This signal is emitted after \l{ProcessStatus::update()}{update()} has been called and the + memory usage values have been refreshed. The arguments are key-value pairs with the keys listed + in the table \l{supported-keys}{above}. +*/ + + QT_USE_NAMESPACE_AM QThread *ProcessStatus::m_workerThread = nullptr; +int ProcessStatus::m_instanceCount = 0; ProcessStatus::ProcessStatus(QObject *parent) : QObject(parent) { - if (!m_workerThread) { + if (m_instanceCount == 0) { m_workerThread = new QThread; m_workerThread->start(); } + ++m_instanceCount; + + m_reader = new ProcessReader; + m_reader->moveToThread(m_workerThread); - m_reader.reset(new ProcessReader); - connect(m_reader.data(), &ProcessReader::updated, this, [this]() { + connect(m_reader, &ProcessReader::updated, this, [this]() { emit cpuLoadChanged(); fetchMemoryReadings(); + emit memoryReportingChanged(m_memoryVirtual, m_memoryRss, m_memoryPss); m_pendingUpdate = false; }); - connect(this, &ProcessStatus::processIdChanged, m_reader.data(), &ProcessReader::setProcessId); + connect(this, &ProcessStatus::processIdChanged, m_reader, &ProcessReader::setProcessId); + connect(this, &ProcessStatus::memoryReportingEnabledChanged, m_reader, &ProcessReader::enableMemoryReporting); +} + +ProcessStatus::~ProcessStatus() +{ + m_reader->deleteLater(); + + --m_instanceCount; + if (m_instanceCount == 0) { + m_workerThread->quit(); + m_workerThread->wait(); + delete m_workerThread; + m_workerThread = nullptr; + } } /*! @@ -153,7 +181,7 @@ void ProcessStatus::update() { if (!m_pendingUpdate) { m_pendingUpdate = true; - QMetaObject::invokeMethod(m_reader.data(), &ProcessReader::update); + QMetaObject::invokeMethod(m_reader, &ProcessReader::update); } } @@ -243,8 +271,7 @@ qint64 ProcessStatus::processId() const */ qreal ProcessStatus::cpuLoad() { - quint32 value = m_reader->cpuLoad.load(); - return ((qreal)value) / ((qreal)std::numeric_limits<quint32>::max()); + return m_reader->cpuLoad.load() / ProcessReader::cpuLoadFactor; } void ProcessStatus::fetchMemoryReadings() @@ -259,8 +286,6 @@ void ProcessStatus::fetchMemoryReadings() m_memoryPss[qSL("total")] = quint64(m_reader->totalPss.load()) << 10; m_memoryPss[qSL("text")] = quint64(m_reader->textPss.load()) << 10; m_memoryPss[qSL("heap")] = quint64(m_reader->heapPss.load()) << 10; - - emit memoryReportingChanged(m_memoryVirtual, m_memoryRss, m_memoryPss); } /*! @@ -317,6 +342,29 @@ QVariantMap ProcessStatus::memoryPss() const } /*! + \qmlproperty bool ProcessStatus::memoryReportingEnabled + + A boolean value that determines whether the memory properties are refreshed each time + \l{ProcessStatus::update()}{update()} is called. The default value is \c true. In your System + UI, the process of determining memory consumption adds additional load to the CPU, affecting + the \c cpuLoad value. If \c cpuLoad needs to be kept accurate, consider disabling memory + reporting. +*/ + +bool ProcessStatus::isMemoryReportingEnabled() const +{ + return m_memoryReportingEnabled; +} + +void ProcessStatus::setMemoryReportingEnabled(bool enabled) +{ + if (enabled != m_memoryReportingEnabled) { + m_memoryReportingEnabled = enabled; + emit memoryReportingEnabledChanged(m_memoryReportingEnabled); + } +} + +/*! \qmlproperty list<string> ProcessStatus::roleNames \readonly diff --git a/src/monitor-lib/processstatus.h b/src/monitor-lib/processstatus.h index b233aced..282ad13f 100644 --- a/src/monitor-lib/processstatus.h +++ b/src/monitor-lib/processstatus.h @@ -66,9 +66,12 @@ class ProcessStatus : public QObject Q_PROPERTY(QVariantMap memoryVirtual READ memoryVirtual NOTIFY memoryReportingChanged) Q_PROPERTY(QVariantMap memoryRss READ memoryRss NOTIFY memoryReportingChanged) Q_PROPERTY(QVariantMap memoryPss READ memoryPss NOTIFY memoryReportingChanged) + Q_PROPERTY(bool memoryReportingEnabled READ isMemoryReportingEnabled WRITE setMemoryReportingEnabled + NOTIFY memoryReportingEnabledChanged) Q_PROPERTY(QStringList roleNames READ roleNames CONSTANT) public: ProcessStatus(QObject *parent = nullptr); + ~ProcessStatus(); QStringList roleNames() const; @@ -84,12 +87,16 @@ public: QVariantMap memoryRss() const; QVariantMap memoryPss() const; + bool isMemoryReportingEnabled() const; + void setMemoryReportingEnabled(bool enabled); + signals: void applicationIdChanged(const QString &applicationId); void processIdChanged(qint64 processId); void cpuLoadChanged(); void memoryReportingChanged(const QVariantMap &memoryVirtual, const QVariantMap &memoryRss, const QVariantMap &memoryPss); + void memoryReportingEnabledChanged(bool enabled); private slots: void onRunStateChanged(Am::RunState state); @@ -104,12 +111,14 @@ private: QVariantMap m_memoryVirtual; QVariantMap m_memoryRss; QVariantMap m_memoryPss; + bool m_memoryReportingEnabled = true; QPointer<AbstractApplication> m_application; bool m_pendingUpdate = false; - QScopedPointer<ProcessReader> m_reader; + ProcessReader *m_reader; static QThread *m_workerThread; + static int m_instanceCount; }; QT_END_NAMESPACE_AM |