#include "memory.hpp" #include #include #include namespace ZShell::services { Memory::Memory(QObject* parent) : TickingService(parent) {} qreal Memory::used() const { return m_used; } qreal Memory::total() const { return m_total; } qreal Memory::cached() const { return m_cached; } qreal Memory::readTotal() const { return m_readTotal; } qreal Memory::writeTotal() const { return m_writeTotal; } qreal Memory::percentage() const { return m_total > 0.0 ? m_used / m_total : 0.0; } void Memory::tick() { QFile f(QStringLiteral("/proc/meminfo")); if (!f.open(QIODevice::ReadOnly | QIODevice::Text)) { return; } const QByteArray data = f.readAll(); f.close(); static const QRegularExpression reTotal( QStringLiteral("MemTotal: *(\\d+)")); static const QRegularExpression reAvail( QStringLiteral("MemAvailable: *(\\d+)")); static const QRegularExpression reCached(QStringLiteral( "Cached: *(\\d+)")); const QString text = QString::fromLatin1(data); const auto totalMatch = reTotal.match(text); const auto availMatch = reAvail.match(text); if (!totalMatch.hasMatch() || !availMatch.hasMatch()) { return; } const quint64 totalKib = totalMatch.captured(1).toULongLong(); const quint64 availKib = availMatch.captured(1).toULongLong(); if (totalKib == 0) { return; } const quint64 usedKib = totalKib > availKib ? totalKib - availKib : 0; const auto cachedMatch = reCached.match(text); const quint64 cachedKib = cachedMatch.hasMatch() ? cachedMatch.captured(1).toULongLong() : 0; static const QRegularExpression rePgin(QStringLiteral("pgpgin (\\d+)")); static const QRegularExpression rePgout(QStringLiteral("pgpgout (\\d+)")); quint64 readKib = 0; quint64 writeKib = 0; { QFile vf(QStringLiteral("/proc/vmstat")); if (vf.open(QIODevice::ReadOnly | QIODevice::Text)) { const QString vtext = QString::fromLatin1(vf.readAll()); vf.close(); const double pageKib = getpagesize() / 1024.0; const auto pgin = rePgin.match(vtext); const auto pgout = rePgout.match(vtext); if (pgin.hasMatch()) { readKib = static_cast(static_cast( pgin.captured(1).toULongLong()) * pageKib); } if (pgout.hasMatch()) { writeKib = static_cast(static_cast( pgout.captured(1).toULongLong()) * pageKib); } } } if (totalKib == m_lastTotal && usedKib == m_lastUsed && cachedKib == m_lastCached && readKib == m_lastReadKib && writeKib == m_lastWriteKib) { return; } m_lastTotal = totalKib; m_lastUsed = usedKib; m_lastCached = cachedKib; m_lastReadKib = readKib; m_lastWriteKib = writeKib; m_total = static_cast(totalKib); m_used = static_cast(usedKib); m_cached = static_cast(cachedKib); m_readTotal = static_cast(readKib); m_writeTotal = static_cast(writeKib); Q_EMIT changed(); } } // namespace ZShell::services