diff options
Diffstat (limited to 'psutil/arch/osx/cpu.c')
-rw-r--r-- | psutil/arch/osx/cpu.c | 71 |
1 files changed, 67 insertions, 4 deletions
diff --git a/psutil/arch/osx/cpu.c b/psutil/arch/osx/cpu.c index 6e564718..a1ba1142 100644 --- a/psutil/arch/osx/cpu.c +++ b/psutil/arch/osx/cpu.c @@ -19,18 +19,18 @@ For reference, here's the git history with original implementations: */ #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 <mach/mach_vm.h> +#include <sys/sysctl.h> +#include <sys/vmmeter.h> +#include <mach/mach.h> #include "../../_psutil_common.h" #include "../../_psutil_posix.h" - PyObject * psutil_cpu_count_logical(PyObject *self, PyObject *args) { int num; @@ -138,3 +138,66 @@ psutil_cpu_freq(PyObject *self, PyObject *args) { min / 1000 / 1000, max / 1000 / 1000); } + + +PyObject * +psutil_per_cpu_times(PyObject *self, PyObject *args) { + natural_t cpu_count; + natural_t i; + processor_info_array_t info_array; + mach_msg_type_number_t info_count; + kern_return_t error; + processor_cpu_load_info_data_t *cpu_load_info = NULL; + int ret; + PyObject *py_retlist = PyList_New(0); + PyObject *py_cputime = NULL; + + if (py_retlist == NULL) + return NULL; + + mach_port_t host_port = mach_host_self(); + error = host_processor_info(host_port, PROCESSOR_CPU_LOAD_INFO, + &cpu_count, &info_array, &info_count); + if (error != KERN_SUCCESS) { + PyErr_Format( + PyExc_RuntimeError, + "host_processor_info(PROCESSOR_CPU_LOAD_INFO) syscall failed: %s", + mach_error_string(error)); + goto error; + } + mach_port_deallocate(mach_task_self(), host_port); + + cpu_load_info = (processor_cpu_load_info_data_t *) info_array; + + for (i = 0; i < cpu_count; i++) { + py_cputime = Py_BuildValue( + "(dddd)", + (double)cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / CLK_TCK, + (double)cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / CLK_TCK, + (double)cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK, + (double)cpu_load_info[i].cpu_ticks[CPU_STATE_IDLE] / CLK_TCK + ); + if (!py_cputime) + goto error; + if (PyList_Append(py_retlist, py_cputime)) + goto error; + Py_CLEAR(py_cputime); + } + + ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array, + info_count * sizeof(int)); + if (ret != KERN_SUCCESS) + PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2); + return py_retlist; + +error: + Py_XDECREF(py_cputime); + Py_DECREF(py_retlist); + if (cpu_load_info != NULL) { + ret = vm_deallocate(mach_task_self(), (vm_address_t)info_array, + info_count * sizeof(int)); + if (ret != KERN_SUCCESS) + PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2); + } + return NULL; +} |