diff options
-rw-r--r-- | src/procfs.c | 51 |
1 files changed, 50 insertions, 1 deletions
diff --git a/src/procfs.c b/src/procfs.c index 763c0d8..90bf5e6 100644 --- a/src/procfs.c +++ b/src/procfs.c @@ -23,6 +23,7 @@ #define LOADAVG_FILEPATH "/proc/loadavg" #define UPTIME_FILEPATH "/proc/uptime" #define POSSIBLE_CPUS_FILEPATH "/sys/devices/system/cpu/possible" +#define MEMINFO_FILEPATH "/proc/meminfo" int procfs_read_system_load_average(struct procfs_load_average_info *info) { @@ -63,7 +64,55 @@ int procfs_read_system_percpu_usage(int max_cpus, struct procfs_system_cpu_usage int procfs_read_system_memory_usage(struct procfs_system_memory_usage_info *usage) { - return -1; + ON_NULL_RETURN_VAL(usage, -1); + + char line[128]; + unsigned long value; + unsigned long mem_total = 0; + unsigned long mem_free = 0; + unsigned long cached = 0; + unsigned long mem_available = 0; + unsigned long swap_total = 0; + unsigned long swap_free = 0; + + FILE *meminfo_fp = fopen(MEMINFO_FILEPATH, "r"); + if (!meminfo_fp) { + ERR("failed to open " MEMINFO_FILEPATH); + return -1; + } + + while (fgets(line, sizeof(line), meminfo_fp)) { + if (sscanf(line, "MemTotal: %lu", &mem_total) == 1) + usage->total = mem_total; + else if (sscanf(line, "MemFree: %lu", &mem_free) == 1) + usage->free = mem_free; + else if (sscanf(line, "Cached: %lu", &cached) == 1) + usage->cache = cached; + else if (sscanf(line, "MemAvailable: %lu", &value) == 1) + mem_available = value; + else if (sscanf(line, "SwapTotal: %lu", &value) == 1) + swap_total = value; + else if (sscanf(line, "SwapFree: %lu", &value) == 1) + swap_free = value; + } + + // Calculate used memory + // MemAvailable is exposed since Linux 3.14, so handle also previous + // kernel versions + usage->used = 0; + if (mem_available > 0) { + if (mem_total > mem_available) + usage->used = mem_total - mem_available; + } else { + if ((mem_total > mem_free) && ((mem_total - mem_free) > cached)) + usage->used = mem_total - mem_free - cached; + } + + usage->swap = (swap_total > swap_free) ? (swap_total - swap_free) : 0; + + fclose(meminfo_fp); + + return 0; } int procfs_read_process_memory_usage(int pid, struct procfs_process_memory_usage_info *usage) |