/* * Copyright (c) 2009, Giampaolo Rodola', Landry Breuil. * All rights reserved. * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include #include #include #include #include #include #include "../../_psutil_posix.h" PyObject * psutil_virtual_mem(PyObject *self, PyObject *args) { int64_t total_physmem; int uvmexp_mib[] = {CTL_VM, VM_UVMEXP}; int bcstats_mib[] = {CTL_VFS, VFS_GENERIC, VFS_BCACHESTAT}; int physmem_mib[] = {CTL_HW, HW_PHYSMEM64}; int vmmeter_mib[] = {CTL_VM, VM_METER}; size_t size; struct uvmexp uvmexp; struct bcachestats bcstats; struct vmtotal vmdata; long pagesize = psutil_getpagesize(); size = sizeof(total_physmem); if (sysctl(physmem_mib, 2, &total_physmem, &size, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } size = sizeof(uvmexp); if (sysctl(uvmexp_mib, 2, &uvmexp, &size, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } size = sizeof(bcstats); if (sysctl(bcstats_mib, 3, &bcstats, &size, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } size = sizeof(vmdata); if (sysctl(vmmeter_mib, 2, &vmdata, &size, NULL, 0) < 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } return Py_BuildValue("KKKKKKKK", // Note: many programs calculate total memory as // "uvmexp.npages * pagesize" but this is incorrect and does not // match "sysctl | grep hw.physmem". (unsigned long long) total_physmem, (unsigned long long) uvmexp.free * pagesize, (unsigned long long) uvmexp.active * pagesize, (unsigned long long) uvmexp.inactive * pagesize, (unsigned long long) uvmexp.wired * pagesize, // this is how "top" determines it (unsigned long long) bcstats.numbufpages * pagesize, // cached (unsigned long long) 0, // buffers (unsigned long long) vmdata.t_vmshr + vmdata.t_rmshr // shared ); } PyObject * psutil_swap_mem(PyObject *self, PyObject *args) { uint64_t swap_total, swap_free; struct swapent *swdev; int nswap, i; if ((nswap = swapctl(SWAP_NSWAP, 0, 0)) == 0) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } if ((swdev = calloc(nswap, sizeof(*swdev))) == NULL) { PyErr_NoMemory(); return NULL; } if (swapctl(SWAP_STATS, swdev, nswap) == -1) { PyErr_SetFromErrno(PyExc_OSError); goto error; } // Total things up. swap_total = swap_free = 0; for (i = 0; i < nswap; i++) { if (swdev[i].se_flags & SWF_ENABLE) { swap_free += (swdev[i].se_nblks - swdev[i].se_inuse); swap_total += swdev[i].se_nblks; } } free(swdev); return Py_BuildValue( "(LLLII)", swap_total * DEV_BSIZE, (swap_total - swap_free) * DEV_BSIZE, swap_free * DEV_BSIZE, // swap in / swap out is not supported as the // swapent struct does not provide any info // about it. 0, 0 ); error: free(swdev); return NULL; }