#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)
{
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)