diff --git a/docs/user/Embedding-Native-Extensions.md b/docs/user/Embedding-Native-Extensions.md index eaa31c0cd3..c413e66c6f 100644 --- a/docs/user/Embedding-Native-Extensions.md +++ b/docs/user/Embedding-Native-Extensions.md @@ -13,6 +13,13 @@ The Context API allows you to set options such as `allowIO`, `allowHostAccess`, To use Python native extensions on GraalPy, the `allowNativeAccess` option must be set to `true`, but this opens the door to full native access. This means that while Python code may be denied access to the host file system, thread or subprocess creation, and more, the native extension is under no such restriction. +## Java Virtual Threads + +Python native extensions are not compatible with Java virtual threads. +Native extensions commonly use native thread-local state, including CPython and extension-runtime state that cannot track Java virtual-thread scheduling. +If an embedded application may load or call native extensions, run that Python code on platform threads. +For example, server applications that use virtual threads for request handling should dispatch GraalPy calls that may use native extensions to a platform-thread executor. + ## Memory Management Python C extensions, like the CPython reference implementation, use reference counting for memory management. diff --git a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java index d9b6ed0b26..f5622e81a4 100644 --- a/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java +++ b/graalpython/com.oracle.graal.python.processor/src/com/oracle/graal/python/processor/CApiBuiltinsProcessor.java @@ -1502,6 +1502,11 @@ private void generateNativeAccessSupport(Element[] origins) throws IOException { lines.add(" return Linker.nativeLinker().upcallStub(staticMethodHandle, functionDescriptor, (Arena) arena).address();"); lines.add(" }"); lines.add(""); + lines.add(" @Override"); + lines.add(" protected boolean isCurrentThreadVirtualImpl() {"); + lines.add(" return Thread.currentThread().isVirtual();"); + lines.add(" }"); + lines.add(""); lines.add(" private static FunctionDescriptor createFunctionDescriptor(NativeSimpleType resType, NativeSimpleType[] argTypes) {"); lines.add(" MemoryLayout[] argLayouts = new MemoryLayout[argTypes.length];"); lines.add(" for (int i = 0; i < argTypes.length; i++) {"); @@ -1598,6 +1603,11 @@ private void generateDummyNativeAccessSupport(Element[] origins) throws IOExcept lines.add(" protected long createClosureImpl(MethodHandle staticMethodHandle, NativeSimpleType resType, NativeSimpleType[] argTypes, Object arena) {"); lines.add(" throw unsupported();"); lines.add(" }"); + lines.add(""); + lines.add(" @Override"); + lines.add(" protected boolean isCurrentThreadVirtualImpl() {"); + lines.add(" return false;"); + lines.add(" }"); lines.add("}"); var file = processingEnv.getFiler().createSourceFile(NATIVE_ACCESS_PACKAGE + "." + NATIVE_ACCESS_SUPPORT_IMPL_CLASS_NAME, origins); diff --git a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java index 7dee2c1dee..3ae238e251 100644 --- a/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java +++ b/graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/objects/cext/capi/CApiContext.java @@ -609,7 +609,7 @@ private BackgroundGCTask(PythonContext context) { super("Python GC", LOGGER); this.ctx = new WeakReference<>(context); this.rssInterval = context.getOption(PythonOptions.BackgroundGCTaskInterval); - this.gcRSSThreshold = context.getOption(PythonOptions.BackgroundGCTaskThreshold) / (double) 100; + this.gcGrowthThreshold = context.getOption(PythonOptions.BackgroundGCTaskThreshold) / (double) 100; this.gcRSSMinimum = context.getOption(PythonOptions.BackgroundGCTaskMinimum); } @@ -624,7 +624,7 @@ private BackgroundGCTask(PythonContext context) { // RSS monitor interval in ms final int rssInterval; /** - * RSS percentage increase between System.gc() calls. Low percentage will trigger + * Resources percentage increase between System.gc() calls. Low percentage will trigger * System.gc() more often which can cause unnecessary overhead. * *