Skip to content

Commit f55f64b

Browse files
committed
[GR-11652] implement the _thread builtin module
PullRequest: graalpython/192
2 parents 7ee2bba + 6ef0ee3 commit f55f64b

File tree

20 files changed

+1777
-51
lines changed

20 files changed

+1777
-51
lines changed

graalpython/com.oracle.graal.python.test/src/tests/test_thread.py

Lines changed: 514 additions & 0 deletions
Large diffs are not rendered by default.

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/PythonLanguage.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ public final class PythonLanguage extends TruffleLanguage<PythonContext> {
103103
public static final int MICRO = 0;
104104
public static final String VERSION = MAJOR + "." + MINOR + "." + MICRO;
105105

106+
public static boolean WITH_THREADS = false;
107+
106108
public static final String MIME_TYPE = "text/x-python";
107109
public static final String EXTENSION = ".py";
108110

@@ -481,4 +483,22 @@ public PCode cacheCode(String filename, Supplier<PCode> createCode) {
481483
public static Shape freshShape() {
482484
return freshShape;
483485
}
486+
487+
@Override
488+
protected boolean isThreadAccessAllowed(Thread thread, boolean singleThreaded) {
489+
if (singleThreaded) {
490+
return super.isThreadAccessAllowed(thread, singleThreaded);
491+
}
492+
return WITH_THREADS;
493+
}
494+
495+
@Override
496+
protected void initializeMultiThreading(PythonContext context) {
497+
PythonContext.getSingleThreadedAssumption().invalidate();
498+
}
499+
500+
@Override
501+
protected void initializeThread(PythonContext context, Thread thread) {
502+
super.initializeThread(context, thread);
503+
}
484504
}

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/Python3Core.java

Lines changed: 67 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,9 @@
7676
import com.oracle.graal.python.builtins.modules.SignalModuleBuiltins;
7777
import com.oracle.graal.python.builtins.modules.SocketModuleBuiltins;
7878
import com.oracle.graal.python.builtins.modules.StringModuleBuiltins;
79+
import com.oracle.graal.python.builtins.modules.SysConfigModuleBuiltins;
7980
import com.oracle.graal.python.builtins.modules.SysModuleBuiltins;
81+
import com.oracle.graal.python.builtins.modules.ThreadModuleBuiltins;
8082
import com.oracle.graal.python.builtins.modules.TimeModuleBuiltins;
8183
import com.oracle.graal.python.builtins.modules.TruffleCextBuiltins;
8284
import com.oracle.graal.python.builtins.modules.UnicodeDataModuleBuiltins;
@@ -135,6 +137,9 @@
135137
import com.oracle.graal.python.builtins.objects.slice.SliceBuiltins;
136138
import com.oracle.graal.python.builtins.objects.str.StringBuiltins;
137139
import com.oracle.graal.python.builtins.objects.superobject.SuperBuiltins;
140+
import com.oracle.graal.python.builtins.objects.thread.LockBuiltins;
141+
import com.oracle.graal.python.builtins.objects.thread.RLockBuiltins;
142+
import com.oracle.graal.python.builtins.objects.thread.ThreadBuiltins;
138143
import com.oracle.graal.python.builtins.objects.traceback.TracebackBuiltins;
139144
import com.oracle.graal.python.builtins.objects.tuple.TupleBuiltins;
140145
import com.oracle.graal.python.builtins.objects.type.PythonBuiltinClass;
@@ -151,8 +156,8 @@
151156
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
152157
import com.oracle.truffle.api.RootCallTarget;
153158
import com.oracle.truffle.api.TruffleFile;
154-
import com.oracle.truffle.api.TruffleOptions;
155159
import com.oracle.truffle.api.TruffleLanguage.Env;
160+
import com.oracle.truffle.api.TruffleOptions;
156161
import com.oracle.truffle.api.nodes.Node;
157162
import com.oracle.truffle.api.nodes.RootNode;
158163
import com.oracle.truffle.api.source.Source;
@@ -163,44 +168,51 @@
163168
* types.
164169
*/
165170
public final class Python3Core implements PythonCore {
166-
// Order matters!
167-
private static final String[] CORE_FILES = new String[]{
168-
"_descriptor",
169-
"object",
170-
"sys",
171-
"dict",
172-
"_mappingproxy",
173-
"str",
174-
"type",
175-
"_imp",
176-
"function",
177-
"_functools",
178-
"method",
179-
"code",
180-
"_warnings",
181-
"posix",
182-
"_io",
183-
"_frozen_importlib",
184-
"classes",
185-
"_weakref",
186-
"set",
187-
"itertools",
188-
"base_exception",
189-
"python_cext",
190-
"_collections",
191-
"memoryview",
192-
"list",
193-
"_codecs",
194-
"bytes",
195-
"bytearray",
196-
"float",
197-
"time",
198-
"unicodedata",
199-
"_locale",
200-
"_sre",
201-
"function",
202-
"_socket",
203-
};
171+
private final String[] coreFiles;
172+
173+
private static final String[] initializeCoreFiles() {
174+
// Order matters!
175+
List<String> coreFiles = new ArrayList<>(Arrays.asList(
176+
"_descriptor",
177+
"object",
178+
"sys",
179+
"dict",
180+
"_mappingproxy",
181+
"str",
182+
"type",
183+
"_imp",
184+
"function",
185+
"_functools",
186+
"method",
187+
"code",
188+
"_warnings",
189+
"posix",
190+
"_io",
191+
"_frozen_importlib",
192+
"classes",
193+
"_weakref",
194+
"set",
195+
"itertools",
196+
"base_exception",
197+
"python_cext",
198+
"_collections",
199+
"memoryview",
200+
"list",
201+
"_codecs",
202+
"bytes",
203+
"bytearray",
204+
"float",
205+
"time",
206+
"unicodedata",
207+
"_locale",
208+
"_sre",
209+
"function",
210+
"_sysconfig",
211+
"_socket",
212+
"_thread"));
213+
214+
return coreFiles.toArray(new String[coreFiles.size()]);
215+
}
204216

205217
private final PythonBuiltins[] builtins;
206218

@@ -289,13 +301,22 @@ private static final PythonBuiltins[] initializeBuiltins() {
289301
new PosixSubprocessModuleBuiltins(),
290302
new CtypesModuleBuiltins(),
291303
new ReadlineModuleBuiltins(),
292-
new PyExpatModuleBuiltins()));
304+
new PyExpatModuleBuiltins(),
305+
new SysConfigModuleBuiltins()));
293306
if (!TruffleOptions.AOT) {
294307
ServiceLoader<PythonBuiltins> providers = ServiceLoader.load(PythonBuiltins.class);
295308
for (PythonBuiltins builtin : providers) {
296309
builtins.add(builtin);
297310
}
298311
}
312+
// threads
313+
if (PythonLanguage.WITH_THREADS) {
314+
builtins.addAll(new ArrayList<>(Arrays.asList(
315+
new ThreadModuleBuiltins(),
316+
new ThreadBuiltins(),
317+
new LockBuiltins(),
318+
new RLockBuiltins())));
319+
}
299320
return builtins.toArray(new PythonBuiltins[builtins.size()]);
300321
}
301322

@@ -323,6 +344,7 @@ private static final PythonBuiltins[] initializeBuiltins() {
323344
public Python3Core(PythonParser parser) {
324345
this.parser = parser;
325346
this.builtins = initializeBuiltins();
347+
this.coreFiles = initializeCoreFiles();
326348
}
327349

328350
@Override
@@ -363,7 +385,7 @@ private void initializeJavaCore() {
363385
private void initializePythonCore() {
364386
String coreHome = PythonCore.getCoreHomeOrFail();
365387
loadFile("builtins", coreHome);
366-
for (String s : CORE_FILES) {
388+
for (String s : coreFiles) {
367389
loadFile(s, coreHome);
368390
}
369391
exportCInterface(getContext());
@@ -526,7 +548,10 @@ private void initializeTypes() {
526548
for (PythonBuiltinClassType builtinClass : PythonBuiltinClassType.VALUES) {
527549
String module = builtinClass.getPublicInModule();
528550
if (module != null) {
529-
lookupBuiltinModule(module).setAttribute(builtinClass.getName(), lookupType(builtinClass));
551+
PythonModule pythonModule = lookupBuiltinModule(module);
552+
if (pythonModule != null) {
553+
pythonModule.setAttribute(builtinClass.getName(), lookupType(builtinClass));
554+
}
530555
}
531556
}
532557
// now initialize well-known objects

graalpython/com.oracle.graal.python/src/com/oracle/graal/python/builtins/PythonBuiltinClassType.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ public enum PythonBuiltinClassType implements LazyPythonClass {
8686
PCode("code"),
8787
PZip("zip", "builtins"),
8888
PBuffer("buffer", "builtins"),
89+
PThread("start_new_thread", "_thread"),
90+
PLock("LockType", "_thread"),
91+
PRLock("RLock", "_thread"),
8992
PSocket("socket", "_socket"),
9093

9194
// Errors and exceptions:
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
* Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* The Universal Permissive License (UPL), Version 1.0
6+
*
7+
* Subject to the condition set forth below, permission is hereby granted to any
8+
* person obtaining a copy of this software, associated documentation and/or
9+
* data (collectively the "Software"), free of charge and under any and all
10+
* copyright rights in the Software, and any and all patent rights owned or
11+
* freely licensable by each licensor hereunder covering either (i) the
12+
* unmodified Software as contributed to or provided by such licensor, or (ii)
13+
* the Larger Works (as defined below), to deal in both
14+
*
15+
* (a) the Software, and
16+
*
17+
* (b) any piece of software and/or hardware listed in the lrgrwrks.txt file if
18+
* one is included with the Software each a "Larger Work" to which the Software
19+
* is contributed by such licensors),
20+
*
21+
* without restriction, including without limitation the rights to copy, create
22+
* derivative works of, display, perform, and distribute the Software and make,
23+
* use, sell, offer for sale, import, export, have made, and have sold the
24+
* Software and the Larger Work(s), and to sublicense the foregoing rights on
25+
* either these or other terms.
26+
*
27+
* This license is subject to the following condition:
28+
*
29+
* The above copyright notice and either this complete permission notice or at a
30+
* minimum a reference to the UPL must be included in all copies or substantial
31+
* portions of the Software.
32+
*
33+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
38+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
39+
* SOFTWARE.
40+
*/
41+
package com.oracle.graal.python.builtins.modules;
42+
43+
import java.util.HashMap;
44+
import java.util.List;
45+
import java.util.Map;
46+
47+
import com.oracle.graal.python.PythonLanguage;
48+
import com.oracle.graal.python.builtins.Builtin;
49+
import com.oracle.graal.python.builtins.CoreFunctions;
50+
import com.oracle.graal.python.builtins.PythonBuiltins;
51+
import com.oracle.graal.python.builtins.objects.dict.PDict;
52+
import com.oracle.graal.python.nodes.function.PythonBuiltinBaseNode;
53+
import com.oracle.graal.python.nodes.function.PythonBuiltinNode;
54+
import com.oracle.truffle.api.dsl.GenerateNodeFactory;
55+
import com.oracle.truffle.api.dsl.NodeFactory;
56+
import com.oracle.truffle.api.dsl.Specialization;
57+
58+
/**
59+
* this builtin module is used to fill in truffle land config options into the sysconfig python
60+
* module
61+
*/
62+
@CoreFunctions(defineModule = "_sysconfig")
63+
public class SysConfigModuleBuiltins extends PythonBuiltins {
64+
private final static Map<Object, Object> STATIC_CONFIG_OPTIONS = new HashMap<>();
65+
static {
66+
STATIC_CONFIG_OPTIONS.put("WITH_THREAD", PythonLanguage.WITH_THREADS ? 1 : 0);
67+
}
68+
69+
@Override
70+
protected List<? extends NodeFactory<? extends PythonBuiltinBaseNode>> getNodeFactories() {
71+
return SysConfigModuleBuiltinsFactory.getFactories();
72+
}
73+
74+
@Builtin(name = "get_config_vars", takesVarArgs = true)
75+
@GenerateNodeFactory
76+
static abstract class GetConfigVarsNode extends PythonBuiltinNode {
77+
@Specialization
78+
PDict select(@SuppressWarnings("unused") Object[] arguments) {
79+
return factory().createDict(STATIC_CONFIG_OPTIONS);
80+
}
81+
}
82+
}

0 commit comments

Comments
 (0)