/* Variable and macro for in-line access to current thread
and interpreter state */
-static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) {
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void);
+#endif
+
+static inline PyThreadState*
+_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
+{
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ return _PyThreadState_GetTSS();
+#else
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
+#endif
}
/* Get the current Python thread state.
The caller must hold the GIL.
See also PyThreadState_Get() and PyThreadState_GET(). */
-static inline PyThreadState *_PyThreadState_GET(void) {
+static inline PyThreadState*
+_PyThreadState_GET(void)
+{
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ return _PyThreadState_GetTSS();
+#else
return _PyRuntimeState_GetThreadState(&_PyRuntime);
+#endif
}
/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */
take_gil(tstate);
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ (void)_PyThreadState_Swap(gilstate, tstate);
+#else
if (_PyThreadState_Swap(gilstate, tstate) != NULL) {
Py_FatalError("non-NULL old thread state");
}
+#endif
}
void
PyEval_SaveThread(void)
{
_PyRuntimeState *runtime = &_PyRuntime;
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ PyThreadState *old_tstate = _PyThreadState_GET();
+ PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate);
+#else
PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
+#endif
ensure_tstate_not_null(__func__, tstate);
struct _ceval_runtime_state *ceval = &runtime->ceval;
take_gil(tstate);
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ (void)_PyThreadState_Swap(&runtime->gilstate, tstate);
+#else
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
Py_FatalError("orphan tstate");
}
+#endif
}
/* Check for asynchronous exception. */
}
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+PyThreadState*
+_PyThreadState_GetTSS(void) {
+ return PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey);
+}
+#endif
+
+
PyThreadState *
_PyThreadState_UncheckedGet(void)
{
PyThreadState *
_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts)
{
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ PyThreadState *oldts = _PyThreadState_GetTSS();
+#else
PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate);
+#endif
_PyRuntimeGILState_SetThreadState(gilstate, newts);
/* It should not be possible for more than one thread state
Py_FatalError("Invalid thread state for this thread");
errno = err;
}
+#endif
+#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
+ PyThread_tss_set(&gilstate->autoTSSkey, newts);
#endif
return oldts;
}
/* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
called by Py_Initialize() */
+#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
assert(_PyEval_ThreadsInitialized(runtime));
+#endif
assert(gilstate->autoInterpreterState);
PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);