/* retoor <retoor@molodetz.nl> */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "memory.h"
int memory_info_init(MemoryInfo *info) {
if (!info) return -1;
memset(info, 0, sizeof(MemoryInfo));
return memory_info_update(info, 0);
}
int memory_info_update(MemoryInfo *info, double interval) {
if (!info) return -1;
info->prev_page_faults = info->page_faults;
info->prev_page_in = info->page_in;
info->prev_page_out = info->page_out;
FILE *fp = fopen("/proc/meminfo", "r");
if (!fp) return -1;
char line[256];
unsigned long mem_total = 0, mem_free = 0, mem_available = 0;
unsigned long buffers = 0, cached = 0, slab_reclaimable = 0;
unsigned long swap_total = 0, swap_free = 0;
while (fgets(line, sizeof(line), fp)) {
if (strncmp(line, "MemTotal:", 9) == 0) {
sscanf(line + 9, "%lu", &mem_total);
} else if (strncmp(line, "MemFree:", 8) == 0) {
sscanf(line + 8, "%lu", &mem_free);
} else if (strncmp(line, "MemAvailable:", 13) == 0) {
sscanf(line + 13, "%lu", &mem_available);
} else if (strncmp(line, "Buffers:", 8) == 0) {
sscanf(line + 8, "%lu", &buffers);
} else if (strncmp(line, "Cached:", 7) == 0) {
sscanf(line + 7, "%lu", &cached);
} else if (strncmp(line, "SReclaimable:", 13) == 0) {
sscanf(line + 13, "%lu", &slab_reclaimable);
} else if (strncmp(line, "SwapTotal:", 10) == 0) {
sscanf(line + 10, "%lu", &swap_total);
} else if (strncmp(line, "SwapFree:", 9) == 0) {
sscanf(line + 9, "%lu", &swap_free);
}
}
fclose(fp);
info->total = mem_total;
info->free = mem_free;
info->available = mem_available;
info->buffers = buffers;
info->cached = cached + slab_reclaimable;
info->used = mem_total - mem_available;
if (mem_total > 0) {
info->used_percent = 100.0 * (double)info->used / (double)mem_total;
}
info->swap_total = swap_total;
info->swap_free = swap_free;
info->swap_used = swap_total - swap_free;
if (swap_total > 0) {
info->swap_percent = 100.0 * (double)info->swap_used / (double)swap_total;
}
fp = fopen("/proc/vmstat", "r");
if (fp) {
while (fgets(line, sizeof(line), fp)) {
if (strncmp(line, "pgfault ", 8) == 0) {
sscanf(line + 8, "%lu", &info->page_faults);
} else if (strncmp(line, "pgpgin ", 7) == 0) {
sscanf(line + 7, "%lu", &info->page_in);
} else if (strncmp(line, "pgpgout ", 8) == 0) {
sscanf(line + 8, "%lu", &info->page_out);
}
}
fclose(fp);
}
if (interval > 0) {
info->page_faults_per_sec = (double)(info->page_faults - info->prev_page_faults) / interval;
info->page_in_per_sec = (double)(info->page_in - info->prev_page_in) / interval;
info->page_out_per_sec = (double)(info->page_out - info->prev_page_out) / interval;
}
return 0;
}