From fb0154ef164d0e5942ac85102ab660b8d2938fbb Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Mon, 15 Feb 2016 12:34:23 +0100 Subject: [PATCH] #792 / cpu_stats: freebsd impl --- docs/index.rst | 40 ++++++++++++++++++++------------------- psutil/_psbsd.py | 13 +++++++++++++ psutil/_psutil_bsd.c | 2 ++ psutil/arch/bsd/freebsd.c | 35 ++++++++++++++++++++++++++++++++++ psutil/arch/bsd/freebsd.h | 1 + psutil/tests/test_bsd.py | 20 ++++++++++++++++++++ 6 files changed, 92 insertions(+), 19 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 5eead97c7..27488e32a 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -155,25 +155,27 @@ CPU Return various CPU statistics as a namedtuple whose fields change depending on the platform. - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | Linux | OSX | Windows | SunOS | FreeBSD | OpenBSD | NetBSD | - +=================+==============+==============+==============+============+=============+==============+ - | ctx_switches | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | interrupts | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | soft_interrupts | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | procs_running | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | procs_blocked | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ - | | | | | | | | - +-----------------+--------------+--------------+--------------+------------+-------------+--------------+ + ctx_switches, interrupts, soft_interrupts, syscalls, traps + + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | Linux | OSX | Windows | SunOS | FreeBSD | OpenBSD | NetBSD | + +=================+==============+==============+==============+=================+=============+==============+ + | ctx_switches | | | | ctx_switches | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | interrupts | | | | interrupts | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | soft_interrupts | | | | soft_interrupts | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | procs_running | | | | syscalls | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | procs_blocked | | | | traps | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | | | | | | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | | | | | | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ + | | | | | | | | + +-----------------+--------------+--------------+--------------+-----------------+-------------+--------------+ Example (Linux): diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 4af3bc8e4..d5c3405f2 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -114,6 +114,11 @@ else: sdiskio = namedtuple('sdiskio', ['read_count', 'write_count', 'read_bytes', 'write_bytes']) +if FREEBSD: + scpustats = namedtuple( + 'scpustats', ['ctx_switches', 'interrupts', 'soft_interrupts', + 'syscalls', 'traps']) + # set later from __init__.py NoSuchProcess = None @@ -222,6 +227,14 @@ def cpu_count_physical(): return ret +def cpu_stats(): + if FREEBSD: + ctx_switches, interrupts, soft_interrupts, syscalls, traps = \ + cext.cpu_stats() + return scpustats( + ctx_switches, interrupts, soft_interrupts, syscalls, traps) + + def boot_time(): """The system boot time expressed in seconds since the epoch.""" return cext.boot_time() diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 31511abb8..ef9e39817 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -1018,6 +1018,8 @@ PsutilMethods[] = { "Return a Python dict of tuples for disk I/O information"}, {"users", psutil_users, METH_VARARGS, "Return currently connected users as a list of tuples"}, + {"cpu_stats", psutil_cpu_stats, METH_VARARGS, + "Return CPU statistics"}, #if defined(__FreeBSD__) || defined(__NetBSD__) {"net_connections", psutil_net_connections, METH_VARARGS, "Return system-wide open connections."}, diff --git a/psutil/arch/bsd/freebsd.c b/psutil/arch/bsd/freebsd.c index f25feba69..d335a7ade 100644 --- a/psutil/arch/bsd/freebsd.c +++ b/psutil/arch/bsd/freebsd.c @@ -992,3 +992,38 @@ psutil_proc_cpu_affinity_set(PyObject *self, PyObject *args) { Py_DECREF(py_cpu_seq); return NULL; } + + +PyObject * +psutil_cpu_stats(PyObject *self, PyObject *args) { + unsigned int v_soft; + unsigned int v_intr; + unsigned int v_syscall; + unsigned int v_trap; + unsigned int v_swtch; + size_t size = sizeof(v_soft); + + if (sysctlbyname("vm.stats.sys.v_soft", &v_soft, &size, NULL, 0)) + goto error; + if (sysctlbyname("vm.stats.sys.v_intr", &v_intr, &size, NULL, 0)) + goto error; + if (sysctlbyname("vm.stats.sys.v_syscall", &v_syscall, &size, NULL, 0)) + goto error; + if (sysctlbyname("vm.stats.sys.v_trap", &v_trap, &size, NULL, 0)) + goto error; + if (sysctlbyname("vm.stats.sys.v_swtch", &v_swtch, &size, NULL, 0)) + goto error; + + return Py_BuildValue( + "IIIII", + v_swtch, // ctx switches + v_intr, // interrupts + v_soft, // software interrupts + v_syscall, // syscalls + v_trap // traps + ); + +error: + PyErr_SetFromErrno(PyExc_OSError); + return NULL; +} diff --git a/psutil/arch/bsd/freebsd.h b/psutil/arch/bsd/freebsd.h index e50c5b1fd..a539445da 100644 --- a/psutil/arch/bsd/freebsd.h +++ b/psutil/arch/bsd/freebsd.h @@ -28,3 +28,4 @@ PyObject* psutil_proc_num_threads(PyObject* self, PyObject* args); PyObject* psutil_proc_threads(PyObject* self, PyObject* args); PyObject* psutil_swap_mem(PyObject* self, PyObject* args); PyObject* psutil_virtual_mem(PyObject* self, PyObject* args); +PyObject* psutil_cpu_stats(PyObject* self, PyObject* args); diff --git a/psutil/tests/test_bsd.py b/psutil/tests/test_bsd.py index 6d2749ae9..53682c614 100644 --- a/psutil/tests/test_bsd.py +++ b/psutil/tests/test_bsd.py @@ -281,6 +281,26 @@ def test_muse_vmem_buffers(self): self.assertAlmostEqual(psutil.virtual_memory().buffers, num, delta=MEMORY_TOLERANCE) + def test_cpu_stats_ctx_switches(self): + self.assertAlmostEqual(psutil.cpu_stats().ctx_switches, + sysctl('vm.stats.sys.v_swtch'), delta=1000) + + def test_cpu_stats_interrupts(self): + self.assertAlmostEqual(psutil.cpu_stats().interrupts, + sysctl('vm.stats.sys.v_intr'), delta=1000) + + def test_cpu_stats_soft_interrupts(self): + self.assertAlmostEqual(psutil.cpu_stats().soft_interrupts, + sysctl('vm.stats.sys.v_soft'), delta=1000) + + def test_cpu_stats_syscalls(self): + self.assertAlmostEqual(psutil.cpu_stats().syscalls, + sysctl('vm.stats.sys.v_syscall'), delta=1000) + + def test_cpu_stats_traps(self): + self.assertAlmostEqual(psutil.cpu_stats().traps, + sysctl('vm.stats.sys.v_trap'), delta=1000) + # ===================================================================== # --- OpenBSD