From 34c8e85e49dc2fcd4f4c56eb755191473c81b1ef Mon Sep 17 00:00:00 2001 From: Christian Barthel Date: Sat, 8 Jan 2022 08:28:15 +0100 Subject: [PATCH] Add Linux support, fix whitespace Read /proc/meminfo, pull out some numbers and use them. --- README.md | 11 +- get_mem.c | 341 +++++++++++++++++++++++++++++++++++------------------- 2 files changed, 232 insertions(+), 120 deletions(-) diff --git a/README.md b/README.md index 456f5e6..5b2ad4c 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,11 @@ # xmem(1) X11 Utility -![fvwm and xmem](https://git.sdf.org/bch/xmem/raw/branch/master/www/xmem_fvwmbar.png) \ No newline at end of file +![fvwm and xmem](https://git.sdf.org/bch/xmem/raw/branch/master/www/xmem_fvwmbar.png) + +# Compile + +```shell + # Linux with DEBUG: + CFLAGS=-DDEBUG make -f Makefile.linux + # BSD: + make +``` \ No newline at end of file diff --git a/get_mem.c b/get_mem.c index b2bcc9e..26960b4 100644 --- a/get_mem.c +++ b/get_mem.c @@ -13,7 +13,7 @@ #if __OpenBSD__ -#include /* DEV_BSIZE MAXCOMLEN PZERO */ +#include /* DEV_BSIZE MAXCOMLEN PZERO */ #include #include #include @@ -36,89 +36,89 @@ static double allmem_kb = 0; static void initPageShift(void) { - int pagesize = getpagesize(); - pageshift = 0; - while (pagesize > 1) { - pageshift++; - pagesize >>= 1; - } - pageshift -= LOG1024; + int pagesize = getpagesize(); + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + pageshift -= LOG1024; } static double getSwapFrac() { - struct swapent *swdev; - int used, total, nswap, rnswap, i; + struct swapent *swdev; + int used, total, nswap, rnswap, i; - nswap = swapctl(SWAP_NSWAP, 0, 0); - if (nswap == 0) - return 0; + nswap = swapctl(SWAP_NSWAP, 0, 0); + if (nswap == 0) + return 0; - swdev = calloc(nswap, sizeof(*swdev)); - if (swdev == NULL) - return 0; + swdev = calloc(nswap, sizeof(*swdev)); + if (swdev == NULL) + return 0; - rnswap = swapctl(SWAP_STATS, swdev, nswap); - if (rnswap == -1) { - free(swdev); - return 0; - } + rnswap = swapctl(SWAP_STATS, swdev, nswap); + if (rnswap == -1) { + free(swdev); + return 0; + } - /* if rnswap != nswap, then what? */ + /* if rnswap != nswap, then what? */ - /* Total things up */ - total = used = 0; - for (i = 0; i < nswap; i++) { - if (swdev[i].se_flags & SWF_ENABLE) { - used += (swdev[i].se_inuse / (1024 / DEV_BSIZE)); - total += (swdev[i].se_nblks / (1024 / DEV_BSIZE)); - } - } - free(swdev); - return (double)used/total; + /* Total things up */ + total = used = 0; + for (i = 0; i < nswap; i++) { + if (swdev[i].se_flags & SWF_ENABLE) { + used += (swdev[i].se_inuse / (1024 / DEV_BSIZE)); + total += (swdev[i].se_nblks / (1024 / DEV_BSIZE)); + } + } + free(swdev); + return (double)used/total; } void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data) { - static int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT}; - static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; - MemStripChartCallbackData ret; - struct uvmexp uvmexp; - struct bcachestats bcstats; - size_t size; + static int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT}; + static int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; + MemStripChartCallbackData ret; + struct uvmexp uvmexp; + struct bcachestats bcstats; + size_t size; - if (pageshift < 0) - initPageShift(); + if (pageshift < 0) + initPageShift(); - size = sizeof(uvmexp); - if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) { - warn("sysctl failed"); - bzero(&uvmexp, sizeof(uvmexp)); - } - size = sizeof(bcstats); - if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) < 0) { - warn("sysctl failed"); - bzero(&bcstats, sizeof(bcstats)); - } + size = sizeof(uvmexp); + if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) { + warn("sysctl failed"); + bzero(&uvmexp, sizeof(uvmexp)); + } + size = sizeof(bcstats); + if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) < 0) { + warn("sysctl failed"); + bzero(&bcstats, sizeof(bcstats)); + } - allmem_kb = pagetok(uvmexp.npages); - ret.cached = pagetok(bcstats.numbufpages) / allmem_kb; - ret.free = pagetok(uvmexp.free) / allmem_kb; - ret.buffer = 0; - ret.code = (1 - ret.cached - ret.free); - ret.swap = getSwapFrac(); + allmem_kb = pagetok(uvmexp.npages); + ret.cached = pagetok(bcstats.numbufpages) / allmem_kb; + ret.free = pagetok(uvmexp.free) / allmem_kb; + ret.buffer = 0; + ret.code = (1 - ret.cached - ret.free); + ret.swap = getSwapFrac(); #ifdef DEBUG - printf("%lf %lf %lf %lf %lf\n", - allmem_kb, - ret.code, - ret.cached, - ret.free, - ret.swap); + printf("%lf %lf %lf %lf %lf\n", + allmem_kb, + ret.code, + ret.cached, + ret.free, + ret.swap); #endif - memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); + memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); } #endif @@ -133,7 +133,7 @@ void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data) */ -#include /* DEV_BSIZE MAXCOMLEN PZERO */ +#include /* DEV_BSIZE MAXCOMLEN PZERO */ #include #include @@ -156,91 +156,194 @@ static unsigned int allmem_pages = 0; static void initPageShift(void) { - pagesize = getpagesize(); - size_t len = sizeof(allmem_pages); - int mib[len]; - pageshift = 0; - while (pagesize > 1) { - pageshift++; - pagesize >>= 1; - } - pageshift -= LOG1024; + pagesize = getpagesize(); + size_t len = sizeof(allmem_pages); + int mib[len]; + pageshift = 0; + while (pagesize > 1) { + pageshift++; + pagesize >>= 1; + } + pageshift -= LOG1024; - kd = kvm_open(NULL, "/dev/null" ,NULL, O_RDONLY, "kvm_open"); + kd = kvm_open(NULL, "/dev/null" ,NULL, O_RDONLY, "kvm_open"); - if (sysctlbyname("vm.stats.vm.v_page_count", &allmem_pages, &len, NULL, 0) == -1) - perror("sysctl"); + if (sysctlbyname("vm.stats.vm.v_page_count", &allmem_pages, &len, NULL, 0) == -1) + perror("sysctl"); #ifdef DEBUG - printf("page_count: %d\n", allmem_pages); + printf("page_count: %d\n", allmem_pages); #endif } static double getSwapFrac() { - /* XXX Borrowed from top(1) code: */ - int n; - struct kvm_swap swapary[1]; - static int pagesize = 0; - static unsigned long swap_maxpages = 0; - size_t sz = sizeof(swap_maxpages); + /* XXX Borrowed from top(1) code: */ + int n; + struct kvm_swap swapary[1]; + static int pagesize = 0; + static unsigned long swap_maxpages = 0; + size_t sz = sizeof(swap_maxpages); - int retavail = 0; - int retfree = 0; + int retavail = 0; + int retfree = 0; - n = kvm_getswapinfo(kd, swapary, 1, 0); - if (n < 0 || swapary[0].ksw_total == 0) - return (0); + n = kvm_getswapinfo(kd, swapary, 1, 0); + if (n < 0 || swapary[0].ksw_total == 0) + return (0); - if (swap_maxpages == 0) - sysctlbyname("vm.swap_maxpages", - &swap_maxpages, &sz, NULL, 0); + if (swap_maxpages == 0) + sysctlbyname("vm.swap_maxpages", + &swap_maxpages, &sz, NULL, 0); - if ( swapary[0].ksw_total > swap_maxpages ) - swapary[0].ksw_total = swap_maxpages; + if ( swapary[0].ksw_total > swap_maxpages ) + swapary[0].ksw_total = swap_maxpages; - retavail = swapary[0].ksw_total; - retfree = swapary[0].ksw_total - swapary[0].ksw_used; + retavail = swapary[0].ksw_total; + retfree = swapary[0].ksw_total - swapary[0].ksw_used; #ifdef DEBUG - printf("swap: %d %d %d %d\n", retavail, - retavail, swapary[0].ksw_total, - swapary[0].ksw_used); + printf("swap: %d %d %d %d\n", retavail, + retavail, swapary[0].ksw_total, + swapary[0].ksw_used); #endif - return (double)(retavail-retfree)/(double)retavail; + return (double)(retavail-retfree)/(double)retavail; } void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data) { - MemStripChartCallbackData ret; - int a, b; - size_t sz = sizeof(int); - double cache = 0; + MemStripChartCallbackData ret; + int a, b; + size_t sz = sizeof(int); + double cache = 0; - if (pageshift < 0) - initPageShift(); + if (pageshift < 0) + initPageShift(); - sysctlbyname("vm.stats.vm.v_wire_count", &a, &sz, NULL, 0); - ret.code = (double)a / (double)allmem_pages; + sysctlbyname("vm.stats.vm.v_wire_count", &a, &sz, NULL, 0); + ret.code = (double)a / (double)allmem_pages; - sysctlbyname("vm.stats.vm.v_active_count", &a, &sz, NULL, 0); - ret.buffer = (double)a / (double)allmem_pages; + sysctlbyname("vm.stats.vm.v_active_count", &a, &sz, NULL, 0); + ret.buffer = (double)a / (double)allmem_pages; - /* v_cache_count and v_inactive_count are treated similarly */ - sysctlbyname("vm.stats.vm.v_inactive_count", &a, &sz, NULL, 0); - sysctlbyname("vm.stats.vm.v_cache_count", &b, &sz, NULL, 0); - ret.cached = (double)(a + b) / allmem_pages; + /* v_cache_count and v_inactive_count are treated similarly */ + sysctlbyname("vm.stats.vm.v_inactive_count", &a, &sz, NULL, 0); + sysctlbyname("vm.stats.vm.v_cache_count", &b, &sz, NULL, 0); + ret.cached = (double)(a + b) / allmem_pages; - sysctlbyname("vm.stats.vm.v_free_count", &a, &sz, NULL, 0); - ret.free = (double)a / allmem_pages; - ret.swap = getSwapFrac(); + sysctlbyname("vm.stats.vm.v_free_count", &a, &sz, NULL, 0); + ret.free = (double)a / allmem_pages; + ret.swap = getSwapFrac(); #ifdef DEBUG - printf("%u %lf %lf %lf %lf\n", allmem_pages, - ret.code, ret.cached, ret.free, ret.swap); + printf("%u %lf %lf %lf %lf\n", allmem_pages, + ret.code, ret.cached, ret.free, ret.swap); #endif - memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); + memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); +} + +#endif + + + + + +/* ------------------------------------------------------------------ */ +#if __gnu_linux__ +#include +#include +#include +#include +#include +#include "MemStripChart.h" + +static unsigned int total_mem = 0; + +int GetRamInKB(int type) +{ + FILE *meminfo = fopen("/proc/meminfo", "r"); + if(meminfo == NULL) + err(1, "fopen on /proc/meminfo failed: "); + + char line[256]; + int memory = -1; + int found = 0; + while(found == 0 && fgets(line, sizeof(line), meminfo)) + { + if (type == 1) { + if((sscanf(line, "MemTotal: %d kB", &memory)) == 1) + found = 1; + } + if (type == 2) { + if(sscanf(line, "MemFree: %d kB", &memory) == 1) + found = 1; + } + if (type == 3) { + if(sscanf(line, "Buffers: %d kB", &memory) == 1) + found = 1; + } + if (type == 4) { + if(sscanf(line, "Cached: %d kB", &memory) == 1) + found = 1; + } + if (type == 5) { + if(sscanf(line, "SwapTotal: %d kB", &memory) == 1) + found = 1; + } + if (type == 6) { + if(sscanf(line, "SwapFree: %d kB", &memory) == 1) + found = 1; + } + } + if (!found) + warnx("failed to sscanf type %d", type); + fclose(meminfo); + return memory; +} + +static void init_total_mem(void) +{ + if (total_mem <= 0) + total_mem = GetRamInKB(1); +#ifdef DEBUG + printf("MemTotal: %d\n", total_mem); +#endif +} + + +void GetMemLoadPoint(Widget w, caddr_t closure, caddr_t call_data) +{ + MemStripChartCallbackData ret; + + init_total_mem(); + /* free(1): + * total + * used = total - free - buffers - cache + + * /proc/meminfo + * total = MemTotal + * code = total - free - buffers - cache (“used”) + * buffer = Buffers + * cached = Cached + * free = MemFree + */ + int mem_free = GetRamInKB(2); + int buffers = GetRamInKB(3); + int cached = GetRamInKB(4); + int swap_total = GetRamInKB(5); + int swap_free = GetRamInKB(6); + ret.code = (total_mem - mem_free - buffers - cached)/(float)total_mem; + ret.buffer = (buffers)/(float)total_mem; + ret.cached = (cached)/(float)total_mem; + ret.free = (mem_free)/(float)total_mem; + ret.swap = (swap_total - swap_free)/(float)swap_total; + +#ifdef DEBUG + printf("%u %lf %lf %lf %lf\n", total_mem, + ret.code, ret.cached, ret.free, ret.swap); +#endif + memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); } #endif