void glibtop_get_mem_s (glibtop *server, glibtop_mem *buf) { struct vminfo vminfo; int pagesize; int result; glibtop_init_s (&server, (1L << GLIBTOP_SYSDEPS_MEM), 0); memset (buf, 0, sizeof (glibtop_mem)); pagesize = sysconf(_SC_PAGESIZE); #ifdef HAVE_VMGETINFO result = vmgetinfo((void*)&vminfo, VMINFO, sizeof(vminfo)); #else result = _glibtop_vmgetinfo((void*)&vminfo, VMINFO, sizeof(vminfo)); #endif if (result == -1) { glibtop_error_io_r (server, "Cannot read vminfo"); return; } buf->total = vminfo.memsizepgs * pagesize; buf->used = (vminfo.numwseguse + vminfo.numpseguse + vminfo.numclseguse) * pagesize; buf->free = vminfo.numfrb * pagesize; buf->locked = (vminfo.numwsegpin + vminfo.numpsegpin + vminfo.numclsegpin) * pagesize; buf->flags = _glibtop_sysdeps_mem; }
/* This is the action packed part of the program */ unsigned long long pg_ref(void *p_start, void *p_end, size_t pg_size, int pg_opt_write) { register char x; register char *p_seek; register unsigned long long pg_cnt=0; struct vm_page_info vinfo; static size_t pg_size_default; /* If not supplied, derive a fixed page size based on the first page in the range using VM_PAGE_INFO. * It's possible to have mixed page sizes within a segment. * The code is not handling this case yet. * A more conservative derivation would be to use VMINFO_GETPSIZES and select the smallest size. */ if (!pg_size) { vinfo.addr=(uint64_t)p_start; if (vmgetinfo(&vinfo, VM_PAGE_INFO, sizeof(vinfo))==0) { pg_size=vinfo.pagesize; } else { /* Failsafe method - system's "fixed" pagesize value */ /* Warning message? */ fprintf(stderr,"vmgetinfo returned %s, error code %d. Defaulting to sysconf.\n",strerror(errno),errno); if (!pg_size_default) pg_size_default=sysconf(_SC_PAGE_SIZE); pg_size=pg_size_default; } } for (p_seek=p_start; p_seek < p_end; p_seek+=pg_size, ++pg_cnt) { /* Read. Force page-in; trigger copy-on-ref after forks (depending on vmm_fork_policy tuning) */ x=*p_seek; /* Write. Force page-in; trigger copy-on-write after forks; and for mmap memory, take page control */ if (pg_opt_write) *p_seek=x; } return pg_cnt; }