summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGiampaolo Rodola <g.rodola@gmail.com>2020-12-21 22:53:56 +0100
committerGitHub <noreply@github.com>2020-12-21 22:53:56 +0100
commit03211cf6b1ec529c8e6cb4b528658547a01d645b (patch)
treec210f62308055181e40c2e47a8122db015d5874f
parenta4c0a0eb0d2a872ab7a45e47fcf37ef1fde5b012 (diff)
downloadpsutil-03211cf6b1ec529c8e6cb4b528658547a01d645b.tar.gz
Refactor macOS CPU code (#1896)
-rw-r--r--psutil/_psutil_osx.c149
-rw-r--r--psutil/arch/osx/cpu.c140
-rw-r--r--psutil/arch/osx/cpu.h13
-rwxr-xr-xsetup.py1
4 files changed, 156 insertions, 147 deletions
diff --git a/psutil/_psutil_osx.c b/psutil/_psutil_osx.c
index b5aa7653..62a95774 100644
--- a/psutil/_psutil_osx.c
+++ b/psutil/_psutil_osx.c
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
+ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*
@@ -14,7 +14,6 @@
#include <stdio.h>
#include <utmpx.h>
#include <sys/sysctl.h>
-#include <sys/vmmeter.h>
#include <libproc.h>
#include <sys/proc_info.h>
#include <netinet/tcp_fsm.h>
@@ -22,13 +21,7 @@
#include <net/if_dl.h>
#include <pwd.h>
#include <unistd.h>
-
#include <mach/mach.h>
-#include <mach/task.h>
-#include <mach/mach_init.h>
-#include <mach/host_info.h>
-#include <mach/mach_host.h>
-#include <mach/mach_traps.h>
#include <mach/mach_vm.h>
#include <mach/shared_region.h>
@@ -45,6 +38,7 @@
#include "_psutil_common.h"
#include "_psutil_posix.h"
#include "arch/osx/process_info.h"
+#include "arch/osx/cpu.h"
#define PSUTIL_TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
@@ -354,50 +348,6 @@ psutil_proc_environ(PyObject *self, PyObject *args) {
/*
- * Return the number of logical CPUs in the system.
- * XXX this could be shared with BSD.
- */
-static PyObject *
-psutil_cpu_count_logical(PyObject *self, PyObject *args) {
- /*
- int mib[2];
- int ncpu;
- size_t len;
- mib[0] = CTL_HW;
- mib[1] = HW_NCPU;
- len = sizeof(ncpu);
-
- if (sysctl(mib, 2, &ncpu, &len, NULL, 0) == -1)
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("i", ncpu);
- */
- int num;
- size_t size = sizeof(int);
-
- if (sysctlbyname("hw.logicalcpu", &num, &size, NULL, 2))
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("i", num);
-}
-
-
-/*
- * Return the number of CPU cores in the system.
- */
-static PyObject *
-psutil_cpu_count_cores(PyObject *self, PyObject *args) {
- int num;
- size_t size = sizeof(int);
-
- if (sysctlbyname("hw.physicalcpu", &num, &size, NULL, 0))
- Py_RETURN_NONE; // mimic os.cpu_count()
- else
- return Py_BuildValue("i", num);
-}
-
-
-/*
* Indicates if the given virtual address on the given architecture is in the
* shared VM region.
*/
@@ -588,36 +538,6 @@ psutil_swap_mem(PyObject *self, PyObject *args) {
/*
- * Return a Python tuple representing user, kernel and idle CPU times
- */
-static PyObject *
-psutil_cpu_times(PyObject *self, PyObject *args) {
- mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
- kern_return_t error;
- host_cpu_load_info_data_t r_load;
-
- mach_port_t host_port = mach_host_self();
- error = host_statistics(host_port, HOST_CPU_LOAD_INFO,
- (host_info_t)&r_load, &count);
- if (error != KERN_SUCCESS) {
- return PyErr_Format(
- PyExc_RuntimeError,
- "host_statistics(HOST_CPU_LOAD_INFO) syscall failed: %s",
- mach_error_string(error));
- }
- mach_port_deallocate(mach_task_self(), host_port);
-
- return Py_BuildValue(
- "(dddd)",
- (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
- (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
- (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
- (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
- );
-}
-
-
-/*
* Return a Python list of tuple representing per-cpu times
*/
static PyObject *
@@ -684,40 +604,6 @@ error:
/*
- * Retrieve CPU frequency. Note: all of these are static vendor values
- * that never change.
- */
-static PyObject *
-psutil_cpu_freq(PyObject *self, PyObject *args) {
- unsigned int curr;
- int64_t min = 0;
- int64_t max = 0;
- int mib[2];
- size_t len = sizeof(curr);
- size_t size = sizeof(min);
-
- // also availble as "hw.cpufrequency" but it's deprecated
- mib[0] = CTL_HW;
- mib[1] = HW_CPU_FREQ;
-
- if (sysctl(mib, 2, &curr, &len, NULL, 0) < 0)
- return PyErr_SetFromOSErrnoWithSyscall("sysctl(HW_CPU_FREQ)");
-
- if (sysctlbyname("hw.cpufrequency_min", &min, &size, NULL, 0))
- psutil_debug("sysct('hw.cpufrequency_min') failed (set to 0)");
-
- if (sysctlbyname("hw.cpufrequency_max", &max, &size, NULL, 0))
- psutil_debug("sysctl('hw.cpufrequency_min') failed (set to 0)");
-
- return Py_BuildValue(
- "IKK",
- curr / 1000 / 1000,
- min / 1000 / 1000,
- max / 1000 / 1000);
-}
-
-
-/*
* Return a Python float indicating the system boot time expressed in
* seconds since the epoch.
*/
@@ -1635,37 +1521,6 @@ error:
/*
- * Return CPU statistics.
- */
-static PyObject *
-psutil_cpu_stats(PyObject *self, PyObject *args) {
- struct vmmeter vmstat;
- kern_return_t ret;
- mach_msg_type_number_t count = sizeof(vmstat) / sizeof(integer_t);
- mach_port_t mport = mach_host_self();
-
- ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)&vmstat, &count);
- if (ret != KERN_SUCCESS) {
- PyErr_Format(
- PyExc_RuntimeError,
- "host_statistics(HOST_VM_INFO) failed: %s",
- mach_error_string(ret));
- return NULL;
- }
- mach_port_deallocate(mach_task_self(), mport);
-
- return Py_BuildValue(
- "IIIII",
- vmstat.v_swtch, // ctx switches
- vmstat.v_intr, // interrupts
- vmstat.v_soft, // software interrupts
- vmstat.v_syscall, // syscalls
- vmstat.v_trap // traps
- );
-}
-
-
-/*
* Return battery information.
*/
static PyObject *
diff --git a/psutil/arch/osx/cpu.c b/psutil/arch/osx/cpu.c
new file mode 100644
index 00000000..37141a2d
--- /dev/null
+++ b/psutil/arch/osx/cpu.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/*
+System-wide CPU related functions.
+
+Original code was refactored and moved from psutil/_psutil_osx.c in 2020
+right before a4c0a0eb0d2a872ab7a45e47fcf37ef1fde5b012.
+For reference, here's the git history with original implementations:
+
+- CPU count logical: 3d291d425b856077e65163e43244050fb188def1
+- CPU count physical: 4263e354bb4984334bc44adf5dd2f32013d69fba
+- CPU times: 32488bdf54aed0f8cef90d639c1667ffaa3c31c7
+- CPU stat: fa00dfb961ef63426c7818899340866ced8d2418
+- CPU frequency: 6ba1ac4ebfcd8c95fca324b15606ab0ec1412d39
+*/
+
+#include <Python.h>
+#include <sys/sysctl.h>
+#include <sys/vmmeter.h>
+
+#include <mach/mach_error.h>
+#include <mach/mach_host.h>
+#include <mach/mach_port.h>
+
+#include "../../_psutil_common.h"
+#include "../../_psutil_posix.h"
+
+
+
+PyObject *
+psutil_cpu_count_logical(PyObject *self, PyObject *args) {
+ int num;
+ size_t size = sizeof(int);
+
+ if (sysctlbyname("hw.logicalcpu", &num, &size, NULL, 2))
+ Py_RETURN_NONE; // mimic os.cpu_count()
+ else
+ return Py_BuildValue("i", num);
+}
+
+
+PyObject *
+psutil_cpu_count_cores(PyObject *self, PyObject *args) {
+ int num;
+ size_t size = sizeof(int);
+
+ if (sysctlbyname("hw.physicalcpu", &num, &size, NULL, 0))
+ Py_RETURN_NONE; // mimic os.cpu_count()
+ else
+ return Py_BuildValue("i", num);
+}
+
+
+PyObject *
+psutil_cpu_times(PyObject *self, PyObject *args) {
+ mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
+ kern_return_t error;
+ host_cpu_load_info_data_t r_load;
+
+ mach_port_t host_port = mach_host_self();
+ error = host_statistics(host_port, HOST_CPU_LOAD_INFO,
+ (host_info_t)&r_load, &count);
+ if (error != KERN_SUCCESS) {
+ return PyErr_Format(
+ PyExc_RuntimeError,
+ "host_statistics(HOST_CPU_LOAD_INFO) syscall failed: %s",
+ mach_error_string(error));
+ }
+ mach_port_deallocate(mach_task_self(), host_port);
+
+ return Py_BuildValue(
+ "(dddd)",
+ (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
+ (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
+ (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
+ (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
+ );
+}
+
+
+PyObject *
+psutil_cpu_stats(PyObject *self, PyObject *args) {
+ struct vmmeter vmstat;
+ kern_return_t ret;
+ mach_msg_type_number_t count = sizeof(vmstat) / sizeof(integer_t);
+ mach_port_t mport = mach_host_self();
+
+ ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)&vmstat, &count);
+ if (ret != KERN_SUCCESS) {
+ PyErr_Format(
+ PyExc_RuntimeError,
+ "host_statistics(HOST_VM_INFO) failed: %s",
+ mach_error_string(ret));
+ return NULL;
+ }
+ mach_port_deallocate(mach_task_self(), mport);
+
+ return Py_BuildValue(
+ "IIIII",
+ vmstat.v_swtch, // ctx switches
+ vmstat.v_intr, // interrupts
+ vmstat.v_soft, // software interrupts
+ vmstat.v_syscall, // syscalls
+ vmstat.v_trap // traps
+ );
+}
+
+
+PyObject *
+psutil_cpu_freq(PyObject *self, PyObject *args) {
+ unsigned int curr;
+ int64_t min = 0;
+ int64_t max = 0;
+ int mib[2];
+ size_t len = sizeof(curr);
+ size_t size = sizeof(min);
+
+ // also availble as "hw.cpufrequency" but it's deprecated
+ mib[0] = CTL_HW;
+ mib[1] = HW_CPU_FREQ;
+
+ if (sysctl(mib, 2, &curr, &len, NULL, 0) < 0)
+ return PyErr_SetFromOSErrnoWithSyscall("sysctl(HW_CPU_FREQ)");
+
+ if (sysctlbyname("hw.cpufrequency_min", &min, &size, NULL, 0))
+ psutil_debug("sysct('hw.cpufrequency_min') failed (set to 0)");
+
+ if (sysctlbyname("hw.cpufrequency_max", &max, &size, NULL, 0))
+ psutil_debug("sysctl('hw.cpufrequency_min') failed (set to 0)");
+
+ return Py_BuildValue(
+ "IKK",
+ curr / 1000 / 1000,
+ min / 1000 / 1000,
+ max / 1000 / 1000);
+}
diff --git a/psutil/arch/osx/cpu.h b/psutil/arch/osx/cpu.h
new file mode 100644
index 00000000..aac0f809
--- /dev/null
+++ b/psutil/arch/osx/cpu.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include <Python.h>
+
+PyObject *psutil_cpu_count_logical(PyObject *self, PyObject *args);
+PyObject *psutil_cpu_count_cores(PyObject *self, PyObject *args);
+PyObject *psutil_cpu_times(PyObject *self, PyObject *args);
+PyObject *psutil_cpu_freq(PyObject *self, PyObject *args);
+PyObject *psutil_cpu_stats(PyObject *self, PyObject *args);
diff --git a/setup.py b/setup.py
index 90c79c7c..fcf89ae6 100755
--- a/setup.py
+++ b/setup.py
@@ -189,6 +189,7 @@ elif MACOS:
sources=sources + [
'psutil/_psutil_osx.c',
'psutil/arch/osx/process_info.c',
+ 'psutil/arch/osx/cpu.c',
],
define_macros=macros,
extra_link_args=[