Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1471)

Unified Diff: third_party/psutil/psutil/_psutil_bsd.c

Issue 6246123: Moving psutil to third_party. This is first step for Media Performance test project. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: modification based on code review's comments Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « third_party/psutil/psutil/_psutil_bsd.h ('k') | third_party/psutil/psutil/_psutil_mswindows.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/psutil/psutil/_psutil_bsd.c
diff --git a/third_party/psutil/psutil/_psutil_bsd.c b/third_party/psutil/psutil/_psutil_bsd.c
new file mode 100644
index 0000000000000000000000000000000000000000..7586d9f1f54f5763aaad96dc270914186adb1310
--- /dev/null
+++ b/third_party/psutil/psutil/_psutil_bsd.c
@@ -0,0 +1,566 @@
+/*
+ * $Id: _psutil_bsd.c 780 2010-11-10 18:42:47Z jloden $
+ *
+ * FreeBSD platform-specific module methods for _psutil_bsd
+ */
+
+#include <Python.h>
+#include <assert.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#include <sys/param.h>
+#include <sys/user.h>
+#include <sys/proc.h>
+#include <sys/vmmeter.h> /* needed for vmtotal struct */
+
+#include "_psutil_bsd.h"
+#include "arch/bsd/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}
+};
+
+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_bsd_traverse(PyObject *m, visitproc visit, void *arg) {
+ Py_VISIT(GETSTATE(m)->error);
+ return 0;
+}
+
+static int
+psutil_bsd_clear(PyObject *m) {
+ Py_CLEAR(GETSTATE(m)->error);
+ return 0;
+}
+
+static struct PyModuleDef
+moduledef = {
+ PyModuleDef_HEAD_INIT,
+ "psutil_bsd",
+ NULL,
+ sizeof(struct module_state),
+ PsutilMethods,
+ NULL,
+ psutil_bsd_traverse,
+ psutil_bsd_clear,
+ NULL
+};
+
+#define INITERROR return NULL
+
+PyObject *
+PyInit__psutil_bsd(void)
+
+#else
+#define INITERROR return
+
+void init_psutil_bsd(void)
+#endif
+{
+#if PY_MAJOR_VERSION >= 3
+ PyObject *module = PyModule_Create(&moduledef);
+#else
+ PyObject *module = Py_InitModule("_psutil_bsd", PsutilMethods);
+#endif
+ if (module == NULL) {
+ INITERROR;
+ }
+ struct module_state *st = GETSTATE(module);
+
+ st->error = PyErr_NewException("_psutil_bsd.Error", NULL, NULL);
+ if (st->error == NULL) {
+ Py_DECREF(module);
+ INITERROR;
+ }
+#if PY_MAJOR_VERSION >= 3
+ return module;
+#endif
+}
+
+
+/*
+ * Utility function which fills a kinfo_proc struct based on process pid
+ */
+static int
+get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
+{
+ int mib[4];
+ size_t size;
+ mib[0] = CTL_KERN;
+ mib[1] = KERN_PROC;
+ mib[2] = KERN_PROC_PID;
+ mib[3] = pid;
+
+ size = sizeof(struct kinfo_proc);
+
+ if (sysctl((int*)mib, 4, proc, &size, NULL, 0) == -1) {
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+
+ /*
+ * sysctl stores 0 in the size if we can't find the process information.
+ * Set errno to ESRCH which will be translated in NoSuchProcess later on.
+ */
+ if (size == 0) {
+ errno = ESRCH;
+ PyErr_SetFromErrno(PyExc_OSError);
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * 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* retlist = PyList_New(0);
+ PyObject* pid;
+
+ 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) {
+ orig_address = proclist; // save so we can free it after we're done
+ for (idx=0; idx < num_processes; idx++) {
+ pid = Py_BuildValue("i", proclist->ki_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.ki_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/bsd/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.ki_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.ki_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.ki_rgid);
+}
+
+
+/*
+ * Return number of threads used by process as a Python integer.
+ */
+static PyObject*
+get_process_num_threads(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.ki_numthreads);
+}
+
+
+
+// convert a timeval struct to a double
+#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;
+ double user_t, sys_t;
+ struct kinfo_proc kp;
+ if (! PyArg_ParseTuple(args, "l", &pid)) {
+ return NULL;
+ }
+ if (get_kinfo_proc(pid, &kp) == -1) {
+ return NULL;
+ }
+ // convert from microseconds to seconds
+ user_t = TV2DOUBLE(kp.ki_rusage.ru_utime);
+ sys_t = TV2DOUBLE(kp.ki_rusage.ru_stime);
+ return Py_BuildValue("(dd)", user_t, sys_t);
+}
+
+
+/*
+ * 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);
+}
+
+
+/*
+ * 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.ki_start));
+}
+
+
+/*
+ * Return the RSS and VMS as a Python tuple.
+ */
+static PyObject*
+get_memory_info(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("(ll)", ptoa(kp.ki_rssize), (long)kp.ki_size);
+}
+
+
+/*
+ * Return a Python integer indicating the total amount of physical memory
+ * in bytes.
+ */
+static PyObject*
+get_total_phymem(PyObject* self, PyObject* args)
+{
+ long total_phymem;
+ int mib[2];
+ size_t len;
+
+ mib[0] = CTL_HW;
+ mib[1] = HW_PHYSMEM;
+ 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)
+{
+ unsigned long v_inactive_count = 0;
+ unsigned long v_cache_count = 0;
+ unsigned long v_free_count = 0;
+ long total_mem = 0;
+ long long avail_mem = 0;
+ size_t size = sizeof(unsigned long);
+ size_t psize = sizeof(total_mem);
+ int pagesize = getpagesize();
+
+ if (sysctlbyname("hw.physmem", &total_mem, &psize, NULL, 0) == -1) {
+ PyErr_SetFromErrno(0);
+ return NULL;
+ }
+
+ if (sysctlbyname("vm.stats.vm.v_inactive_count", &v_inactive_count,
+ &size, NULL, 0) == -1) {
+ PyErr_SetFromErrno(0);
+ return NULL;
+ }
+
+ if (sysctlbyname("vm.stats.vm.v_cache_count",
+ &v_cache_count, &size, NULL, 0) == -1) {
+ PyErr_SetFromErrno(0);
+ return NULL;
+ }
+
+ if (sysctlbyname("vm.stats.vm.v_free_count",
+ &v_free_count, &size, NULL, 0) == -1) {
+ PyErr_SetFromErrno(0);
+ return NULL;
+ }
+
+ avail_mem = (v_inactive_count + v_cache_count + v_free_count) * pagesize;
+ // used_mem = total_mem - avail_mem;
+
+ return Py_BuildValue("L", avail_mem);
+}
+
+
+/*
+ * Return a Python long indicating the total amount of virtual memory
+ * in bytes.
+ */
+static PyObject*
+get_total_virtmem(PyObject* self, PyObject* args)
+{
+ int mib[2];
+ struct vmtotal vm;
+ size_t size;
+ long long total_vmem;
+
+ mib[0] = CTL_VM;
+ mib[1] = VM_METER;
+ size = sizeof(vm);
+ sysctl(mib, 2, &vm, &size, NULL, 0);
+
+ // vmtotal struct:
+ // http://fxr.watson.org/fxr/source/sys/vmmeter.h?v=FREEBSD54
+ // note: value is returned in page, so we must multiply by size of a page
+ total_vmem = (long long)vm.t_vm * (long long)getpagesize();
+ return Py_BuildValue("L", total_vmem);
+}
+
+
+/*
+ * Return a Python long indicating the avail amount of virtual memory
+ * in bytes.
+ */
+static PyObject*
+get_avail_virtmem(PyObject* self, PyObject* args)
+{
+ int mib[2];
+ struct vmtotal vm;
+ size_t size;
+ long long total_vmem;
+ long long avail_vmem;
+
+ mib[0] = CTL_VM;
+ mib[1] = VM_METER;
+ size = sizeof(vm);
+ sysctl(mib, 2, &vm, &size, NULL, 0);
+
+ // vmtotal struct:
+ // http://fxr.watson.org/fxr/source/sys/vmmeter.h?v=FREEBSD54
+ // note: value is returned in page, so we must multiply by size of a page
+ total_vmem = (long long)vm.t_vm * (long long)getpagesize();
+ avail_vmem = total_vmem - ((long long)vm.t_avm * (long long)getpagesize());
+ return Py_BuildValue("L", avail_vmem);
+}
+
+
+/*
+ * Return a Python tuple representing user, kernel and idle CPU times
+ */
+static PyObject*
+get_system_cpu_times(PyObject* self, PyObject* args)
+{
+ long cpu_time[CPUSTATES];
+ size_t size;
+
+ size = sizeof(cpu_time);
+
+ if (sysctlbyname("kern.cp_time", &cpu_time, &size, NULL, 0) == -1) {
+ PyErr_SetFromErrno(0);
+ return NULL;
+ }
+
+ /*
+ #define CP_USER 0
+ #define CP_NICE 1
+ #define CP_SYS 2
+ #define CP_INTR 3
+ #define CP_IDLE 4
+ #define CPUSTATES 5
+ */
+ //user, nice, system, idle, iowait, irqm, softirq
+ return Py_BuildValue("(ddddd)",
+ (double)cpu_time[CP_USER] / CLOCKS_PER_SEC,
+ (double)cpu_time[CP_NICE] / CLOCKS_PER_SEC,
+ (double)cpu_time[CP_SYS] / CLOCKS_PER_SEC,
+ (double)cpu_time[CP_IDLE] / CLOCKS_PER_SEC,
+ (double)cpu_time[CP_INTR] / CLOCKS_PER_SEC
+ );
+}
+
« no previous file with comments | « third_party/psutil/psutil/_psutil_bsd.h ('k') | third_party/psutil/psutil/_psutil_mswindows.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698