summaryrefslogtreecommitdiff
path: root/psutil/arch/osx/cpu.c
diff options
context:
space:
mode:
Diffstat (limited to 'psutil/arch/osx/cpu.c')
-rw-r--r--psutil/arch/osx/cpu.c71
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;
+}