Skip to content

Commit 37bf29c

Browse files
Use PyInterpreterConfig.own_gil.
1 parent a73f36f commit 37bf29c

File tree

8 files changed

+46
-11
lines changed

8 files changed

+46
-11
lines changed

Include/internal/pycore_ceval.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ _PyEval_Vector(PyThreadState *tstate,
9797
PyObject *kwnames);
9898

9999
extern int _PyEval_ThreadsInitialized(void);
100-
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
100+
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
101101
extern void _PyEval_FiniGIL(PyInterpreterState *interp);
102102

103103
extern void _PyEval_ReleaseLock(PyThreadState *tstate);

Include/internal/pycore_ceval_state.h

+1
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ struct _pending_calls {
8686
struct _ceval_state {
8787
int recursion_limit;
8888
struct _gil_runtime_state *gil;
89+
int own_gil;
8990
/* This single variable consolidates all requests to break out of
9091
the fast path in the eval loop. */
9192
_Py_atomic_int eval_breaker;

Lib/test/test_capi/test_misc.py

+9-4
Original file line numberDiff line numberDiff line change
@@ -1420,14 +1420,18 @@ def test_configured_settings(self):
14201420

14211421
# expected to work
14221422
for config, expected in {
1423-
(True, True, True, True, True, True, True): ALL_FLAGS,
1424-
(True, False, False, False, False, False, False): OBMALLOC,
1423+
(True, True, True, True, True, True, True):
1424+
(ALL_FLAGS, True),
1425+
(True, False, False, False, False, False, False):
1426+
(OBMALLOC, False),
14251427
(False, False, False, True, False, True, False):
1426-
THREADS | EXTENSIONS,
1428+
(THREADS | EXTENSIONS, False),
14271429
}.items():
14281430
kwargs = dict(zip(kwlist, config))
1431+
exp_flags, exp_gil = expected
14291432
expected = {
1430-
'feature_flags': expected,
1433+
'feature_flags': exp_flags,
1434+
'own_gil': exp_gil,
14311435
}
14321436
with self.subTest(config):
14331437
r, w = os.pipe()
@@ -1494,6 +1498,7 @@ def check(enabled, override):
14941498
flags = BASE_FLAGS | EXTENSIONS if enabled else BASE_FLAGS
14951499
settings = {
14961500
'feature_flags': flags,
1501+
'own_gil': False,
14971502
}
14981503

14991504
expected = {

Lib/test/test_embed.py

+1
Original file line numberDiff line numberDiff line change
@@ -1666,6 +1666,7 @@ def test_init_main_interpreter_settings(self):
16661666
# All optional features should be enabled.
16671667
'feature_flags':
16681668
OBMALLOC | FORK | EXEC | THREADS | DAEMON_THREADS,
1669+
'own_gil': True,
16691670
}
16701671
out, err = self.run_embedded_interpreter(
16711672
'test_init_main_interpreter_settings',

Lib/test/test_import/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1640,7 +1640,7 @@ class SubinterpImportTests(unittest.TestCase):
16401640
)
16411641
ISOLATED = dict(
16421642
use_main_obmalloc=False,
1643-
own_gil=False,
1643+
own_gil=True,
16441644
)
16451645
NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()}
16461646

Modules/_testinternalcapi.c

+7
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,13 @@ get_interp_settings(PyObject *self, PyObject *args)
729729
return NULL;
730730
}
731731

732+
/* "own GIL" */
733+
PyObject *own_gil = interp->ceval.own_gil ? Py_True : Py_False;
734+
if (PyDict_SetItemString(settings, "own_gil", own_gil) != 0) {
735+
Py_DECREF(settings);
736+
return NULL;
737+
}
738+
732739
return settings;
733740
}
734741

Python/ceval_gil.c

+22-1
Original file line numberDiff line numberDiff line change
@@ -500,9 +500,18 @@ PyEval_ThreadsInitialized(void)
500500
}
501501

502502
PyStatus
503-
_PyEval_InitGIL(PyThreadState *tstate)
503+
_PyEval_InitGIL(PyThreadState *tstate, int own_gil)
504504
{
505505
assert(tstate->interp->ceval.gil == NULL);
506+
if (!own_gil) {
507+
PyInterpreterState *main_interp = _PyInterpreterState_Main();
508+
assert(tstate->interp != main_interp);
509+
struct _gil_runtime_state *gil = main_interp->ceval.gil;
510+
assert(gil_created(gil));
511+
tstate->interp->ceval.gil = gil;
512+
tstate->interp->ceval.own_gil = 0;
513+
return _PyStatus_OK();
514+
}
506515

507516
/* XXX per-interpreter GIL */
508517
struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
@@ -512,15 +521,19 @@ _PyEval_InitGIL(PyThreadState *tstate)
512521
and destroy it. */
513522
assert(gil_created(gil));
514523
tstate->interp->ceval.gil = gil;
524+
// XXX For now we lie.
525+
tstate->interp->ceval.own_gil = 1;
515526
return _PyStatus_OK();
516527
}
528+
assert(own_gil);
517529

518530
assert(!gil_created(gil));
519531

520532
PyThread_init_thread();
521533
create_gil(gil);
522534
assert(gil_created(gil));
523535
tstate->interp->ceval.gil = gil;
536+
tstate->interp->ceval.own_gil = 1;
524537
take_gil(tstate);
525538
return _PyStatus_OK();
526539
}
@@ -530,6 +543,14 @@ _PyEval_FiniGIL(PyInterpreterState *interp)
530543
{
531544
if (interp->ceval.gil == NULL) {
532545
/* It was already finalized (or hasn't been initialized yet). */
546+
assert(!interp->ceval.own_gil);
547+
return;
548+
}
549+
else if (!interp->ceval.own_gil) {
550+
PyInterpreterState *main_interp = _PyInterpreterState_Main();
551+
assert(interp != main_interp);
552+
assert(interp->ceval.gil == main_interp->ceval.gil);
553+
interp->ceval.gil = NULL;
533554
return;
534555
}
535556

Python/pylifecycle.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ init_interp_settings(PyInterpreterState *interp,
585585

586586

587587
static PyStatus
588-
init_interp_create_gil(PyThreadState *tstate)
588+
init_interp_create_gil(PyThreadState *tstate, int own_gil)
589589
{
590590
PyStatus status;
591591

@@ -600,7 +600,7 @@ init_interp_create_gil(PyThreadState *tstate)
600600
}
601601

602602
/* Create the GIL and take it */
603-
status = _PyEval_InitGIL(tstate);
603+
status = _PyEval_InitGIL(tstate, own_gil);
604604
if (_PyStatus_EXCEPTION(status)) {
605605
return status;
606606
}
@@ -647,7 +647,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
647647
_PyThreadState_Bind(tstate);
648648
(void) PyThreadState_Swap(tstate);
649649

650-
status = init_interp_create_gil(tstate);
650+
status = init_interp_create_gil(tstate, config.own_gil);
651651
if (_PyStatus_EXCEPTION(status)) {
652652
return status;
653653
}
@@ -2049,7 +2049,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
20492049
goto error;
20502050
}
20512051

2052-
status = init_interp_create_gil(tstate);
2052+
status = init_interp_create_gil(tstate, config->own_gil);
20532053
if (_PyStatus_EXCEPTION(status)) {
20542054
goto error;
20552055
}

0 commit comments

Comments
 (0)