1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113
|
/*
* 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.
*/
/*
Memory related functions. Original code was refactored and moved from
psutil/arch/netbsd/specific.c in 2023 (and was moved in there previously
already) from cset 84219ad. For reference, here's the git history with
original(ish) implementations:
- virtual memory: 0749a69c01b374ca3e2180aaafc3c95e3b2d91b9 (Oct 2016)
- swap memory: 312442ad2a5b5d0c608476c5ab3e267735c3bc59 (Jan 2016)
*/
#include <Python.h>
#include <sys/swap.h>
#include <sys/sysctl.h>
#include <uvm/uvm_extern.h>
#include "../../_psutil_common.h"
#include "../../_psutil_posix.h"
// Virtual memory stats, taken from:
// https://github.com/satterly/zabbix-stats/blob/master/src/libs/zbxsysinfo/
// netbsd/memory.c
PyObject *
psutil_virtual_mem(PyObject *self, PyObject *args) {
size_t size;
struct uvmexp_sysctl uv;
int mib[] = {CTL_VM, VM_UVMEXP2};
long long cached;
size = sizeof(uv);
if (sysctl(mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
return NULL;
}
// Note: zabbix does not include anonpages, but that doesn't match the
// "Cached" value in /proc/meminfo.
// https://github.com/zabbix/zabbix/blob/af5e0f8/src/libs/zbxsysinfo/netbsd/memory.c#L182
cached = (uv.filepages + uv.execpages + uv.anonpages) << uv.pageshift;
return Py_BuildValue(
"LLLLLL",
(long long) uv.npages << uv.pageshift, // total
(long long) uv.free << uv.pageshift, // free
(long long) uv.active << uv.pageshift, // active
(long long) uv.inactive << uv.pageshift, // inactive
(long long) uv.wired << uv.pageshift, // wired
cached // cached
);
}
PyObject *
psutil_swap_mem(PyObject *self, PyObject *args) {
uint64_t swap_total, swap_free;
struct swapent *swdev;
int nswap, i;
long pagesize = psutil_getpagesize();
nswap = swapctl(SWAP_NSWAP, 0, 0);
if (nswap == 0) {
// This means there's no swap partition.
return Py_BuildValue("(iiiii)", 0, 0, 0, 0, 0);
}
swdev = calloc(nswap, sizeof(*swdev));
if (swdev == NULL) {
PyErr_SetFromErrno(PyExc_OSError);
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_total += (uint64_t)swdev[i].se_nblks * DEV_BSIZE;
swap_free += (uint64_t)(swdev[i].se_nblks - swdev[i].se_inuse) * DEV_BSIZE;
}
}
free(swdev);
// Get swap in/out
unsigned int total;
size_t size = sizeof(total);
struct uvmexp_sysctl uv;
int mib[] = {CTL_VM, VM_UVMEXP2};
size = sizeof(uv);
if (sysctl(mib, 2, &uv, &size, NULL, 0) < 0) {
PyErr_SetFromErrno(PyExc_OSError);
goto error;
}
return Py_BuildValue("(LLLll)",
swap_total,
(swap_total - swap_free),
swap_free,
(long) uv.pgswapin * pagesize, // swap in
(long) uv.pgswapout * pagesize); // swap out
error:
free(swdev);
return NULL;
}
|