procfs: implement system memory usage 87/180287/5
authorLukasz Stanislawski <l.stanislaws@samsung.com>
Wed, 16 May 2018 07:24:51 +0000 (09:24 +0200)
committerLukasz Stanislawski <l.stanislaws@samsung.com>
Tue, 12 Jun 2018 10:08:47 +0000 (10:08 +0000)
Change-Id: I8ccd8a2bc6a200d7d9af4d8fac170cff7fafd5b1

src/procfs.c

index 763c0d8..90bf5e6 100644 (file)
@@ -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)