Skip to content

Commit

Permalink
OpenBSD: add support for CPU frequency (#2057)
Browse files Browse the repository at this point in the history
  • Loading branch information
giampaolo authored Jan 16, 2022
1 parent 01f5f1e commit 98b4948
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 31 deletions.
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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**

Expand Down
8 changes: 5 additions & 3 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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):

Expand All @@ -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.
Expand Down
54 changes: 30 additions & 24 deletions psutil/_psbsd.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
# =====================================================================
Expand Down Expand Up @@ -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
Expand Down
7 changes: 4 additions & 3 deletions psutil/_psutil_bsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -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."},
Expand All @@ -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"},
Expand Down
18 changes: 18 additions & 0 deletions psutil/arch/openbsd/cpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions psutil/arch/openbsd/cpu.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@

#include <Python.h>

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);
2 changes: 1 addition & 1 deletion psutil/tests/test_contracts.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down

0 comments on commit 98b4948

Please sign in to comment.