diff options
author | Giampaolo Rodola <g.rodola@gmail.com> | 2020-12-21 22:53:56 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-12-21 22:53:56 +0100 |
commit | 03211cf6b1ec529c8e6cb4b528658547a01d645b (patch) | |
tree | c210f62308055181e40c2e47a8122db015d5874f | |
parent | a4c0a0eb0d2a872ab7a45e47fcf37ef1fde5b012 (diff) | |
download | psutil-03211cf6b1ec529c8e6cb4b528658547a01d645b.tar.gz |
Refactor macOS CPU code (#1896)
-rw-r--r-- | psutil/_psutil_osx.c | 149 | ||||
-rw-r--r-- | psutil/arch/osx/cpu.c | 140 | ||||
-rw-r--r-- | psutil/arch/osx/cpu.h | 13 | ||||
-rwxr-xr-x | setup.py | 1 |
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); @@ -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=[ |