| Index: third_party/psutil/psutil/_psutil_osx.c
|
| diff --git a/third_party/psutil/psutil/_psutil_osx.c b/third_party/psutil/psutil/_psutil_osx.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..64947a708922ecc306d5a1aeec42bd9d26200517
|
| --- /dev/null
|
| +++ b/third_party/psutil/psutil/_psutil_osx.c
|
| @@ -0,0 +1,689 @@
|
| +/*
|
| + * $Id: _psutil_osx.c 780 2010-11-10 18:42:47Z jloden $
|
| + *
|
| + * OS X platform-specific module methods for _psutil_osx
|
| + */
|
| +
|
| +#include <Python.h>
|
| +#include <assert.h>
|
| +#include <errno.h>
|
| +#include <stdbool.h>
|
| +#include <stdlib.h>
|
| +#include <stdio.h>
|
| +#include <signal.h>
|
| +#include <sys/sysctl.h>
|
| +#include <sys/vmmeter.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/shared_memory_server.h>
|
| +
|
| +#include "_psutil_osx.h"
|
| +#include "arch/osx/process_info.h"
|
| +
|
| +
|
| +/*
|
| + * define the psutil C module methods and initialize the module.
|
| + */
|
| +static PyMethodDef
|
| +PsutilMethods[] =
|
| +{
|
| + // --- per-process functions
|
| +
|
| + {"get_process_name", get_process_name, METH_VARARGS,
|
| + "Return process name"},
|
| + {"get_process_cmdline", get_process_cmdline, METH_VARARGS,
|
| + "Return process cmdline as a list of cmdline arguments"},
|
| + {"get_process_ppid", get_process_ppid, METH_VARARGS,
|
| + "Return process ppid as an integer"},
|
| + {"get_process_uid", get_process_uid, METH_VARARGS,
|
| + "Return process real user id as an integer"},
|
| + {"get_process_gid", get_process_gid, METH_VARARGS,
|
| + "Return process real group id as an integer"},
|
| + {"get_cpu_times", get_cpu_times, METH_VARARGS,
|
| + "Return tuple of user/kern time for the given PID"},
|
| + {"get_process_create_time", get_process_create_time, METH_VARARGS,
|
| + "Return a float indicating the process create time expressed in "
|
| + "seconds since the epoch"},
|
| + {"get_memory_info", get_memory_info, METH_VARARGS,
|
| + "Return a tuple of RSS/VMS memory information"},
|
| + {"get_process_num_threads", get_process_num_threads, METH_VARARGS,
|
| + "Return number of threads used by process"},
|
| +
|
| + // --- system-related functions
|
| +
|
| + {"get_pid_list", get_pid_list, METH_VARARGS,
|
| + "Returns a list of PIDs currently running on the system"},
|
| + {"get_num_cpus", get_num_cpus, METH_VARARGS,
|
| + "Return number of CPUs on the system"},
|
| + {"get_total_phymem", get_total_phymem, METH_VARARGS,
|
| + "Return the total amount of physical memory, in bytes"},
|
| + {"get_avail_phymem", get_avail_phymem, METH_VARARGS,
|
| + "Return the amount of available physical memory, in bytes"},
|
| + {"get_total_virtmem", get_total_virtmem, METH_VARARGS,
|
| + "Return the total amount of virtual memory, in bytes"},
|
| + {"get_avail_virtmem", get_avail_virtmem, METH_VARARGS,
|
| + "Return the amount of available virtual memory, in bytes"},
|
| + {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
|
| + "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
|
| +
|
| + {NULL, NULL, 0, NULL}
|
| +};
|
| +
|
| +
|
| +/*
|
| + * Raises an OSError(errno=ESRCH, strerror="No such process") exception
|
| + * in Python.
|
| + */
|
| +static PyObject*
|
| +NoSuchProcess(void) {
|
| + errno = ESRCH;
|
| + return PyErr_SetFromErrno(PyExc_OSError);
|
| +}
|
| +
|
| +/*
|
| + * Raises an OSError(errno=EPERM, strerror="Operation not permitted") exception
|
| + * in Python.
|
| + */
|
| +static PyObject*
|
| +AccessDenied(void) {
|
| + errno = EPERM;
|
| + return PyErr_SetFromErrno(PyExc_OSError);
|
| +}
|
| +
|
| +struct module_state {
|
| + PyObject *error;
|
| +};
|
| +
|
| +#if PY_MAJOR_VERSION >= 3
|
| +#define GETSTATE(m) ((struct module_state*)PyModule_GetState(m))
|
| +#else
|
| +#define GETSTATE(m) (&_state)
|
| +static struct module_state _state;
|
| +#endif
|
| +
|
| +#if PY_MAJOR_VERSION >= 3
|
| +
|
| +static int
|
| +psutil_osx_traverse(PyObject *m, visitproc visit, void *arg) {
|
| + Py_VISIT(GETSTATE(m)->error);
|
| + return 0;
|
| +}
|
| +
|
| +static int
|
| +psutil_osx_clear(PyObject *m) {
|
| + Py_CLEAR(GETSTATE(m)->error);
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +static struct PyModuleDef
|
| +moduledef = {
|
| + PyModuleDef_HEAD_INIT,
|
| + "psutil_osx",
|
| + NULL,
|
| + sizeof(struct module_state),
|
| + PsutilMethods,
|
| + NULL,
|
| + psutil_osx_traverse,
|
| + psutil_osx_clear,
|
| + NULL
|
| +};
|
| +
|
| +#define INITERROR return NULL
|
| +
|
| +PyObject *
|
| +PyInit__psutil_osx(void)
|
| +
|
| +#else
|
| +#define INITERROR return
|
| +
|
| +void
|
| +init_psutil_osx(void)
|
| +#endif
|
| +{
|
| +#if PY_MAJOR_VERSION >= 3
|
| + PyObject *module = PyModule_Create(&moduledef);
|
| +#else
|
| + PyObject *module = Py_InitModule("_psutil_osx", PsutilMethods);
|
| +#endif
|
| + if (module == NULL) {
|
| + INITERROR;
|
| + }
|
| + struct module_state *st = GETSTATE(module);
|
| +
|
| + st->error = PyErr_NewException("_psutil_osx.Error", NULL, NULL);
|
| + if (st->error == NULL) {
|
| + Py_DECREF(module);
|
| + INITERROR;
|
| + }
|
| +#if PY_MAJOR_VERSION >= 3
|
| + return module;
|
| +#endif
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python list of all the PIDs running on the system.
|
| + */
|
| +static PyObject*
|
| +get_pid_list(PyObject* self, PyObject* args)
|
| +{
|
| + kinfo_proc *proclist = NULL;
|
| + kinfo_proc *orig_address = NULL;
|
| + size_t num_processes;
|
| + size_t idx;
|
| + PyObject *pid;
|
| + PyObject *retlist = PyList_New(0);
|
| +
|
| + if (get_proc_list(&proclist, &num_processes) != 0) {
|
| + Py_DECREF(retlist);
|
| + PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list.");
|
| + return NULL;
|
| + }
|
| +
|
| + if (num_processes > 0) {
|
| + // save the address of proclist so we can free it later
|
| + orig_address = proclist;
|
| + for (idx=0; idx < num_processes; idx++) {
|
| + pid = Py_BuildValue("i", proclist->kp_proc.p_pid);
|
| + PyList_Append(retlist, pid);
|
| + Py_XDECREF(pid);
|
| + proclist++;
|
| + }
|
| + }
|
| + free(orig_address);
|
| + return retlist;
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return process name from kinfo_proc as a Python string.
|
| + */
|
| +static PyObject*
|
| +get_process_name(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + struct kinfo_proc kp;
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| + if (get_kinfo_proc(pid, &kp) == -1) {
|
| + return NULL;
|
| + }
|
| + return Py_BuildValue("s", kp.kp_proc.p_comm);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return process cmdline as a Python list of cmdline arguments.
|
| + */
|
| +static PyObject*
|
| +get_process_cmdline(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + PyObject* arglist = NULL;
|
| +
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| +
|
| + // get the commandline, defined in arch/osx/process_info.c
|
| + arglist = get_arg_list(pid);
|
| +
|
| + // get_arg_list() returns NULL only if getcmdargs failed with ESRCH
|
| + // (no process with that PID)
|
| + if (NULL == arglist) {
|
| + return PyErr_SetFromErrno(PyExc_OSError);
|
| + }
|
| + return Py_BuildValue("N", arglist);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return process parent pid from kinfo_proc as a Python integer.
|
| + */
|
| +static PyObject*
|
| +get_process_ppid(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + struct kinfo_proc kp;
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| + if (get_kinfo_proc(pid, &kp) == -1) {
|
| + return NULL;
|
| + }
|
| + return Py_BuildValue("l", (long)kp.kp_eproc.e_ppid);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return process real uid from kinfo_proc as a Python integer.
|
| + */
|
| +static PyObject*
|
| +get_process_uid(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + struct kinfo_proc kp;
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| + if (get_kinfo_proc(pid, &kp) == -1) {
|
| + return NULL;
|
| + }
|
| + return Py_BuildValue("l", (long)kp.kp_eproc.e_pcred.p_ruid);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return process real group id from ki_comm as a Python integer.
|
| + */
|
| +static PyObject*
|
| +get_process_gid(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + struct kinfo_proc kp;
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| + if (get_kinfo_proc(pid, &kp) == -1) {
|
| + return NULL;
|
| + }
|
| + return Py_BuildValue("l", (long)kp.kp_eproc.e_pcred.p_rgid);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return 1 if PID exists in the current process list, else 0.
|
| + */
|
| +static int
|
| +pid_exists(long pid) {
|
| + int kill_ret;
|
| +
|
| + // save some time if it's an invalid PID
|
| + if (pid < 0) {
|
| + return 0;
|
| + }
|
| +
|
| + // if kill returns success of permission denied we know it's a valid PID
|
| + kill_ret = kill(pid , 0);
|
| + if ( (0 == kill_ret) || (EPERM == errno) ) {
|
| + return 1;
|
| + }
|
| +
|
| + // otherwise return 0 for PID not found
|
| + return 0;
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python integer indicating the number of CPUs on the system.
|
| + */
|
| +static PyObject*
|
| +get_num_cpus(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) {
|
| + PyErr_SetFromErrno(0);
|
| + return NULL;
|
| + }
|
| +
|
| + return Py_BuildValue("i", ncpu);
|
| +}
|
| +
|
| +
|
| +#define TV2DOUBLE(t) ((t).tv_sec + (t).tv_usec / 1000000.0)
|
| +
|
| +/*
|
| + * Return a Python tuple (user_time, kernel_time)
|
| + */
|
| +static PyObject*
|
| +get_cpu_times(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + int err;
|
| + unsigned int info_count = TASK_BASIC_INFO_COUNT;
|
| + task_port_t task;// = (task_port_t)NULL;
|
| + time_value_t user_time, system_time;
|
| + struct task_basic_info tasks_info;
|
| + struct task_thread_times_info task_times;
|
| +
|
| + // the argument passed should be a process id
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| +
|
| + /* task_for_pid() requires special privileges
|
| + * "This function can be called only if the process is owned by the
|
| + * procmod group or if the caller is root."
|
| + * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html
|
| + */
|
| + err = task_for_pid(mach_task_self(), pid, &task);
|
| + if ( err == KERN_SUCCESS) {
|
| + info_count = TASK_BASIC_INFO_COUNT;
|
| + err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count);
|
| + if (err != KERN_SUCCESS) {
|
| + if (err == 4) { // errcode 4 is "invalid argument" (access denied)
|
| + return AccessDenied();
|
| + }
|
| +
|
| + //otherwise throw a runtime error with appropriate error code
|
| + return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed for pid %lu - %s (%i)",
|
| + pid, mach_error_string(err), err);
|
| +
|
| + }
|
| +
|
| + info_count = TASK_THREAD_TIMES_INFO_COUNT;
|
| + err = task_info(task, TASK_THREAD_TIMES_INFO, (task_info_t)&task_times, &info_count);
|
| + if (err != KERN_SUCCESS) {
|
| + if (err == 4) { // errcode 4 is "invalid argument" (access denied)
|
| + return AccessDenied();
|
| + }
|
| +
|
| + return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_THREAD_TIMES_INFO) failed for pid %lu - %s (%i)",
|
| + pid, mach_error_string(err), err);
|
| + }
|
| + }
|
| +
|
| + else { // task_for_pid failed
|
| + if (! pid_exists(pid) ) {
|
| + return NoSuchProcess();
|
| + }
|
| +
|
| + // pid exists, so return AccessDenied error since task_for_pid() failed
|
| + return AccessDenied();
|
| + }
|
| +
|
| + float user_t = -1.0;
|
| + float sys_t = -1.0;
|
| + user_time = tasks_info.user_time;
|
| + system_time = tasks_info.system_time;
|
| +
|
| + time_value_add(&user_time, &task_times.user_time);
|
| + time_value_add(&system_time, &task_times.system_time);
|
| +
|
| + user_t = (float)user_time.seconds + ((float)user_time.microseconds / 1000000.0);
|
| + sys_t = (float)system_time.seconds + ((float)system_time.microseconds / 1000000.0);
|
| + return Py_BuildValue("(dd)", user_t, sys_t);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python float indicating the process create time expressed in
|
| + * seconds since the epoch.
|
| + */
|
| +static PyObject*
|
| +get_process_create_time(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + struct kinfo_proc kp;
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| + if (get_kinfo_proc(pid, &kp) == -1) {
|
| + return NULL;
|
| + }
|
| + return Py_BuildValue("d", TV2DOUBLE(kp.kp_proc.p_starttime));
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a tuple of RSS and VMS memory usage.
|
| + */
|
| +static PyObject*
|
| +get_memory_info(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + int err;
|
| + unsigned int info_count = TASK_BASIC_INFO_COUNT;
|
| + mach_port_t task;
|
| + struct task_basic_info tasks_info;
|
| + vm_region_basic_info_data_64_t b_info;
|
| + vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT;
|
| + vm_size_t size;
|
| + mach_port_t object_name;
|
| +
|
| + // the argument passed should be a process id
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| +
|
| + /* task_for_pid() requires special privileges
|
| + * "This function can be called only if the process is owned by the
|
| + * procmod group or if the caller is root."
|
| + * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html
|
| + */
|
| + err = task_for_pid(mach_task_self(), pid, &task);
|
| + if ( err == KERN_SUCCESS) {
|
| + info_count = TASK_BASIC_INFO_COUNT;
|
| + err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count);
|
| + if (err != KERN_SUCCESS) {
|
| + if (err == 4) { // errcode 4 is "invalid argument" (access denied)
|
| + return AccessDenied();
|
| + }
|
| +
|
| + //otherwise throw a runtime error with appropriate error code
|
| + return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed for pid %lu - %s (%i)",
|
| + pid, mach_error_string(err), err);
|
| + }
|
| +
|
| + /* Issue #73 http://code.google.com/p/psutil/issues/detail?id=73
|
| + * adjust the virtual memory size down to account for
|
| + * shared memory that task_info.virtual_size includes w/every process
|
| + */
|
| + info_count = VM_REGION_BASIC_INFO_COUNT_64;
|
| + err = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO,
|
| + (vm_region_info_t)&b_info, &info_count, &object_name);
|
| + if (err == KERN_SUCCESS) {
|
| + if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) &&
|
| + tasks_info.virtual_size > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) {
|
| + tasks_info.virtual_size -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE);
|
| + }
|
| + }
|
| + }
|
| +
|
| + else {
|
| + if (! pid_exists(pid) ) {
|
| + return NoSuchProcess();
|
| + }
|
| +
|
| + // pid exists, so return AccessDenied error since task_for_pid() failed
|
| + return AccessDenied();
|
| + }
|
| +
|
| + return Py_BuildValue("(ll)", tasks_info.resident_size, tasks_info.virtual_size);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return number of threads used by process as a Python integer.
|
| + */
|
| +static PyObject*
|
| +get_process_num_threads(PyObject* self, PyObject* args)
|
| +{
|
| + long pid;
|
| + int err;
|
| + unsigned int info_count = TASK_BASIC_INFO_COUNT;
|
| + mach_port_t task;
|
| + struct task_basic_info tasks_info;
|
| + thread_act_port_array_t thread_list;
|
| + mach_msg_type_number_t thread_count;
|
| +
|
| + // the argument passed should be a process id
|
| + if (! PyArg_ParseTuple(args, "l", &pid)) {
|
| + return NULL;
|
| + }
|
| +
|
| + /* task_for_pid() requires special privileges
|
| + * "This function can be called only if the process is owned by the
|
| + * procmod group or if the caller is root."
|
| + * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html
|
| + */
|
| + err = task_for_pid(mach_task_self(), pid, &task);
|
| + if ( err == KERN_SUCCESS) {
|
| + info_count = TASK_BASIC_INFO_COUNT;
|
| + err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count);
|
| + if (err != KERN_SUCCESS) {
|
| + if (err == 4) { // errcode 4 is "invalid argument" (access denied)
|
| + return AccessDenied();
|
| + }
|
| +
|
| + //otherwise throw a runtime error with appropriate error code
|
| + return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed for pid %lu - %s (%i)",
|
| + pid, mach_error_string(err), err);
|
| + }
|
| +
|
| + err = task_threads(task, &thread_list, &thread_count);
|
| + if (err == KERN_SUCCESS) {
|
| + return Py_BuildValue("l", (long)thread_count);
|
| + }
|
| + }
|
| +
|
| +
|
| + else {
|
| + if (! pid_exists(pid) ) {
|
| + return NoSuchProcess();
|
| + }
|
| +
|
| + // pid exists, so return AccessDenied error since task_for_pid() failed
|
| + return AccessDenied();
|
| + }
|
| + return NULL;
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python integer indicating the total amount of physical memory
|
| + * in bytes.
|
| + */
|
| +static PyObject*
|
| +get_total_phymem(PyObject* self, PyObject* args)
|
| +{
|
| + int mib[2];
|
| + uint64_t total_phymem;
|
| + size_t len;
|
| +
|
| + mib[0] = CTL_HW;
|
| + mib[1] = HW_MEMSIZE;
|
| + len = sizeof(total_phymem);
|
| +
|
| + if (sysctl(mib, 2, &total_phymem, &len, NULL, 0) == -1) {
|
| + PyErr_SetFromErrno(0);
|
| + return NULL;
|
| + }
|
| +
|
| + return Py_BuildValue("L", total_phymem);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python long indicating the amount of available physical memory in
|
| + * bytes.
|
| + */
|
| +static PyObject*
|
| +get_avail_phymem(PyObject* self, PyObject* args)
|
| +{
|
| + vm_statistics_data_t vm_stat;
|
| + mach_msg_type_number_t count;
|
| + kern_return_t error;
|
| + unsigned long long mem_free;
|
| + int pagesize = getpagesize();
|
| + mach_port_t mport = mach_host_self();
|
| +
|
| + count = sizeof(vm_stat) / sizeof(natural_t);
|
| + error = host_statistics(mport, HOST_VM_INFO, (host_info_t)&vm_stat, &count);
|
| +
|
| + if (error != KERN_SUCCESS) {
|
| + return PyErr_Format(PyExc_RuntimeError,
|
| + "Error in host_statistics(): %s", mach_error_string(error));
|
| + }
|
| +
|
| + mem_free = (unsigned long long) vm_stat.free_count * pagesize;
|
| + return Py_BuildValue("L", mem_free);
|
| +}
|
| +
|
| +
|
| +/*
|
| + * Return a Python integer indicating the total amount of virtual memory
|
| + * in bytes.
|
| + */
|
| +static PyObject*
|
| +get_total_virtmem(PyObject* self, PyObject* args)
|
| +{
|
| + int mib[2];
|
| + size_t size;
|
| + struct xsw_usage totals;
|
| +
|
| + mib[0] = CTL_VM;
|
| + mib[1] = VM_SWAPUSAGE;
|
| + size = sizeof(totals);
|
| +
|
| + if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) {
|
| + PyErr_SetFromErrno(0);
|
| + return NULL;
|
| + }
|
| +
|
| + return Py_BuildValue("L", totals.xsu_total);
|
| +}
|
| +
|
| +/*
|
| + * Return a Python integer indicating the avail amount of virtual memory
|
| + * in bytes.
|
| + */
|
| +static PyObject*
|
| +get_avail_virtmem(PyObject* self, PyObject* args)
|
| +{
|
| + int mib[2];
|
| + size_t size;
|
| + struct xsw_usage totals;
|
| +
|
| + mib[0] = CTL_VM;
|
| + mib[1] = VM_SWAPUSAGE;
|
| + size = sizeof(totals);
|
| +
|
| + if (sysctl(mib, 2, &totals, &size, NULL, 0) == -1) {
|
| + PyErr_SetFromErrno(0);
|
| + return NULL;
|
| + }
|
| +
|
| + return Py_BuildValue("L", totals.xsu_avail);
|
| +}
|
| +
|
| +/*
|
| + * Return a Python tuple representing user, kernel and idle CPU times
|
| + */
|
| +static PyObject*
|
| +get_system_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;
|
| +
|
| + error = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&r_load, &count);
|
| + if (error != KERN_SUCCESS) {
|
| + return PyErr_Format(PyExc_RuntimeError,
|
| + "Error in host_statistics(): %s", mach_error_string(error));
|
| + }
|
| +
|
| + //user, nice, system, idle, iowait, irqm, softirq
|
| + 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
|
| + );
|
| +}
|
| +
|
|
|