Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 7be4e35

Browse filesBrowse files
authored
bpo-40513: Per-interpreter GIL (GH-19943)
In the experimental isolated subinterpreters build mode, the GIL is now per-interpreter. Move gil from _PyRuntimeState.ceval to PyInterpreterState.ceval. new_interpreter() always get the config from the main interpreter.
1 parent 0dd5e7a commit 7be4e35
Copy full SHA for 7be4e35

File tree

6 files changed

+82
-5
lines changed
Filter options

6 files changed

+82
-5
lines changed

‎Include/internal/pycore_ceval.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_ceval.h
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,11 @@ extern PyObject *_PyEval_EvalCode(
5050
PyObject *kwdefs, PyObject *closure,
5151
PyObject *name, PyObject *qualname);
5252

53+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
54+
extern int _PyEval_ThreadsInitialized(PyInterpreterState *interp);
55+
#else
5356
extern int _PyEval_ThreadsInitialized(struct pyruntimestate *runtime);
57+
#endif
5458
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
5559
extern void _PyEval_FiniGIL(PyThreadState *tstate);
5660

‎Include/internal/pycore_interp.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_interp.h
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ struct _ceval_state {
4646
/* Request for dropping the GIL */
4747
_Py_atomic_int gil_drop_request;
4848
struct _pending_calls pending;
49+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
50+
struct _gil_runtime_state gil;
51+
#endif
4952
};
5053

5154

‎Include/internal/pycore_runtime.h

Copy file name to clipboardExpand all lines: Include/internal/pycore_runtime.h
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,9 @@ struct _ceval_runtime_state {
1919
the main thread of the main interpreter can handle signals: see
2020
_Py_ThreadCanHandleSignals(). */
2121
_Py_atomic_int signals_pending;
22+
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
2223
struct _gil_runtime_state gil;
24+
#endif
2325
};
2426

2527
/* GIL state */

‎Python/ceval.c

Copy file name to clipboardExpand all lines: Python/ceval.c
+46-2Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,21 @@ ensure_tstate_not_null(const char *func, PyThreadState *tstate)
250250
}
251251

252252

253+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
254+
int
255+
_PyEval_ThreadsInitialized(PyInterpreterState *interp)
256+
{
257+
return gil_created(&interp->ceval.gil);
258+
}
259+
260+
int
261+
PyEval_ThreadsInitialized(void)
262+
{
263+
// Fatal error if there is no current interpreter
264+
PyInterpreterState *interp = PyInterpreterState_Get();
265+
return _PyEval_ThreadsInitialized(interp);
266+
}
267+
#else
253268
int
254269
_PyEval_ThreadsInitialized(_PyRuntimeState *runtime)
255270
{
@@ -262,18 +277,25 @@ PyEval_ThreadsInitialized(void)
262277
_PyRuntimeState *runtime = &_PyRuntime;
263278
return _PyEval_ThreadsInitialized(runtime);
264279
}
280+
#endif
265281

266282
PyStatus
267283
_PyEval_InitGIL(PyThreadState *tstate)
268284
{
285+
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
269286
if (!_Py_IsMainInterpreter(tstate)) {
270287
/* Currently, the GIL is shared by all interpreters,
271288
and only the main interpreter is responsible to create
272289
and destroy it. */
273290
return _PyStatus_OK();
274291
}
292+
#endif
275293

294+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
295+
struct _gil_runtime_state *gil = &tstate->interp->ceval.gil;
296+
#else
276297
struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
298+
#endif
277299
assert(!gil_created(gil));
278300

279301
PyThread_init_thread();
@@ -288,14 +310,20 @@ _PyEval_InitGIL(PyThreadState *tstate)
288310
void
289311
_PyEval_FiniGIL(PyThreadState *tstate)
290312
{
313+
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
291314
if (!_Py_IsMainInterpreter(tstate)) {
292315
/* Currently, the GIL is shared by all interpreters,
293316
and only the main interpreter is responsible to create
294317
and destroy it. */
295318
return;
296319
}
320+
#endif
297321

322+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
323+
struct _gil_runtime_state *gil = &tstate->interp->ceval.gil;
324+
#else
298325
struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
326+
#endif
299327
if (!gil_created(gil)) {
300328
/* First Py_InitializeFromConfig() call: the GIL doesn't exist
301329
yet: do nothing. */
@@ -413,13 +441,18 @@ PyEval_ReleaseThread(PyThreadState *tstate)
413441
void
414442
_PyEval_ReInitThreads(_PyRuntimeState *runtime)
415443
{
444+
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
445+
ensure_tstate_not_null(__func__, tstate);
446+
447+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
448+
struct _gil_runtime_state *gil = &tstate->interp->ceval.gil;
449+
#else
416450
struct _gil_runtime_state *gil = &runtime->ceval.gil;
451+
#endif
417452
if (!gil_created(gil)) {
418453
return;
419454
}
420455
recreate_gil(gil);
421-
PyThreadState *tstate = _PyRuntimeState_GetThreadState(runtime);
422-
ensure_tstate_not_null(__func__, tstate);
423456

424457
take_gil(tstate);
425458

@@ -457,7 +490,11 @@ PyEval_SaveThread(void)
457490

458491
struct _ceval_runtime_state *ceval = &runtime->ceval;
459492
struct _ceval_state *ceval2 = &tstate->interp->ceval;
493+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
494+
assert(gil_created(&ceval2->gil));
495+
#else
460496
assert(gil_created(&ceval->gil));
497+
#endif
461498
drop_gil(ceval, ceval2, tstate);
462499
return tstate;
463500
}
@@ -716,7 +753,9 @@ void
716753
_PyEval_InitRuntimeState(struct _ceval_runtime_state *ceval)
717754
{
718755
_Py_CheckRecursionLimit = Py_DEFAULT_RECURSION_LIMIT;
756+
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
719757
_gil_initialize(&ceval->gil);
758+
#endif
720759
}
721760

722761
int
@@ -731,6 +770,11 @@ _PyEval_InitState(struct _ceval_state *ceval)
731770
if (pending->lock == NULL) {
732771
return -1;
733772
}
773+
774+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
775+
_gil_initialize(&ceval->gil);
776+
#endif
777+
734778
return 0;
735779
}
736780

‎Python/ceval_gil.h

Copy file name to clipboardExpand all lines: Python/ceval_gil.h
+22-2Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,11 @@ static void
144144
drop_gil(struct _ceval_runtime_state *ceval, struct _ceval_state *ceval2,
145145
PyThreadState *tstate)
146146
{
147+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
148+
struct _gil_runtime_state *gil = &ceval2->gil;
149+
#else
147150
struct _gil_runtime_state *gil = &ceval->gil;
151+
#endif
148152
if (!_Py_atomic_load_relaxed(&gil->locked)) {
149153
Py_FatalError("drop_gil: GIL is not locked");
150154
}
@@ -228,7 +232,11 @@ take_gil(PyThreadState *tstate)
228232
PyInterpreterState *interp = tstate->interp;
229233
struct _ceval_runtime_state *ceval = &interp->runtime->ceval;
230234
struct _ceval_state *ceval2 = &interp->ceval;
235+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
236+
struct _gil_runtime_state *gil = &ceval2->gil;
237+
#else
231238
struct _gil_runtime_state *gil = &ceval->gil;
239+
#endif
232240

233241
/* Check that _PyEval_InitThreads() was called to create the lock */
234242
assert(gil_created(gil));
@@ -320,10 +328,22 @@ take_gil(PyThreadState *tstate)
320328

321329
void _PyEval_SetSwitchInterval(unsigned long microseconds)
322330
{
323-
_PyRuntime.ceval.gil.interval = microseconds;
331+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
332+
PyInterpreterState *interp = PyInterpreterState_Get();
333+
struct _gil_runtime_state *gil = &interp->ceval.gil;
334+
#else
335+
struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil;
336+
#endif
337+
gil->interval = microseconds;
324338
}
325339

326340
unsigned long _PyEval_GetSwitchInterval()
327341
{
328-
return _PyRuntime.ceval.gil.interval;
342+
#ifdef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
343+
PyInterpreterState *interp = PyInterpreterState_Get();
344+
struct _gil_runtime_state *gil = &interp->ceval.gil;
345+
#else
346+
struct _gil_runtime_state *gil = &_PyRuntime.ceval.gil;
347+
#endif
348+
return gil->interval;
329349
}

‎Python/pylifecycle.c

Copy file name to clipboardExpand all lines: Python/pylifecycle.c
+5-1Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1561,9 +1561,13 @@ new_interpreter(PyThreadState **tstate_p, int isolated_subinterpreter)
15611561

15621562
/* Copy the current interpreter config into the new interpreter */
15631563
const PyConfig *config;
1564+
#ifndef EXPERIMENTAL_ISOLATED_SUBINTERPRETERS
15641565
if (save_tstate != NULL) {
15651566
config = _PyInterpreterState_GetConfig(save_tstate->interp);
1566-
} else {
1567+
}
1568+
else
1569+
#endif
1570+
{
15671571
/* No current thread state, copy from the main interpreter */
15681572
PyInterpreterState *main_interp = PyInterpreterState_Main();
15691573
config = _PyInterpreterState_GetConfig(main_interp);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.