Files
fastfetch/src/detection/memory/memory_linux.c
T

102 lines
4.0 KiB
C
Raw Normal View History

#include "memory.h"
2026-01-06 09:48:38 +08:00
#include "common/io.h"
2026-03-29 09:28:49 +08:00
const char* ffDetectMemory(FFMemoryResult* ram) {
char buf[PROC_FILE_BUFFSIZ];
2024-10-18 16:15:48 +08:00
ssize_t nRead = ffReadFileData("/proc/meminfo", ARRAY_SIZE(buf) - 1, buf);
2026-03-29 09:28:49 +08:00
if (nRead < 0) {
2024-10-18 16:15:48 +08:00
return "ffReadFileData(\"/proc/meminfo\", ARRAY_SIZE(buf)-1, buf)";
2026-03-29 09:28:49 +08:00
}
buf[nRead] = '\0';
2023-11-24 10:12:34 +08:00
uint64_t memTotal = 0,
memAvailable = 0,
shmem = 0,
memFree = 0,
buffers = 0,
cached = 0,
2022-10-18 23:46:42 +08:00
sReclaimable = 0;
2026-07-10 18:08:04 +08:00
char* token = nullptr;
if ((token = memmem(buf, (size_t) nRead, "MemTotal:", strlen("MemTotal:"))) != nullptr) {
memTotal = (uint64_t) strtoull(token + strlen("MemTotal:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
} else {
return "MemTotal not found in /proc/meminfo";
2026-03-29 09:28:49 +08:00
}
2026-07-10 18:08:04 +08:00
if ((token = memmem(buf, (size_t) nRead, "MemAvailable:", strlen("MemAvailable:"))) != nullptr) {
memAvailable = (uint64_t) strtoull(token + strlen("MemAvailable:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
}
if (memAvailable == 0 || memAvailable >= memTotal) { // MemAvailable can be unreasonable. #1988
2026-07-10 18:08:04 +08:00
if ((token = memmem(buf, (size_t) nRead, "MemFree:", strlen("MemFree:"))) != nullptr) {
memFree = (uint64_t) strtoull(token + strlen("MemFree:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
}
2026-07-10 18:08:04 +08:00
if ((token = memmem(buf, (size_t) nRead, "Buffers:", strlen("Buffers:"))) != nullptr) {
buffers = (uint64_t) strtoull(token + strlen("Buffers:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
}
2026-07-10 18:08:04 +08:00
if ((token = memmem(buf, (size_t) nRead, "Cached:", strlen("Cached:"))) != nullptr) {
cached = (uint64_t) strtoull(token + strlen("Cached:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
}
2026-07-10 18:08:04 +08:00
if ((token = memmem(buf, (size_t) nRead, "Shmem:", strlen("Shmem:"))) != nullptr) {
shmem = (uint64_t) strtoull(token + strlen("Shmem:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
}
2026-07-10 18:08:04 +08:00
if ((token = memmem(buf, (size_t) nRead, "SReclaimable:", strlen("SReclaimable:"))) != nullptr) {
sReclaimable = (uint64_t) strtoull(token + strlen("SReclaimable:"), nullptr, 10);
2026-03-29 09:28:49 +08:00
}
memAvailable = memFree + buffers + cached + sReclaimable - shmem;
}
2023-11-24 10:12:34 +08:00
ram->bytesTotal = memTotal * 1024lu;
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
2023-05-11 20:39:54 +08:00
uint64_t arcSize = 0;
nRead = ffReadFileData("/proc/spl/kstat/zfs/arcstats", ARRAY_SIZE(buf) - 1, buf);
if (nRead > 0) {
buf[nRead] = '\0';
// 24 1 0x01 148 40256 2053603602 851614020716
// name type data
// hits 4 752
// Skip first line
const char* p = memchr(buf, '\n', (size_t) nRead);
2026-07-10 18:08:04 +08:00
if (__builtin_expect(p != nullptr, true)) {
++p;
nRead -= (p - buf);
assert(nRead > 0);
// Find line offset of data
const char* pData = memmem(p, (size_t) nRead, "data\n", strlen("data\n"));
2026-07-10 18:08:04 +08:00
if (__builtin_expect(pData != nullptr, true)) {
uint32_t dataOffset = (uint32_t) (pData - p);
p += dataOffset + strlen("data\n");
nRead -= (ssize_t) (dataOffset + strlen("data\n"));
assert(nRead > 0);
2026-07-10 18:08:04 +08:00
if ((token = memmem(p, (size_t) nRead, "\nsize ", strlen("\nsize "))) != nullptr) {
arcSize = (uint64_t) strtoull(token + 1 + dataOffset, nullptr, 10);
if (arcSize > 0) {
uint64_t arcMin = 0;
2026-07-10 18:08:04 +08:00
if ((token = memmem(p, (size_t) nRead, "\nc_min ", strlen("\nc_min "))) != nullptr) {
arcMin = (uint64_t) strtoull(token + 1 + dataOffset, nullptr, 10);
if (arcSize > arcMin) {
arcSize -= arcMin;
if (ram->bytesUsed > arcSize) {
ram->bytesUsed -= arcSize;
}
}
}
}
}
}
}
}
2026-07-10 18:08:04 +08:00
return nullptr;
}