/* $Id: get_mem.c,v 1.5 2018/12/26 18:46:04 bch Exp $ * * xmem(1) utility adapted by Christian Barthel : * - Added OpenBSD support * - Added FreeBSD support * * get memory usage, from get_load.c derived * * Author: Hans-Helmut Buehmann 20. Jan. 1996 * * Modified for more recent kernels Helmut Geyer Oct. 1996 */ #if __OpenBSD__ #include /* DEV_BSIZE MAXCOMLEN PZERO */ #include #include #include #include #include #include #include #include #include #include #include "MemStripChart.h" static int pageshift = -1; #define pagetok(size) ((size) << pageshift) #define LOG1024 10 static double allmem_kb = 0; static void initPageShift(void) { 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; nswap = swapctl(SWAP_NSWAP, 0, 0); if (nswap == 0) 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; } /* 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; } 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; 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)); } 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); #endif memcpy(call_data, &ret, sizeof(MemStripChartCallbackData)); } #endif /* ------------------------------------------------------------------- */ #if __FreeBSD__ /* $Id: get_mem_fbsd.c,v 1.1 2018/12/26 18:46:16 bch Exp $ * * Author: Christian Barthel */ #include /* DEV_BSIZE MAXCOMLEN PZERO */ #include #include #include #include #include #include #include #include #include "MemStripChart.h" static int pageshift = -1; static int pagesize = 0; static kvm_t *kd = 0; #define pagetok(size) ((size) << pageshift) #define LOG1024 10 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; 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"); #ifdef DEBUG 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); int retavail = 0; int retfree = 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 ( 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; #ifdef DEBUG printf("swap: %d %d %d %d\n", retavail, retavail, swapary[0].ksw_total, swapary[0].ksw_used); #endif 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; 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_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; 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); #endif 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