From 6ba1ac4ebfcd8c95fca324b15606ab0ec1412d39 Mon Sep 17 00:00:00 2001 From: Giampaolo Rodola Date: Sat, 3 Dec 2016 18:05:07 +0100 Subject: [PATCH] #941: implement cpu_freq() for OSX --- psutil/_pslinux.py | 2 -- psutil/_psosx.py | 5 +++++ psutil/_psutil_osx.c | 31 +++++++++++++++++++++++++++++++ psutil/tests/test_osx.py | 15 +++++++++++++++ psutil/tests/test_system.py | 3 ++- 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/psutil/_pslinux.py b/psutil/_pslinux.py index add06a11d..e073b06e0 100644 --- a/psutil/_pslinux.py +++ b/psutil/_pslinux.py @@ -628,8 +628,6 @@ def cpu_freq(): # scaling_* files seem preferable to cpuinfo_*, see: # http://unix.stackexchange.com/a/87537/168884 ret = [] - # XXX - print(os.listdir("/sys/devices/system/cpu/cpufreq/")) ls = glob.glob("/sys/devices/system/cpu/cpufreq/policy*") # Sort the list so that '10' comes after '2'. This should # ensure the CPU order is consistent with other CPU functions diff --git a/psutil/_psosx.py b/psutil/_psosx.py index 2665080e0..0778b5fb7 100644 --- a/psutil/_psosx.py +++ b/psutil/_psosx.py @@ -165,6 +165,11 @@ def cpu_stats(): ctx_switches, interrupts, soft_interrupts, syscalls) +def cpu_freq(): + curr, min_, max_ = cext.cpu_freq() + return [_common.scpufreq(curr, min_, max_)] + + # ===================================================================== # --- disks # ===================================================================== diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c index a1168c291..fb26dc9b4 100644 --- a/psutil/_psutil_osx.c +++ b/psutil/_psutil_osx.c @@ -808,6 +808,35 @@ psutil_per_cpu_times(PyObject *self, PyObject *args) { } +/* + * Retrieve CPU frequency. + */ +static PyObject * +psutil_cpu_freq(PyObject *self, PyObject *args) { + int64_t curr; + int64_t min; + int64_t max; + size_t size = sizeof(int64_t); + + if (sysctlbyname("hw.cpufrequency", &curr, &size, NULL, 0)) + goto error; + if (sysctlbyname("hw.cpufrequency_min", &min, &size, NULL, 0)) + goto error; + if (sysctlbyname("hw.cpufrequency_max", &max, &size, NULL, 0)) + goto error; + + return Py_BuildValue( + "KKK", + curr / 1000 / 1000, + min / 1000 / 1000, + max / 1000 / 1000); + +error: + PyErr_SetFromErrno(PyExc_OSError); + return NULL; +} + + /* * Return a Python float indicating the system boot time expressed in * seconds since the epoch. @@ -1778,6 +1807,8 @@ PsutilMethods[] = { "Return system cpu times as a tuple (user, system, nice, idle, irc)"}, {"per_cpu_times", psutil_per_cpu_times, METH_VARARGS, "Return system per-cpu times as a list of tuples"}, + {"cpu_freq", psutil_cpu_freq, METH_VARARGS, + "Return cpu current frequency"}, {"boot_time", psutil_boot_time, METH_VARARGS, "Return the system boot time expressed in seconds since the epoch."}, {"disk_partitions", psutil_disk_partitions, METH_VARARGS, diff --git a/psutil/tests/test_osx.py b/psutil/tests/test_osx.py index 7b61bc74a..02fa430b7 100755 --- a/psutil/tests/test_osx.py +++ b/psutil/tests/test_osx.py @@ -111,6 +111,8 @@ def test_process_create_time(self): @unittest.skipUnless(OSX, "OSX only") class TestSystemAPIs(unittest.TestCase): + # --- disk + def test_disks(self): # test psutil.disk_usage() and psutil.disk_partitions() # against "df -a" @@ -138,6 +140,8 @@ def df(path): if abs(usage.used - used) > 10 * 1024 * 1024: self.fail("psutil=%s, df=%s" % usage.used, used) + # --- cpu + def test_cpu_count_logical(self): num = sysctl("sysctl hw.logicalcpu") self.assertEqual(num, psutil.cpu_count(logical=True)) @@ -146,6 +150,15 @@ def test_cpu_count_physical(self): num = sysctl("sysctl hw.physicalcpu") self.assertEqual(num, psutil.cpu_count(logical=False)) + def test_cpu_freq(self): + freq = psutil.cpu_freq()[0] + self.assertEqual( + freq.curr * 1000 * 1000, sysctl("sysctl hw.cpufrequency")) + self.assertEqual( + freq.min * 1000 * 1000, sysctl("sysctl hw.cpufrequency_min")) + self.assertEqual( + freq.max * 1000 * 1000, sysctl("sysctl hw.cpufrequency_max")) + # --- virtual mem def test_vmem_total(self): @@ -206,6 +219,8 @@ def test_swapmem_sout(self): # self.assertEqual(psutil_smem.used, human2bytes(used)) # self.assertEqual(psutil_smem.free, human2bytes(free)) + # --- network + def test_net_if_stats(self): for name, stats in psutil.net_if_stats().items(): try: diff --git a/psutil/tests/test_system.py b/psutil/tests/test_system.py index ac63dc7cc..d1b81838b 100755 --- a/psutil/tests/test_system.py +++ b/psutil/tests/test_system.py @@ -701,7 +701,8 @@ def test_cpu_stats(self): "platform not suported") def test_cpu_freq(self): ls = psutil.cpu_freq() - assert ls, ls + if not TRAVIS: + assert ls, ls for nt in ls: for name in nt._fields: value = getattr(nt, name)