summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/procfs.c51
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)