summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBernd Weimer <bernd.weimer@pelagicore.com>2019-10-18 12:30:42 +0200
committerBernd Weimer <bernd.weimer@pelagicore.com>2019-11-14 09:35:27 +0100
commit5828dc7a0dabbc8e0ae1414c0bdf18659aac6111 (patch)
tree54cd2709bf6c6250ba57e63d8751de61800c8118
parent689905b4b45349ba9f376d4814851afba4a34165 (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.cpp56
-rw-r--r--src/monitor-lib/processreader.h4
-rw-r--r--src/monitor-lib/processstatus.cpp66
-rw-r--r--src/monitor-lib/processstatus.h11
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