com.oracle.graal.python.builtins.modules.ResourceModuleBuiltins Maven / Gradle / Ivy
/*
* Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* The Universal Permissive License (UPL), Version 1.0
*
* Subject to the condition set forth below, permission is hereby granted to any
* person obtaining a copy of this software, associated documentation and/or
* data (collectively the "Software"), free of charge and under any and all
* copyright rights in the Software, and any and all patent rights owned or
* freely licensable by each licensor hereunder covering either (i) the
* unmodified Software as contributed to or provided by such licensor, or (ii)
* the Larger Works (as defined below), to deal in both
*
* (a) the Software, and
*
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
* one is included with the Software each a "Larger Work" to which the Software
* is contributed by such licensors),
*
* without restriction, including without limitation the rights to copy, create
* derivative works of, display, perform, and distribute the Software and make,
* use, sell, offer for sale, import, export, have made, and have sold the
* Software and the Larger Work(s), and to sublicense the foregoing rights on
* either these or other terms.
*
* This license is subject to the following condition:
*
* The above copyright notice and either this complete permission notice or at a
* minimum a reference to the UPL must be included in all copies or substantial
* portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.oracle.graal.python.builtins.modules;
import static com.oracle.graal.python.runtime.exception.PythonErrorType.ValueError;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.lang.management.ThreadMXBean;
import java.util.List;
import org.graalvm.nativeimage.ImageInfo;
import com.oracle.graal.python.builtins.Builtin;
import com.oracle.graal.python.builtins.CoreFunctions;
import com.oracle.graal.python.builtins.Python3Core;
import com.oracle.graal.python.builtins.PythonBuiltinClassType;
import com.oracle.graal.python.builtins.PythonBuiltins;
import com.oracle.graal.python.builtins.objects.thread.PThread;
import com.oracle.graal.python.builtins.objects.tuple.PTuple;
import com.oracle.graal.python.builtins.objects.tuple.StructSequence;
import com.oracle.graal.python.nodes.ErrorMessages;
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
import com.oracle.truffle.api.dsl.Fallback;
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
import com.oracle.truffle.api.dsl.ImportStatic;
import com.oracle.truffle.api.dsl.NodeFactory;
import com.oracle.truffle.api.dsl.Specialization;
@CoreFunctions(defineModule = "resource")
public final class ResourceModuleBuiltins extends PythonBuiltins {
static int RUSAGE_CHILDREN = -1;
static int RUSAGE_SELF = 0;
static int RUSAGE_THREAD = 1;
static int RLIMIT_CPU = 0;
static int RLIMIT_FSIZE = 1;
static int RLIMIT_DATA = 2;
static int RLIMIT_STACK = 3;
static int RLIMIT_CORE = 4;
static int RLIMIT_AS = 5;
static int RLIMIT_RSS = 5;
static int RLIMIT_MEMLOCK = 6;
static int RLIMIT_NPROC = 7;
static int RLIMIT_NOFILE = 8;
static long RLIM_INFINITY = Long.MAX_VALUE;
static final StructSequence.BuiltinTypeDescriptor STRUCT_RUSAGE_DESC = new StructSequence.BuiltinTypeDescriptor(
PythonBuiltinClassType.PStructRusage,
// @formatter:off The formatter joins these lines making it less readable
"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.",
// @formatter:on
16,
new String[]{
"ru_utime", "ru_stime", "ru_maxrss",
"ru_ixrss", "ru_idrss", "ru_isrss",
"ru_minflt", "ru_majflt",
"ru_nswap", "ru_inblock", "ru_oublock",
"ru_msgsnd", "ru_msgrcv", "ru_nsignals",
"ru_nvcsw", "ru_nivcsw"
},
new String[]{
"user time used", "system time used", "max. resident set size",
"shared memory size", "unshared data size", "unshared stack size",
"page faults not requiring I/O", "page faults requiring I/O",
"number of swap outs", "block input operations", "block output operations",
"IPC messages sent", "IPC messages received", "signals received",
"voluntary context switches", "involuntary context switches"
});
@Override
protected List extends NodeFactory extends PythonBuiltinBaseNode>> getNodeFactories() {
return ResourceModuleBuiltinsFactory.getFactories();
}
@Override
public void initialize(Python3Core core) {
super.initialize(core);
addBuiltinConstant("RUSAGE_CHILDREN", RUSAGE_CHILDREN);
addBuiltinConstant("RUSAGE_SELF", RUSAGE_SELF);
addBuiltinConstant("RUSAGE_THREAD", RUSAGE_THREAD);
addBuiltinConstant("RLIMIT_CPU", RLIMIT_CPU);
addBuiltinConstant("RLIMIT_FSIZE", RLIMIT_FSIZE);
addBuiltinConstant("RLIMIT_DATA", RLIMIT_DATA);
addBuiltinConstant("RLIMIT_STACK", RLIMIT_STACK);
addBuiltinConstant("RLIMIT_CORE", RLIMIT_CORE);
addBuiltinConstant("RLIMIT_AS", RLIMIT_AS);
addBuiltinConstant("RLIMIT_RSS", RLIMIT_RSS);
addBuiltinConstant("RLIMIT_MEMLOCK", RLIMIT_MEMLOCK);
addBuiltinConstant("RLIMIT_NPROC", RLIMIT_NPROC);
addBuiltinConstant("RLIMIT_NOFILE", RLIMIT_NOFILE);
addBuiltinConstant("RLIM_INFINITY", RLIM_INFINITY);
StructSequence.initType(core, STRUCT_RUSAGE_DESC);
}
@Builtin(name = "getrusage", minNumOfPositionalArgs = 1)
@GenerateNodeFactory
@ImportStatic(ResourceModuleBuiltins.class)
abstract static class GetRuUsageNode extends PythonBuiltinNode {
@Specialization(guards = {"who == RUSAGE_THREAD"})
@TruffleBoundary
PTuple getruusageThread(@SuppressWarnings("unused") int who) {
long id = PThread.getThreadId(Thread.currentThread());
Runtime runtime = Runtime.getRuntime();
double ru_utime = 0; // time in user mode (float)
double ru_stime = 0; // time in system mode (float)
long ru_maxrss; // maximum resident set size
if (!ImageInfo.inImageCode()) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
if (threadMXBean.isCurrentThreadCpuTimeSupported()) {
ru_utime = threadMXBean.getThreadUserTime(id) / 1000000000.0;
ru_stime = Math.max(0, (threadMXBean.getThreadCpuTime(id) - threadMXBean.getThreadUserTime(id))) / 1000000000.0;
}
if (threadMXBean instanceof com.sun.management.ThreadMXBean) {
com.sun.management.ThreadMXBean thMxBean = (com.sun.management.ThreadMXBean) threadMXBean;
ru_maxrss = thMxBean.getThreadAllocatedBytes(id);
} else {
ru_maxrss = runtime.maxMemory();
}
} else {
ru_maxrss = runtime.maxMemory();
}
String osName = System.getProperty("os.name");
if (osName.contains("Linux")) {
// peak memory usage (kilobytes on Linux
ru_maxrss /= 1024;
}
long ru_ixrss = -1; // shared memory size
long ru_idrss = -1; // unshared memory size
long ru_isrss = -1; // unshared stack size
long ru_minflt = -1; // page faults not requiring I/O
long ru_majflt = -1; // page faults requiring I/O
long ru_nswap = -1; // number of swap outs
long ru_inblock = -1; // block input operations
long ru_oublock = -1; // block output operations
long ru_msgsnd = -1; // messages sent
long ru_msgrcv = -1; // messages received
long ru_nsignals = -1; // signals received
long ru_nvcsw = -1; // voluntary context switches
long ru_nivcsw = -1; // nvoluntary context switches
return factory().createStructSeq(STRUCT_RUSAGE_DESC, ru_utime, ru_stime, ru_maxrss, ru_ixrss, ru_idrss, ru_isrss,
ru_minflt, ru_majflt, ru_nswap, ru_inblock, ru_oublock, ru_msgsnd, ru_msgrcv, ru_nsignals,
ru_nvcsw, ru_nivcsw);
}
@Specialization(guards = {"who == RUSAGE_SELF"})
@TruffleBoundary
PTuple getruusageSelf(@SuppressWarnings("unused") int who) {
Runtime runtime = Runtime.getRuntime();
double ru_utime = 0; // time in user mode (float)
double ru_stime = 0; // time in system mode (float)
long ru_maxrss;
if (!ImageInfo.inImageCode()) {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
if (threadMXBean.isThreadCpuTimeSupported()) {
for (long thId : threadMXBean.getAllThreadIds()) {
long tu = threadMXBean.getThreadUserTime(thId);
long tc = threadMXBean.getThreadCpuTime(thId);
if (tu != -1) {
ru_utime += tu / 1000000000.0;
}
if (tu != -1 && tc != -1) {
ru_stime += Math.max(0, tc - tu) / 1000000000.0;
}
}
}
MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMemoryUsage = memoryMXBean.getHeapMemoryUsage();
MemoryUsage nonHeapMemoryUsage = memoryMXBean.getNonHeapMemoryUsage();
ru_maxrss = heapMemoryUsage.getCommitted() + nonHeapMemoryUsage.getCommitted();
} else {
ru_maxrss = runtime.maxMemory();
}
String osName = System.getProperty("os.name");
if (osName.contains("Linux")) {
// peak memory usage (kilobytes on Linux
ru_maxrss /= 1024;
}
long ru_ixrss = -1; // shared memory size
long ru_idrss = -1; // unshared memory size
long ru_isrss = -1; // unshared stack size
long ru_minflt = -1; // page faults not requiring I/O
long ru_majflt = -1; // page faults requiring I/O
long ru_nswap = -1; // number of swap outs
long ru_inblock = -1; // block input operations
long ru_oublock = -1; // block output operations
long ru_msgsnd = -1; // messages sent
long ru_msgrcv = -1; // messages received
long ru_nsignals = -1; // signals received
long ru_nvcsw = -1; // voluntary context switches
long ru_nivcsw = -1; // nvoluntary context switches
return factory().createStructSeq(STRUCT_RUSAGE_DESC, ru_utime, ru_stime, ru_maxrss, ru_ixrss, ru_idrss, ru_isrss,
ru_minflt, ru_majflt, ru_nswap, ru_inblock, ru_oublock, ru_msgsnd, ru_msgrcv, ru_nsignals,
ru_nvcsw, ru_nivcsw);
}
@Fallback
PTuple getruusage(@SuppressWarnings("unused") Object who) {
throw raise(ValueError, ErrorMessages.RUSAGE_NOT_YET_IMPLEMENED);
}
}
@Builtin(name = "getpagesize", minNumOfPositionalArgs = 0)
@GenerateNodeFactory
abstract static class GetPageSizeNode extends PythonBuiltinNode {
@Specialization
int getPageSize() {
return 4096;
}
}
@Builtin(name = "getrlimit", minNumOfPositionalArgs = 1)
@GenerateNodeFactory
abstract static class GetRLimitNode extends PythonBuiltinNode {
@Specialization
PTuple getPageSize(@SuppressWarnings("unused") int which) {
// dummy implementation - report "unrestricted" for everything
return factory().createTuple(new Object[]{RLIM_INFINITY, RLIM_INFINITY});
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy