From 445296b299ed9e6466d53dd3b491d66ec8d46e5d Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Sun, 16 Jan 2022 19:02:35 +0000 Subject: [PATCH 1/3] implement CPU freq for OpenBSD --- psutil/_psbsd.py | 54 +++++++++++++++++++--------------- psutil/_psutil_bsd.c | 7 +++-- psutil/arch/openbsd/cpu.c | 18 ++++++++++++ psutil/arch/openbsd/cpu.h | 1 + psutil/tests/test_contracts.py | 2 +- 5 files changed, 54 insertions(+), 28 deletions(-) diff --git a/psutil/_psbsd.py b/psutil/_psbsd.py index 528850657..c4200cce1 100644 --- a/psutil/_psbsd.py +++ b/psutil/_psbsd.py @@ -310,6 +310,36 @@ def cpu_stats(): return _common.scpustats(ctxsw, intrs, soft_intrs, syscalls) +if FREEBSD: + def cpu_freq(): + """Return frequency metrics for CPUs. As of Dec 2018 only + CPU 0 appears to be supported by FreeBSD and all other cores + match the frequency of CPU 0. + """ + ret = [] + num_cpus = cpu_count_logical() + for cpu in range(num_cpus): + try: + current, available_freq = cext.cpu_freq(cpu) + except NotImplementedError: + continue + if available_freq: + try: + min_freq = int(available_freq.split(" ")[-1].split("/")[0]) + except(IndexError, ValueError): + min_freq = None + try: + max_freq = int(available_freq.split(" ")[0].split("/")[0]) + except(IndexError, ValueError): + max_freq = None + ret.append(_common.scpufreq(current, min_freq, max_freq)) + return ret +elif OPENBSD: + def cpu_freq(): + curr = float(cext.cpu_freq()) + return [_common.scpufreq(curr, 0.0, 0.0)] + + # ===================================================================== # --- disks # ===================================================================== @@ -439,30 +469,6 @@ def sensors_temperatures(): return ret - def cpu_freq(): - """Return frequency metrics for CPUs. As of Dec 2018 only - CPU 0 appears to be supported by FreeBSD and all other cores - match the frequency of CPU 0. - """ - ret = [] - num_cpus = cpu_count_logical() - for cpu in range(num_cpus): - try: - current, available_freq = cext.cpu_frequency(cpu) - except NotImplementedError: - continue - if available_freq: - try: - min_freq = int(available_freq.split(" ")[-1].split("/")[0]) - except(IndexError, ValueError): - min_freq = None - try: - max_freq = int(available_freq.split(" ")[0].split("/")[0]) - except(IndexError, ValueError): - max_freq = None - ret.append(_common.scpufreq(current, min_freq, max_freq)) - return ret - # ===================================================================== # --- other system functions diff --git a/psutil/_psutil_bsd.c b/psutil/_psutil_bsd.c index 80efe6a61..732a560f2 100644 --- a/psutil/_psutil_bsd.c +++ b/psutil/_psutil_bsd.c @@ -1133,6 +1133,10 @@ static PyMethodDef mod_methods[] = { "Return currently connected users as a list of tuples"}, {"cpu_stats", psutil_cpu_stats, METH_VARARGS, "Return CPU statistics"}, +#if defined(PSUTIL_FREEBSD) || defined(PSUTIL_OPENBSD) + {"cpu_freq", psutil_cpu_freq, METH_VARARGS, + "Return CPU frequency"}, +#endif #if defined(PSUTIL_FREEBSD) || defined(PSUTIL_NETBSD) {"net_connections", psutil_net_connections, METH_VARARGS, "Return system-wide open connections."}, @@ -1142,10 +1146,7 @@ static PyMethodDef mod_methods[] = { "Return battery information."}, {"sensors_cpu_temperature", psutil_sensors_cpu_temperature, METH_VARARGS, "Return temperature information for a given CPU core number."}, - {"cpu_frequency", psutil_cpu_freq, METH_VARARGS, - "Return frequency of a given CPU"}, #endif - // --- others {"set_debug", psutil_set_debug, METH_VARARGS, "Enable or disable PSUTIL_DEBUG messages"}, diff --git a/psutil/arch/openbsd/cpu.c b/psutil/arch/openbsd/cpu.c index 2a366fe01..0691fd1ff 100644 --- a/psutil/arch/openbsd/cpu.c +++ b/psutil/arch/openbsd/cpu.c @@ -89,3 +89,21 @@ psutil_cpu_stats(PyObject *self, PyObject *args) { uv.forks // forks ); } + + +PyObject * +psutil_cpu_freq(PyObject *self, PyObject *args) { + int freq; + size_t size; + int mib[2] = {CTL_HW, HW_CPUSPEED}; + + // On VirtualBox I get "sysctl hw.cpuspeed=2593" (never changing), + // which appears to be expressed in Mhz. + size = sizeof(freq); + if (sysctl(mib, 2, &freq, &size, NULL, 0) < 0) { + PyErr_SetFromErrno(PyExc_OSError); + return NULL; + } + + return Py_BuildValue("i", freq); +} diff --git a/psutil/arch/openbsd/cpu.h b/psutil/arch/openbsd/cpu.h index 6bace0b18..07bf95fd8 100644 --- a/psutil/arch/openbsd/cpu.h +++ b/psutil/arch/openbsd/cpu.h @@ -7,5 +7,6 @@ #include +PyObject *psutil_cpu_freq(PyObject* self, PyObject* args); PyObject *psutil_cpu_stats(PyObject* self, PyObject* args); PyObject *psutil_per_cpu_times(PyObject *self, PyObject *args); diff --git a/psutil/tests/test_contracts.py b/psutil/tests/test_contracts.py index 7401cc15e..9def408a9 100755 --- a/psutil/tests/test_contracts.py +++ b/psutil/tests/test_contracts.py @@ -134,7 +134,7 @@ def test_win_service_get(self): def test_cpu_freq(self): self.assertEqual(hasattr(psutil, "cpu_freq"), - LINUX or MACOS or WINDOWS or FREEBSD) + LINUX or MACOS or WINDOWS or FREEBSD or OPENBSD) def test_sensors_temperatures(self): self.assertEqual( From 5780901b5c2f2b2d226578e84dae2daea8c443fc Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Sun, 16 Jan 2022 20:03:01 +0100 Subject: [PATCH 2/3] update doc Signed-off-by: Giampaolo Rodola --- docs/index.rst | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/docs/index.rst b/docs/index.rst index 7c9e8ae3a..6df7ccefb 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -269,11 +269,11 @@ CPU Return CPU frequency as a named tuple including *current*, *min* and *max* frequencies expressed in Mhz. On Linux *current* frequency reports the real-time value, on all other - platforms it represents the nominal "fixed" value. + platforms this usually represents the nominal "fixed" value (never changing). If *percpu* is ``True`` and the system supports per-cpu frequency retrieval (Linux only) a list of frequencies is returned for each CPU, if not, a list with a single element is returned. - If *min* and *max* cannot be determined they are set to ``0``. + If *min* and *max* cannot be determined they are set to ``0.0``. Example (Linux): @@ -288,12 +288,14 @@ CPU scpufreq(current=1703.609, min=800.0, max=3500.0), scpufreq(current=1754.289, min=800.0, max=3500.0)] - Availability: Linux, macOS, Windows, FreeBSD + Availability: Linux, macOS, Windows, FreeBSD, OpenBSD .. versionadded:: 5.1.0 .. versionchanged:: 5.5.1 added FreeBSD support. + .. versionchanged:: 5.9.1 added OpenBSD support. + .. function:: getloadavg() Return the average system load over the last 1, 5 and 15 minutes as a tuple. From 9728be30fbc7ebdcb5b920ff1f4cfa07a69b4ae7 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Sun, 16 Jan 2022 20:05:57 +0100 Subject: [PATCH 3/3] update HISTORY Signed-off-by: Giampaolo Rodola --- HISTORY.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/HISTORY.rst b/HISTORY.rst index b19c71426..595de9754 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -10,6 +10,7 @@ XXXX-XX-XX - 2050_, [Linux]: increase ``read(2)`` buffer size from 1k to 32k when reading ``/proc`` pseudo files line by line. This should help having more consistent results. +- 2057_, [OpenBSD]: add support for `cpu_freq()`_. **Bug fixes**