fix(memory): Implement memory updating for pre-3.4 kernels ()

Since 3.4, `/proc/meminfo` contains a `MemAvailable` field, which polybar uses to determine
`(gb|mb)_free` and `(gb|mb)_used`. This commit adds a fallback for when `MemAvailable` does
not exist, allowing a fairly-accurate approximation on older kernels.

This commit also removes the reliance on the exact order fields appear in `/proc/meminfo`.
This commit is contained in:
Tudor Brindus 2017-02-04 12:19:58 -05:00 committed by Michael Carlberg
parent 9ced7dbf73
commit 107bdb91e3

View file

@ -33,25 +33,34 @@ namespace modules {
bool memory_module::update() { bool memory_module::update() {
unsigned long long kb_total{0ULL}; unsigned long long kb_total{0ULL};
unsigned long long kb_avail{0ULL}; unsigned long long kb_avail{0ULL};
unsigned long long kb_free{0ULL};
try { try {
std::ifstream in(PATH_MEMORY_INFO); std::ifstream meminfo(PATH_MEMORY_INFO);
std::stringstream buffer; std::map<std::string, unsigned long long int> parsed;
string str;
buffer.imbue(std::locale::classic()); std::string line;
while (std::getline(meminfo, line)) {
size_t sep_off = line.find(':');
size_t value_off = line.find_first_of("123456789", sep_off);
for (int i = 3; i > 0 && std::getline(in, str); i--) { if (sep_off == std::string::npos || value_off == std::string::npos) continue;
size_t off = str.find_first_of("1234567890", str.find(':'));
if (off != string::npos && str.size() > off) { std::string id = line.substr(0, sep_off);
buffer << std::strtoull(&str[off], nullptr, 10) << std::endl; unsigned long long int value = std::strtoull(&line[value_off], nullptr, 10);
} parsed[id] = value;
} }
buffer >> kb_total; kb_total = parsed["MemTotal"];
buffer >> kb_free;
buffer >> kb_avail; // newer kernels (3.4+) have an accurate available memory field,
// see https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=34e431b0ae398fc54ea69ff85ec700722c9da773
// for details
if (parsed.count("MemAvailable")) {
kb_avail = parsed["MemAvailable"];
} else {
// old kernel; give a best-effort approximation of available memory
kb_avail = parsed["MemFree"] + parsed["Buffers"] + parsed["Cached"] + parsed["SReclaimable"] - parsed["Shmem"];
}
} catch (const std::exception& err) { } catch (const std::exception& err) {
m_log.err("Failed to read memory values (what: %s)", err.what()); m_log.err("Failed to read memory values (what: %s)", err.what());
} }