forked from enlightenment/enlightenment
173 lines
4.6 KiB
C
173 lines
4.6 KiB
C
#include "memusage.h"
|
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
# include <sys/types.h>
|
|
# include <sys/sysctl.h>
|
|
# include <vm/vm_param.h>
|
|
#endif
|
|
|
|
#if defined(__OpenBSD__)
|
|
# include <sys/param.h>
|
|
# include <sys/sysctl.h>
|
|
# include <sys/swap.h>
|
|
# include <sys/mount.h>
|
|
#endif
|
|
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
static long int
|
|
_sysctlfromname(const char *name, void *mib, int depth, size_t *len)
|
|
{
|
|
long int result;
|
|
|
|
if (sysctlnametomib(name, mib, len) < 0) return -1;
|
|
|
|
*len = sizeof(result);
|
|
if (sysctl(mib, depth, &result, len, NULL, 0) < 0) return -1;
|
|
|
|
return result;
|
|
}
|
|
|
|
#endif
|
|
|
|
void
|
|
_memsize_bytes_to_kb(unsigned long *bytes)
|
|
{
|
|
*bytes = (unsigned int)*bytes >> 10;
|
|
}
|
|
|
|
void
|
|
_memusage_sysctl_getusage(unsigned long *mem_total,
|
|
unsigned long *mem_used,
|
|
unsigned long *mem_cached,
|
|
unsigned long *mem_buffers,
|
|
unsigned long *mem_shared,
|
|
unsigned long *swp_total,
|
|
unsigned long *swp_used)
|
|
{
|
|
size_t len;
|
|
int i = 0;
|
|
*mem_total = *mem_used = *mem_cached = *mem_buffers = *mem_shared = 0;
|
|
*swp_total = *swp_used = 0;
|
|
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
|
size_t miblen;
|
|
int total_pages = 0, free_pages = 0, inactive_pages = 0;
|
|
long int result = 0;
|
|
int page_size = getpagesize();
|
|
|
|
int *mib = malloc(sizeof(int) * 4);
|
|
if (mib == NULL) return;
|
|
|
|
mib[0] = CTL_HW; mib[1] = HW_PHYSMEM;
|
|
len = sizeof(*mem_total);
|
|
if (sysctl(mib, 2, mem_total, &len, NULL, 0) == -1)
|
|
return;
|
|
*mem_total /= 1024;
|
|
|
|
total_pages = _sysctlfromname("vm.stats.vm.v_page_count", mib, 4, &len);
|
|
if (total_pages < 0) return;
|
|
|
|
free_pages = _sysctlfromname("vm.stats.vm.v_free_count", mib, 4, &len);
|
|
if (free_pages < 0) return;
|
|
|
|
inactive_pages = _sysctlfromname("vm.stats.vm.v_inactive_count", mib, 4, &len);
|
|
if (inactive_pages < 0) return;
|
|
|
|
*mem_used = (total_pages - free_pages - inactive_pages) * page_size;
|
|
_memsize_bytes_to_kb(mem_used);
|
|
|
|
result = _sysctlfromname("vfs.bufspace", mib, 2, &len);
|
|
if (result < 0) return;
|
|
*mem_buffers = (result);
|
|
_memsize_bytes_to_kb(mem_buffers);
|
|
|
|
result = _sysctlfromname("vm.stats.vm.v_active_count", mib, 4, &len);
|
|
if (result < 0) return;
|
|
*mem_cached = (result * page_size);
|
|
_memsize_bytes_to_kb(mem_cached);
|
|
|
|
result = _sysctlfromname("vm.stats.vm.v_cache_count", mib, 4, &len);
|
|
if (result < 0) return;
|
|
*mem_shared = (result * page_size);
|
|
_memsize_bytes_to_kb(mem_shared);
|
|
|
|
result = _sysctlfromname("vm.swap_total", mib, 2, &len);
|
|
if (result < 0) return;
|
|
*swp_total = (result / 1024);
|
|
|
|
miblen = 3;
|
|
if (sysctlnametomib("vm.swap_info", mib, &miblen) == -1) return;
|
|
|
|
struct xswdev xsw;
|
|
// previous mib is important for this one...
|
|
|
|
for (i = 0; ; i++)
|
|
{
|
|
mib[miblen] = i;
|
|
len = sizeof(xsw);
|
|
if (sysctl(mib, miblen + 1, &xsw, &len, NULL, 0) == -1) break;
|
|
|
|
*swp_used += (unsigned long)xsw.xsw_used * page_size;
|
|
}
|
|
|
|
*swp_used >>= 10;
|
|
|
|
E_FREE(mib);
|
|
#elif defined(__OpenBSD__)
|
|
static int mib[] = { CTL_HW, HW_PHYSMEM64 };
|
|
static int bcstats_mib[] = { CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT };
|
|
struct bcachestats bcstats;
|
|
static int uvmexp_mib[] = { CTL_VM, VM_UVMEXP };
|
|
struct uvmexp uvmexp;
|
|
int nswap, rnswap;
|
|
struct swapent *swdev = NULL;
|
|
|
|
len = sizeof(*mem_total);
|
|
if (sysctl(mib, 2, mem_total, &len, NULL, 0) == -1)
|
|
return;
|
|
|
|
len = sizeof(uvmexp);
|
|
if (sysctl(uvmexp_mib, 2, &uvmexp, &len, NULL, 0) == -1)
|
|
return;
|
|
|
|
len = sizeof(bcstats);
|
|
if (sysctl(bcstats_mib, 3, &bcstats, &len, NULL, 0) == -1)
|
|
return;
|
|
|
|
// Don't fail if there's not swap!
|
|
nswap = swapctl(SWAP_NSWAP, 0, 0);
|
|
if (nswap == 0) goto swap_out;
|
|
|
|
swdev = calloc(nswap, sizeof(*swdev));
|
|
if (swdev == NULL) goto swap_out;
|
|
|
|
rnswap = swapctl(SWAP_STATS, swdev, nswap);
|
|
if (rnswap == -1) goto swap_out;
|
|
|
|
for (i = 0; i < nswap; i++) // nswap; i++)
|
|
{
|
|
if (swdev[i].se_flags & SWF_ENABLE)
|
|
{
|
|
*swp_used += (swdev[i].se_inuse / (1024 / DEV_BSIZE));
|
|
*swp_total += (swdev[i].se_nblks / (1024 / DEV_BSIZE));
|
|
}
|
|
}
|
|
swap_out:
|
|
if (swdev) E_FREE(swdev);
|
|
|
|
*mem_total /= 1024;
|
|
|
|
*mem_cached = (uvmexp.pagesize * bcstats.numbufpages);
|
|
_memsize_bytes_to_kb(mem_cached);
|
|
|
|
*mem_used = (uvmexp.active * uvmexp.pagesize);
|
|
_memsize_bytes_to_kb(mem_used);
|
|
|
|
*mem_buffers = (uvmexp.pagesize * (uvmexp.npages - uvmexp.free));
|
|
_memsize_bytes_to_kb(mem_buffers);
|
|
|
|
*mem_shared = (uvmexp.pagesize * uvmexp.wired);
|
|
_memsize_bytes_to_kb(mem_shared);
|
|
#endif
|
|
}
|
|
|