Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 688357e

Browse files
committed
Patch #512005: getrusage() returns struct-like object.
1 parent 6cca2f4 commit 688357e

4 files changed

Lines changed: 112 additions & 57 deletions

File tree

Doc/lib/libresource.tex

Lines changed: 39 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -133,50 +133,56 @@ \subsection{Resource Limits}
133133

134134
\subsection{Resource Usage}
135135

136-
These functiona are used to retrieve resource usage information:
136+
These functions are used to retrieve resource usage information:
137137

138138
\begin{funcdesc}{getrusage}{who}
139-
This function returns a large tuple that describes the resources
139+
This function returns an object that describes the resources
140140
consumed by either the current process or its children, as specified
141141
by the \var{who} parameter. The \var{who} parameter should be
142142
specified using one of the \constant{RUSAGE_*} constants described
143143
below.
144144

145-
The elements of the return value each
146-
describe how a particular system resource has been used, e.g. amount
147-
of time spent running is user mode or number of times the process was
148-
swapped out of main memory. Some values are dependent on the clock
149-
tick internal, e.g. the amount of memory the process is using.
150-
151-
The first two elements of the return value are floating point values
152-
representing the amount of time spent executing in user mode and the
153-
amount of time spent executing in system mode, respectively. The
154-
remaining values are integers. Consult the \manpage{getrusage}{2}
155-
man page for detailed information about these values. A brief
156-
summary is presented here:
157-
158-
\begin{tableii}{r|l}{code}{Offset}{Resource}
159-
\lineii{0}{time in user mode (float)}
160-
\lineii{1}{time in system mode (float)}
161-
\lineii{2}{maximum resident set size}
162-
\lineii{3}{shared memory size}
163-
\lineii{4}{unshared memory size}
164-
\lineii{5}{unshared stack size}
165-
\lineii{6}{page faults not requiring I/O}
166-
\lineii{7}{page faults requiring I/O}
167-
\lineii{8}{number of swap outs}
168-
\lineii{9}{block input operations}
169-
\lineii{10}{block output operations}
170-
\lineii{11}{messages sent}
171-
\lineii{12}{messages received}
172-
\lineii{13}{signals received}
173-
\lineii{14}{voluntary context switches}
174-
\lineii{15}{involuntary context switches}
175-
\end{tableii}
145+
The fields of the return value each describe how a particular system
146+
resource has been used, e.g. amount of time spent running is user mode
147+
or number of times the process was swapped out of main memory. Some
148+
values are dependent on the clock tick internal, e.g. the amount of
149+
memory the process is using.
150+
151+
For backward compatibility, the return value is also accessible as
152+
a tuple of 16 elements.
153+
154+
The fields \member{ru_utime} and \member{ru_stime} of the return value
155+
are floating point values representing the amount of time spent
156+
executing in user mode and the amount of time spent executing in system
157+
mode, respectively. The remaining values are integers. Consult the
158+
\manpage{getrusage}{2} man page for detailed information about these
159+
values. A brief summary is presented here:
160+
161+
\begin{tableiii}{r|l|l}{code}{Index}{Field}{Resource}
162+
\lineiii{0}{\member{ru_utime}}{time in user mode (float)}
163+
\lineiii{1}{\member{ru_stime}}{time in system mode (float)}
164+
\lineiii{2}{\member{ru_maxrss}}{maximum resident set size}
165+
\lineiii{3}{\member{ru_ixrss}}{shared memory size}
166+
\lineiii{4}{\member{ru_idrss}}{unshared memory size}
167+
\lineiii{5}{\member{ru_isrss}}{unshared stack size}
168+
\lineiii{6}{\member{ru_minflt}}{page faults not requiring I/O}
169+
\lineiii{7}{\member{ru_majflt}}{page faults requiring I/O}
170+
\lineiii{8}{\member{ru_nswap}}{number of swap outs}
171+
\lineiii{9}{\member{ru_inblock}}{block input operations}
172+
\lineiii{10}{\member{ru_oublock}}{block output operations}
173+
\lineiii{11}{\member{ru_msgsnd}}{messages sent}
174+
\lineiii{12}{\member{ru_msgrcv}}{messages received}
175+
\lineiii{13}{\member{ru_nsignals}}{signals received}
176+
\lineiii{14}{\member{ru_nvcsw}}{voluntary context switches}
177+
\lineiii{15}{\member{ru_nivcsw}}{involuntary context switches}
178+
\end{tableiii}
176179

177180
This function will raise a \exception{ValueError} if an invalid
178181
\var{who} parameter is specified. It may also raise
179182
\exception{error} exception in unusual circumstances.
183+
184+
\versionchanged[Added access to values as attributes of the
185+
returned object]{2.3}
180186
\end{funcdesc}
181187

182188
\begin{funcdesc}{getpagesize}{}

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@ Joel Shprentz
413413
Itamar Shtull-Trauring
414414
Eric Siegerman
415415
Paul Sijben
416+
Kirill Simonov
416417
Nathan Paul Simons
417418
Janne Sinkkonen
418419
George Sipe

Misc/NEWS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ Extension modules
5656
hole was quickly plugged in zlib-1.1.4, and the Windows build of
5757
Python now ships with zlib-1.1.4.
5858

59-
- pwd and grp return enhanced tuples now, with symbolic field names.
59+
- pwd, grp, and resource return enhanced tuples now, with symbolic
60+
field names.
6061

6162
- array.array is now a type object. A new format character
6263
'u' indicates Py_UNICODE arrays. For those, .tounicode and

Modules/resource.c

Lines changed: 70 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11

22
#include "Python.h"
3+
#include "structseq.h"
34
#include <sys/resource.h>
45
#include <sys/time.h>
56
#include <string.h>
@@ -16,11 +17,48 @@
1617

1718
static PyObject *ResourceError;
1819

20+
static char struct_rusage__doc__[] =
21+
"struct_rusage: Result from getrusage.\n\n"
22+
"This object may be accessed either as a tuple of\n"
23+
" (utime,stime,maxrss,ixrss,idrss,isrss,minflt,majflt,\n"
24+
" nswap,inblock,oublock,msgsnd,msgrcv,nsignals,nvcsw,nivcsw)\n"
25+
"or via the attributes ru_utime, ru_stime, ru_maxrss, and so on.\n";
26+
27+
static PyStructSequence_Field struct_rusage_fields[] = {
28+
{"ru_utime", "user time used"},
29+
{"ru_stime", "system time used"},
30+
{"ru_maxrss", "max. resident set size"},
31+
{"ru_ixrss", "shared memory size"},
32+
{"ru_idrss", "unshared data size"},
33+
{"ru_isrss", "unshared stack size"},
34+
{"ru_minflt", "page faults not requiring I/O"},
35+
{"ru_majflt", "page faults requiring I/O"},
36+
{"ru_nswap", "number of swap outs"},
37+
{"ru_inblock", "block input operations"},
38+
{"ru_oublock", "block output operations"},
39+
{"ru_msgsnd", "IPC messages sent"},
40+
{"ru_msgrcv", "IPC messages received"},
41+
{"ru_nsignals", "signals received"},
42+
{"ru_nvcsw", "voluntary context switches"},
43+
{"ru_nivcsw", "involuntary context switches"},
44+
{0}
45+
};
46+
47+
static PyStructSequence_Desc struct_rusage_desc = {
48+
"resource.struct_rusage", /* name */
49+
struct_rusage__doc__, /* doc */
50+
struct_rusage_fields, /* fields */
51+
16 /* n_in_sequence */
52+
};
53+
54+
static PyTypeObject StructRUsageType;
55+
1956
static PyObject *
2057
resource_getrusage(PyObject *self, PyObject *args)
2158
{
2259
int who;
2360
struct rusage ru;
61+
PyObject *result;
2462

2563
if (!PyArg_ParseTuple(args, "i:getrusage", &who))
2664
return NULL;
@@ -35,29 +73,35 @@ resource_getrusage(PyObject *self, PyObject *args)
3573
return NULL;
3674
}
3775

38-
/* Yeah, this 16-tuple is way ugly. It's probably a lot less
39-
ugly than a dictionary with keys (or object attributes)
40-
named things like 'ixrss'.
41-
*/
42-
return Py_BuildValue(
43-
"ddiiiiiiiiiiiiii",
44-
doubletime(ru.ru_utime), /* user time used */
45-
doubletime(ru.ru_stime), /* system time used */
46-
ru.ru_maxrss, /* max. resident set size */
47-
ru.ru_ixrss, /* shared memory size */
48-
ru.ru_idrss, /* unshared memory size */
49-
ru.ru_isrss, /* unshared stack size */
50-
ru.ru_minflt, /* page faults not requiring I/O*/
51-
ru.ru_majflt, /* page faults requiring I/O */
52-
ru.ru_nswap, /* number of swap outs */
53-
ru.ru_inblock, /* block input operations */
54-
ru.ru_oublock, /* block output operations */
55-
ru.ru_msgsnd, /* messages sent */
56-
ru.ru_msgrcv, /* messages received */
57-
ru.ru_nsignals, /* signals received */
58-
ru.ru_nvcsw, /* voluntary context switches */
59-
ru.ru_nivcsw /* involuntary context switches */
60-
);
76+
result = PyStructSequence_New(&StructRUsageType);
77+
if (!result)
78+
return NULL;
79+
80+
PyStructSequence_SET_ITEM(result, 0,
81+
PyFloat_FromDouble(doubletime(ru.ru_utime)));
82+
PyStructSequence_SET_ITEM(result, 1,
83+
PyFloat_FromDouble(doubletime(ru.ru_stime)));
84+
PyStructSequence_SET_ITEM(result, 2, PyInt_FromLong(ru.ru_maxrss));
85+
PyStructSequence_SET_ITEM(result, 3, PyInt_FromLong(ru.ru_ixrss));
86+
PyStructSequence_SET_ITEM(result, 4, PyInt_FromLong(ru.ru_idrss));
87+
PyStructSequence_SET_ITEM(result, 5, PyInt_FromLong(ru.ru_isrss));
88+
PyStructSequence_SET_ITEM(result, 6, PyInt_FromLong(ru.ru_minflt));
89+
PyStructSequence_SET_ITEM(result, 7, PyInt_FromLong(ru.ru_majflt));
90+
PyStructSequence_SET_ITEM(result, 8, PyInt_FromLong(ru.ru_nswap));
91+
PyStructSequence_SET_ITEM(result, 9, PyInt_FromLong(ru.ru_inblock));
92+
PyStructSequence_SET_ITEM(result, 10, PyInt_FromLong(ru.ru_oublock));
93+
PyStructSequence_SET_ITEM(result, 11, PyInt_FromLong(ru.ru_msgsnd));
94+
PyStructSequence_SET_ITEM(result, 12, PyInt_FromLong(ru.ru_msgrcv));
95+
PyStructSequence_SET_ITEM(result, 13, PyInt_FromLong(ru.ru_nsignals));
96+
PyStructSequence_SET_ITEM(result, 14, PyInt_FromLong(ru.ru_nvcsw));
97+
PyStructSequence_SET_ITEM(result, 15, PyInt_FromLong(ru.ru_nivcsw));
98+
99+
if (PyErr_Occurred()) {
100+
Py_DECREF(result);
101+
return NULL;
102+
}
103+
104+
return result;
61105
}
62106

63107

@@ -172,6 +216,9 @@ initresource(void)
172216
}
173217
Py_INCREF(ResourceError);
174218
PyModule_AddObject(m, "error", ResourceError);
219+
PyStructSequence_InitType(&StructRUsageType, &struct_rusage_desc);
220+
PyModule_AddObject(m, "struct_rusage",
221+
(PyObject*) &StructRUsageType);
175222

176223
/* insert constants */
177224
#ifdef RLIMIT_CPU

0 commit comments

Comments
 (0)