]> granicus.if.org Git - python/commitdiff
Patch #512005: getrusage() returns struct-like object.
authorMartin v. Löwis <martin@v.loewis.de>
Mon, 8 Apr 2002 21:28:20 +0000 (21:28 +0000)
committerMartin v. Löwis <martin@v.loewis.de>
Mon, 8 Apr 2002 21:28:20 +0000 (21:28 +0000)
Doc/lib/libresource.tex
Misc/ACKS
Misc/NEWS
Modules/resource.c

index 33de531947e86cef8ce517aa404ff5a6060a7d36..6ec975b6ff96ac33195b793897ebaec72717597d 100644 (file)
@@ -133,50 +133,56 @@ not be available from this module on that platform.
 
 \subsection{Resource Usage}
 
-These functiona are used to retrieve resource usage information:
+These functions are used to retrieve resource usage information:
 
 \begin{funcdesc}{getrusage}{who}
-  This function returns a large tuple that describes the resources
+  This function returns an object that describes the resources
   consumed by either the current process or its children, as specified
   by the \var{who} parameter.  The \var{who} parameter should be
   specified using one of the \constant{RUSAGE_*} constants described
   below.
 
-  The elements of the return value each
-  describe how a particular system resource has been used, e.g. amount
-  of time spent running is user mode or number of times the process was
-  swapped out of main memory. Some values are dependent on the clock
-  tick internal, e.g. the amount of memory the process is using.
-
-  The first two elements of the return value are floating point values
-  representing the amount of time spent executing in user mode and the
-  amount of time spent executing in system mode, respectively. The
-  remaining values are integers. Consult the \manpage{getrusage}{2}
-  man page for detailed information about these values. A brief
-  summary is presented here:
-
-\begin{tableii}{r|l}{code}{Offset}{Resource}
-  \lineii{0}{time in user mode (float)}
-  \lineii{1}{time in system mode (float)}
-  \lineii{2}{maximum resident set size}
-  \lineii{3}{shared memory size}
-  \lineii{4}{unshared memory size}
-  \lineii{5}{unshared stack size}
-  \lineii{6}{page faults not requiring I/O}
-  \lineii{7}{page faults requiring I/O}
-  \lineii{8}{number of swap outs}
-  \lineii{9}{block input operations}
-  \lineii{10}{block output operations}
-  \lineii{11}{messages sent}
-  \lineii{12}{messages received}
-  \lineii{13}{signals received}
-  \lineii{14}{voluntary context switches}
-  \lineii{15}{involuntary context switches}
-\end{tableii}
+  The fields of the return value each describe how a particular system
+  resource has been used, e.g. amount of time spent running is user mode
+  or number of times the process was swapped out of main memory. Some
+  values are dependent on the clock tick internal, e.g. the amount of
+  memory the process is using.
+
+  For backward compatibility, the return value is also accessible as
+  a tuple of 16 elements.
+
+  The fields \member{ru_utime} and \member{ru_stime} of the return value
+  are floating point values representing the amount of time spent
+  executing in user mode and the amount of time spent executing in system
+  mode, respectively. The remaining values are integers. Consult the
+  \manpage{getrusage}{2} man page for detailed information about these
+  values. A brief summary is presented here:
+
+\begin{tableiii}{r|l|l}{code}{Index}{Field}{Resource}
+  \lineiii{0}{\member{ru_utime}}{time in user mode (float)}
+  \lineiii{1}{\member{ru_stime}}{time in system mode (float)}
+  \lineiii{2}{\member{ru_maxrss}}{maximum resident set size}
+  \lineiii{3}{\member{ru_ixrss}}{shared memory size}
+  \lineiii{4}{\member{ru_idrss}}{unshared memory size}
+  \lineiii{5}{\member{ru_isrss}}{unshared stack size}
+  \lineiii{6}{\member{ru_minflt}}{page faults not requiring I/O}
+  \lineiii{7}{\member{ru_majflt}}{page faults requiring I/O}
+  \lineiii{8}{\member{ru_nswap}}{number of swap outs}
+  \lineiii{9}{\member{ru_inblock}}{block input operations}
+  \lineiii{10}{\member{ru_oublock}}{block output operations}
+  \lineiii{11}{\member{ru_msgsnd}}{messages sent}
+  \lineiii{12}{\member{ru_msgrcv}}{messages received}
+  \lineiii{13}{\member{ru_nsignals}}{signals received}
+  \lineiii{14}{\member{ru_nvcsw}}{voluntary context switches}
+  \lineiii{15}{\member{ru_nivcsw}}{involuntary context switches}
+\end{tableiii}
 
   This function will raise a \exception{ValueError} if an invalid
   \var{who} parameter is specified. It may also raise
   \exception{error} exception in unusual circumstances.
+
+  \versionchanged[Added access to values as attributes of the
+  returned object]{2.3}
 \end{funcdesc}
 
 \begin{funcdesc}{getpagesize}{}
index 4f5ea8d8a3cae65c425c2d7f438b80a1e91c2e11..1e69c7aae7419a0fe8bc707a97f1536c36b69d9a 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -413,6 +413,7 @@ Joel Shprentz
 Itamar Shtull-Trauring
 Eric Siegerman
 Paul Sijben
+Kirill Simonov
 Nathan Paul Simons
 Janne Sinkkonen
 George Sipe
index bb5792cd662a36ffdcacd585da433b6175c74f69..cd61d0ee62e7780eac9764906462ac5a285dbd88 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -56,7 +56,8 @@ Extension modules
   hole was quickly plugged in zlib-1.1.4, and the Windows build of
   Python now ships with zlib-1.1.4.
 
-- pwd and grp return enhanced tuples now, with symbolic field names.
+- pwd, grp, and resource return enhanced tuples now, with symbolic
+  field names.
 
 - array.array is now a type object. A new format character
   'u' indicates Py_UNICODE arrays. For those, .tounicode and
index ecd992ed2bb31d3b90a3315a1a0211d873c8db4d..4d8d4faa014c9be7c2806b47a2e97ea64c98c47d 100644 (file)
@@ -1,5 +1,6 @@
 
 #include "Python.h"
+#include "structseq.h"
 #include <sys/resource.h>
 #include <sys/time.h>
 #include <string.h>
 
 static PyObject *ResourceError;
 
+static char struct_rusage__doc__[] =
+       "struct_rusage: Result from getrusage.\n\n"
+       "This object may be accessed either as a tuple of\n"
+       "    (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
+       "    nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
+       "or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.\n";
+
+static PyStructSequence_Field struct_rusage_fields[] = {
+       {"ru_utime",    "user time used"},
+       {"ru_stime",    "system time used"},
+       {"ru_maxrss",   "max. resident set size"},
+       {"ru_ixrss",    "shared memory size"},
+       {"ru_idrss",    "unshared data size"},
+       {"ru_isrss",    "unshared stack size"},
+       {"ru_minflt",   "page faults not requiring I/O"},
+       {"ru_majflt",   "page faults requiring I/O"},
+       {"ru_nswap",    "number of swap outs"},
+       {"ru_inblock",  "block input operations"},
+       {"ru_oublock",  "block output operations"},
+       {"ru_msgsnd",   "IPC messages sent"},
+       {"ru_msgrcv",   "IPC messages received"},
+       {"ru_nsignals", "signals received"},
+       {"ru_nvcsw",    "voluntary context switches"},
+       {"ru_nivcsw",   "involuntary context switches"},
+       {0}
+};
+
+static PyStructSequence_Desc struct_rusage_desc = {
+       "resource.struct_rusage",       /* name */
+       struct_rusage__doc__,   /* doc */
+       struct_rusage_fields,   /* fields */
+       16      /* n_in_sequence */
+};
+
+static PyTypeObject StructRUsageType;
+
 static PyObject *
 resource_getrusage(PyObject *self, PyObject *args)
 {
        int who;
        struct rusage ru;
+       PyObject *result;
 
        if (!PyArg_ParseTuple(args, "i:getrusage", &who))
                return NULL;
@@ -35,29 +73,35 @@ resource_getrusage(PyObject *self, PyObject *args)
                return NULL;
        }
 
-       /* Yeah, this 16-tuple is way ugly. It's probably a lot less
-          ugly than a dictionary with keys (or object attributes)
-          named things like 'ixrss'. 
-          */
-       return Py_BuildValue(
-               "ddiiiiiiiiiiiiii",
-               doubletime(ru.ru_utime),     /* user time used */
-               doubletime(ru.ru_stime),     /* system time used */
-               ru.ru_maxrss,                /* max. resident set size */
-               ru.ru_ixrss,                 /* shared memory size */
-               ru.ru_idrss,                 /* unshared memory size */
-               ru.ru_isrss,                 /* unshared stack size */
-               ru.ru_minflt,                /* page faults not requiring I/O*/
-               ru.ru_majflt,                /* page faults requiring I/O */
-               ru.ru_nswap,                 /* number of swap outs */
-               ru.ru_inblock,               /* block input operations */
-               ru.ru_oublock,               /* block output operations */
-               ru.ru_msgsnd,                /* messages sent */
-               ru.ru_msgrcv,                /* messages received */
-               ru.ru_nsignals,              /* signals received */
-               ru.ru_nvcsw,                 /* voluntary context switches */
-               ru.ru_nivcsw                 /* involuntary context switches */
-               );
+       result = PyStructSequence_New(&StructRUsageType);
+       if (!result)
+               return NULL;
+
+       PyStructSequence_SET_ITEM(result, 0,
+                       PyFloat_FromDouble(doubletime(ru.ru_utime)));
+       PyStructSequence_SET_ITEM(result, 1,
+                       PyFloat_FromDouble(doubletime(ru.ru_stime)));
+       PyStructSequence_SET_ITEM(result, 2, PyInt_FromLong(ru.ru_maxrss));
+       PyStructSequence_SET_ITEM(result, 3, PyInt_FromLong(ru.ru_ixrss));
+       PyStructSequence_SET_ITEM(result, 4, PyInt_FromLong(ru.ru_idrss));
+       PyStructSequence_SET_ITEM(result, 5, PyInt_FromLong(ru.ru_isrss));
+       PyStructSequence_SET_ITEM(result, 6, PyInt_FromLong(ru.ru_minflt));
+       PyStructSequence_SET_ITEM(result, 7, PyInt_FromLong(ru.ru_majflt));
+       PyStructSequence_SET_ITEM(result, 8, PyInt_FromLong(ru.ru_nswap));
+       PyStructSequence_SET_ITEM(result, 9, PyInt_FromLong(ru.ru_inblock));
+       PyStructSequence_SET_ITEM(result, 10, PyInt_FromLong(ru.ru_oublock));
+       PyStructSequence_SET_ITEM(result, 11, PyInt_FromLong(ru.ru_msgsnd));
+       PyStructSequence_SET_ITEM(result, 12, PyInt_FromLong(ru.ru_msgrcv));
+       PyStructSequence_SET_ITEM(result, 13, PyInt_FromLong(ru.ru_nsignals));
+       PyStructSequence_SET_ITEM(result, 14, PyInt_FromLong(ru.ru_nvcsw));
+       PyStructSequence_SET_ITEM(result, 15, PyInt_FromLong(ru.ru_nivcsw));
+
+       if (PyErr_Occurred()) {
+               Py_DECREF(result);
+               return NULL;
+       }
+
+       return result;
 }
 
 
@@ -172,6 +216,9 @@ initresource(void)
        }
        Py_INCREF(ResourceError);
        PyModule_AddObject(m, "error", ResourceError);
+       PyStructSequence_InitType(&StructRUsageType, &struct_rusage_desc);
+       PyModule_AddObject(m, "struct_rusage", 
+                          (PyObject*) &StructRUsageType);
 
        /* insert constants */
 #ifdef RLIMIT_CPU