42
42
43
43
import static com .oracle .graal .python .runtime .exception .PythonErrorType .ValueError ;
44
44
45
- import java .lang .management .ManagementFactory ;
46
- import java .lang .management .MemoryMXBean ;
47
- import java .lang .management .MemoryUsage ;
48
- import java .lang .management .ThreadMXBean ;
49
45
import java .util .List ;
50
46
51
- import org .graalvm .nativeimage .ImageInfo ;
52
-
53
47
import com .oracle .graal .python .builtins .Builtin ;
54
48
import com .oracle .graal .python .builtins .CoreFunctions ;
55
49
import com .oracle .graal .python .builtins .Python3Core ;
56
50
import com .oracle .graal .python .builtins .PythonBuiltinClassType ;
57
51
import com .oracle .graal .python .builtins .PythonBuiltins ;
58
- import com .oracle .graal .python .builtins .objects .thread . PThread ;
52
+ import com .oracle .graal .python .builtins .objects .exception . OSErrorEnum ;
59
53
import com .oracle .graal .python .builtins .objects .tuple .PTuple ;
60
54
import com .oracle .graal .python .builtins .objects .tuple .StructSequence ;
61
55
import com .oracle .graal .python .nodes .ErrorMessages ;
56
+ import com .oracle .graal .python .nodes .PConstructAndRaiseNode ;
62
57
import com .oracle .graal .python .nodes .PRaiseNode ;
63
58
import com .oracle .graal .python .nodes .function .PythonBuiltinBaseNode ;
64
59
import com .oracle .graal .python .nodes .function .PythonBuiltinNode ;
60
+ import com .oracle .graal .python .runtime .PosixConstants ;
61
+ import com .oracle .graal .python .runtime .PosixSupport ;
62
+ import com .oracle .graal .python .runtime .PosixSupportLibrary ;
63
+ import com .oracle .graal .python .runtime .PosixSupportLibrary .PosixException ;
64
+ import com .oracle .graal .python .runtime .PosixSupportLibrary .RusageResult ;
65
65
import com .oracle .graal .python .runtime .object .PythonObjectFactory ;
66
- import com .oracle .truffle .api .CompilerDirectives . TruffleBoundary ;
66
+ import com .oracle .truffle .api .dsl . Bind ;
67
67
import com .oracle .truffle .api .dsl .Cached ;
68
- import com .oracle .truffle .api .dsl .Fallback ;
69
68
import com .oracle .truffle .api .dsl .GenerateNodeFactory ;
70
69
import com .oracle .truffle .api .dsl .ImportStatic ;
71
70
import com .oracle .truffle .api .dsl .NodeFactory ;
72
71
import com .oracle .truffle .api .dsl .Specialization ;
72
+ import com .oracle .truffle .api .frame .VirtualFrame ;
73
+ import com .oracle .truffle .api .library .CachedLibrary ;
74
+ import com .oracle .truffle .api .nodes .Node ;
73
75
74
76
@ CoreFunctions (defineModule = "resource" )
75
77
public final class ResourceModuleBuiltins extends PythonBuiltins {
76
78
77
- static int RUSAGE_CHILDREN = -1 ;
78
- static int RUSAGE_SELF = 0 ;
79
- static int RUSAGE_THREAD = 1 ;
80
-
81
79
static int RLIMIT_CPU = 0 ;
82
80
static int RLIMIT_FSIZE = 1 ;
83
81
static int RLIMIT_DATA = 2 ;
@@ -129,9 +127,13 @@ public void initialize(Python3Core core) {
129
127
130
128
addBuiltinConstant ("error" , PythonBuiltinClassType .OSError );
131
129
132
- addBuiltinConstant ("RUSAGE_CHILDREN" , RUSAGE_CHILDREN );
133
- addBuiltinConstant ("RUSAGE_SELF" , RUSAGE_SELF );
134
- addBuiltinConstant ("RUSAGE_THREAD" , RUSAGE_THREAD );
130
+ if (PosixConstants .RUSAGE_CHILDREN .defined ) {
131
+ addBuiltinConstant ("RUSAGE_CHILDREN" , PosixConstants .RUSAGE_CHILDREN .getValueIfDefined ());
132
+ }
133
+ addBuiltinConstant ("RUSAGE_SELF" , PosixConstants .RUSAGE_SELF .value );
134
+ if (PosixConstants .RUSAGE_THREAD .defined ) {
135
+ addBuiltinConstant ("RUSAGE_THREAD" , PosixConstants .RUSAGE_THREAD .getValueIfDefined ());
136
+ }
135
137
136
138
addBuiltinConstant ("RLIMIT_CPU" , RLIMIT_CPU );
137
139
addBuiltinConstant ("RLIMIT_FSIZE" , RLIMIT_FSIZE );
@@ -154,119 +156,29 @@ public void initialize(Python3Core core) {
154
156
@ ImportStatic (ResourceModuleBuiltins .class )
155
157
abstract static class GetRuUsageNode extends PythonBuiltinNode {
156
158
157
- @ Specialization (guards = {"who == RUSAGE_THREAD" })
158
- @ TruffleBoundary
159
- PTuple getruusageThread (@ SuppressWarnings ("unused" ) int who ) {
160
- long id = PThread .getThreadId (Thread .currentThread ());
161
- Runtime runtime = Runtime .getRuntime ();
162
-
163
- double ru_utime = 0 ; // time in user mode (float)
164
- double ru_stime = 0 ; // time in system mode (float)
165
- long ru_maxrss ; // maximum resident set size
166
-
167
- if (!ImageInfo .inImageCode ()) {
168
- ThreadMXBean threadMXBean = ManagementFactory .getThreadMXBean ();
169
- if (threadMXBean .isCurrentThreadCpuTimeSupported ()) {
170
- ru_utime = threadMXBean .getThreadUserTime (id ) / 1000000000.0 ;
171
- ru_stime = Math .max (0 , (threadMXBean .getThreadCpuTime (id ) - threadMXBean .getThreadUserTime (id ))) / 1000000000.0 ;
172
- }
173
-
174
- if (threadMXBean instanceof com .sun .management .ThreadMXBean ) {
175
- com .sun .management .ThreadMXBean thMxBean = (com .sun .management .ThreadMXBean ) threadMXBean ;
176
- ru_maxrss = thMxBean .getThreadAllocatedBytes (id );
159
+ @ Specialization
160
+ static PTuple getruusage (VirtualFrame frame , int who ,
161
+ @ Bind ("this" ) Node inliningTarget ,
162
+ @ CachedLibrary (limit = "1" ) PosixSupportLibrary posixLib ,
163
+ @ Cached PConstructAndRaiseNode .Lazy constructAndRaiseNode ,
164
+ @ Cached PRaiseNode .Lazy raiseNode ) {
165
+ PosixSupport posixSupport = PosixSupport .get (inliningTarget );
166
+ RusageResult rusage ;
167
+ try {
168
+ rusage = posixLib .getrusage (posixSupport , who );
169
+ } catch (PosixException e ) {
170
+ if (e .getErrorCode () == OSErrorEnum .EINVAL .getNumber ()) {
171
+ throw raiseNode .get (inliningTarget ).raise (ValueError , ErrorMessages .RUSAGE_INVALID_WHO );
177
172
} else {
178
- ru_maxrss = runtime . maxMemory ( );
173
+ throw constructAndRaiseNode . get ( inliningTarget ). raiseOSErrorFromPosixException ( frame , e );
179
174
}
180
- } else {
181
- ru_maxrss = runtime .maxMemory ();
182
- }
183
-
184
- String osName = System .getProperty ("os.name" );
185
- if (osName .contains ("Linux" )) {
186
- // peak memory usage (kilobytes on Linux
187
- ru_maxrss /= 1024 ;
188
175
}
189
176
190
- long ru_ixrss = -1 ; // shared memory size
191
- long ru_idrss = -1 ; // unshared memory size
192
- long ru_isrss = -1 ; // unshared stack size
193
- long ru_minflt = -1 ; // page faults not requiring I/O
194
- long ru_majflt = -1 ; // page faults requiring I/O
195
- long ru_nswap = -1 ; // number of swap outs
196
- long ru_inblock = -1 ; // block input operations
197
- long ru_oublock = -1 ; // block output operations
198
- long ru_msgsnd = -1 ; // messages sent
199
- long ru_msgrcv = -1 ; // messages received
200
- long ru_nsignals = -1 ; // signals received
201
- long ru_nvcsw = -1 ; // voluntary context switches
202
- long ru_nivcsw = -1 ; // nvoluntary context switches
203
- return PythonObjectFactory .getUncached ().createStructSeq (STRUCT_RUSAGE_DESC , ru_utime , ru_stime , ru_maxrss , ru_ixrss , ru_idrss , ru_isrss ,
204
- ru_minflt , ru_majflt , ru_nswap , ru_inblock , ru_oublock , ru_msgsnd , ru_msgrcv , ru_nsignals ,
205
- ru_nvcsw , ru_nivcsw );
206
- }
207
-
208
- @ Specialization (guards = {"who == RUSAGE_SELF" })
209
- @ TruffleBoundary
210
- PTuple getruusageSelf (@ SuppressWarnings ("unused" ) int who ) {
211
- Runtime runtime = Runtime .getRuntime ();
212
-
213
- double ru_utime = 0 ; // time in user mode (float)
214
- double ru_stime = 0 ; // time in system mode (float)
215
- long ru_maxrss ;
216
-
217
- if (!ImageInfo .inImageCode ()) {
218
- ThreadMXBean threadMXBean = ManagementFactory .getThreadMXBean ();
219
- if (threadMXBean .isThreadCpuTimeSupported ()) {
220
- for (long thId : threadMXBean .getAllThreadIds ()) {
221
- long tu = threadMXBean .getThreadUserTime (thId );
222
- long tc = threadMXBean .getThreadCpuTime (thId );
223
-
224
- if (tu != -1 ) {
225
- ru_utime += tu / 1000000000.0 ;
226
- }
227
-
228
- if (tu != -1 && tc != -1 ) {
229
- ru_stime += Math .max (0 , tc - tu ) / 1000000000.0 ;
230
- }
231
- }
232
- }
233
-
234
- MemoryMXBean memoryMXBean = ManagementFactory .getMemoryMXBean ();
235
- MemoryUsage heapMemoryUsage = memoryMXBean .getHeapMemoryUsage ();
236
- MemoryUsage nonHeapMemoryUsage = memoryMXBean .getNonHeapMemoryUsage ();
237
- ru_maxrss = heapMemoryUsage .getCommitted () + nonHeapMemoryUsage .getCommitted ();
238
- } else {
239
- ru_maxrss = runtime .maxMemory ();
240
- }
241
-
242
- String osName = System .getProperty ("os.name" );
243
- if (osName .contains ("Linux" )) {
244
- // peak memory usage (kilobytes on Linux
245
- ru_maxrss /= 1024 ;
246
- }
247
-
248
- long ru_ixrss = -1 ; // shared memory size
249
- long ru_idrss = -1 ; // unshared memory size
250
- long ru_isrss = -1 ; // unshared stack size
251
- long ru_minflt = -1 ; // page faults not requiring I/O
252
- long ru_majflt = -1 ; // page faults requiring I/O
253
- long ru_nswap = -1 ; // number of swap outs
254
- long ru_inblock = -1 ; // block input operations
255
- long ru_oublock = -1 ; // block output operations
256
- long ru_msgsnd = -1 ; // messages sent
257
- long ru_msgrcv = -1 ; // messages received
258
- long ru_nsignals = -1 ; // signals received
259
- long ru_nvcsw = -1 ; // voluntary context switches
260
- long ru_nivcsw = -1 ; // nvoluntary context switches
261
- return PythonObjectFactory .getUncached ().createStructSeq (STRUCT_RUSAGE_DESC , ru_utime , ru_stime , ru_maxrss , ru_ixrss , ru_idrss , ru_isrss ,
262
- ru_minflt , ru_majflt , ru_nswap , ru_inblock , ru_oublock , ru_msgsnd , ru_msgrcv , ru_nsignals ,
263
- ru_nvcsw , ru_nivcsw );
264
- }
265
-
266
- @ Fallback
267
- static PTuple getruusage (@ SuppressWarnings ("unused" ) Object who ,
268
- @ Cached PRaiseNode raiseNode ) {
269
- throw raiseNode .raise (ValueError , ErrorMessages .RUSAGE_NOT_YET_IMPLEMENED );
177
+ return PythonObjectFactory .getUncached ().createStructSeq (STRUCT_RUSAGE_DESC ,
178
+ rusage .ru_utime (), rusage .ru_stime (),
179
+ rusage .ru_maxrss (), rusage .ru_ixrss (), rusage .ru_idrss (), rusage .ru_isrss (),
180
+ rusage .ru_minflt (), rusage .ru_majflt (), rusage .ru_nswap (), rusage .ru_inblock (), rusage .ru_oublock (),
181
+ rusage .ru_msgsnd (), rusage .ru_msgrcv (), rusage .ru_nsignals (), rusage .ru_nvcsw (), rusage .ru_nivcsw ());
270
182
}
271
183
}
272
184
0 commit comments