Skip to content

Commit e838a93

Browse files
authored
bpo-40522: _PyThreadState_Swap() sets autoTSSkey (GH-19939)
In the experimental isolated subinterpreters build mode, _PyThreadState_GET() gets the autoTSSkey variable and _PyThreadState_Swap() sets the autoTSSkey variable. * Add _PyThreadState_GetTSS() * _PyRuntimeState_GetThreadState() and _PyThreadState_GET() return _PyThreadState_GetTSS() * PyEval_SaveThread() sets the autoTSSkey variable to current Python thread state rather than NULL. * eval_frame_handle_pending() doesn't check that _PyThreadState_Swap() result is NULL. * _PyThreadState_Swap() gets the current Python thread state with _PyThreadState_GetTSS() rather than _PyRuntimeGILState_GetThreadState(). * PyGILState_Ensure() no longer checks _PyEval_ThreadsInitialized() since it cannot access the current interpreter.
1 parent b4b5386 commit e838a93

File tree

3 files changed

+48
-2
lines changed

3 files changed

+48
-2
lines changed

Include/internal/pycore_pystate.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,18 @@ _Py_ThreadCanHandlePendingCalls(void)
4949
/* Variable and macro for in-line access to current thread
5050
and interpreter state */
5151

52-
static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime) {
52+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
53+
PyAPI_FUNC(PyThreadState*) _PyThreadState_GetTSS(void);
54+
#endif
55+
56+
static inline PyThreadState*
57+
_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
58+
{
59+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
60+
return _PyThreadState_GetTSS();
61+
#else
5362
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->gilstate.tstate_current);
63+
#endif
5464
}
5565

5666
/* Get the current Python thread state.
@@ -62,8 +72,14 @@ static inline PyThreadState* _PyRuntimeState_GetThreadState(_PyRuntimeState *run
6272
The caller must hold the GIL.
6373
6474
See also PyThreadState_Get() and PyThreadState_GET(). */
65-
static inline PyThreadState *_PyThreadState_GET(void) {
75+
static inline PyThreadState*
76+
_PyThreadState_GET(void)
77+
{
78+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
79+
return _PyThreadState_GetTSS();
80+
#else
6681
return _PyRuntimeState_GetThreadState(&_PyRuntime);
82+
#endif
6783
}
6884

6985
/* Redefine PyThreadState_GET() as an alias to _PyThreadState_GET() */

Python/ceval.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,9 +380,13 @@ PyEval_AcquireThread(PyThreadState *tstate)
380380
take_gil(tstate);
381381

382382
struct _gilstate_runtime_state *gilstate = &tstate->interp->runtime->gilstate;
383+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
384+
(void)_PyThreadState_Swap(gilstate, tstate);
385+
#else
383386
if (_PyThreadState_Swap(gilstate, tstate) != NULL) {
384387
Py_FatalError("non-NULL old thread state");
385388
}
389+
#endif
386390
}
387391

388392
void
@@ -443,7 +447,12 @@ PyThreadState *
443447
PyEval_SaveThread(void)
444448
{
445449
_PyRuntimeState *runtime = &_PyRuntime;
450+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
451+
PyThreadState *old_tstate = _PyThreadState_GET();
452+
PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, old_tstate);
453+
#else
446454
PyThreadState *tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
455+
#endif
447456
ensure_tstate_not_null(__func__, tstate);
448457

449458
struct _ceval_runtime_state *ceval = &runtime->ceval;
@@ -866,9 +875,13 @@ eval_frame_handle_pending(PyThreadState *tstate)
866875

867876
take_gil(tstate);
868877

878+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
879+
(void)_PyThreadState_Swap(&runtime->gilstate, tstate);
880+
#else
869881
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
870882
Py_FatalError("orphan tstate");
871883
}
884+
#endif
872885
}
873886

874887
/* Check for asynchronous exception. */

Python/pystate.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -956,6 +956,14 @@ _PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
956956
}
957957

958958

959+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
960+
PyThreadState*
961+
_PyThreadState_GetTSS(void) {
962+
return PyThread_tss_get(&_PyRuntime.gilstate.autoTSSkey);
963+
}
964+
#endif
965+
966+
959967
PyThreadState *
960968
_PyThreadState_UncheckedGet(void)
961969
{
@@ -975,7 +983,11 @@ PyThreadState_Get(void)
975983
PyThreadState *
976984
_PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *newts)
977985
{
986+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
987+
PyThreadState *oldts = _PyThreadState_GetTSS();
988+
#else
978989
PyThreadState *oldts = _PyRuntimeGILState_GetThreadState(gilstate);
990+
#endif
979991

980992
_PyRuntimeGILState_SetThreadState(gilstate, newts);
981993
/* It should not be possible for more than one thread state
@@ -993,6 +1005,9 @@ _PyThreadState_Swap(struct _gilstate_runtime_state *gilstate, PyThreadState *new
9931005
Py_FatalError("Invalid thread state for this thread");
9941006
errno = err;
9951007
}
1008+
#endif
1009+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
1010+
PyThread_tss_set(&gilstate->autoTSSkey, newts);
9961011
#endif
9971012
return oldts;
9981013
}
@@ -1363,7 +1378,9 @@ PyGILState_Ensure(void)
13631378

13641379
/* Ensure that _PyEval_InitThreads() and _PyGILState_Init() have been
13651380
called by Py_Initialize() */
1381+
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
13661382
assert(_PyEval_ThreadsInitialized(runtime));
1383+
#endif
13671384
assert(gilstate->autoInterpreterState);
13681385

13691386
PyThreadState *tcur = (PyThreadState *)PyThread_tss_get(&gilstate->autoTSSkey);

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy