Skip to content

Commit

Permalink
Use PyInterpreterConfig.own_gil.
Browse files Browse the repository at this point in the history
  • Loading branch information
ericsnowcurrently committed May 5, 2023
1 parent a73f36f commit 37bf29c
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 11 deletions.
2 changes: 1 addition & 1 deletion Include/internal/pycore_ceval.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ _PyEval_Vector(PyThreadState *tstate,
PyObject *kwnames);

extern int _PyEval_ThreadsInitialized(void);
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate);
extern PyStatus _PyEval_InitGIL(PyThreadState *tstate, int own_gil);
extern void _PyEval_FiniGIL(PyInterpreterState *interp);

extern void _PyEval_ReleaseLock(PyThreadState *tstate);
Expand Down
1 change: 1 addition & 0 deletions Include/internal/pycore_ceval_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ struct _pending_calls {
struct _ceval_state {
int recursion_limit;
struct _gil_runtime_state *gil;
int own_gil;
/* This single variable consolidates all requests to break out of
the fast path in the eval loop. */
_Py_atomic_int eval_breaker;
Expand Down
13 changes: 9 additions & 4 deletions Lib/test/test_capi/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -1420,14 +1420,18 @@ def test_configured_settings(self):

# expected to work
for config, expected in {
(True, True, True, True, True, True, True): ALL_FLAGS,
(True, False, False, False, False, False, False): OBMALLOC,
(True, True, True, True, True, True, True):
(ALL_FLAGS, True),
(True, False, False, False, False, False, False):
(OBMALLOC, False),
(False, False, False, True, False, True, False):
THREADS | EXTENSIONS,
(THREADS | EXTENSIONS, False),
}.items():
kwargs = dict(zip(kwlist, config))
exp_flags, exp_gil = expected
expected = {
'feature_flags': expected,
'feature_flags': exp_flags,
'own_gil': exp_gil,
}
with self.subTest(config):
r, w = os.pipe()
Expand Down Expand Up @@ -1494,6 +1498,7 @@ def check(enabled, override):
flags = BASE_FLAGS | EXTENSIONS if enabled else BASE_FLAGS
settings = {
'feature_flags': flags,
'own_gil': False,
}

expected = {
Expand Down
1 change: 1 addition & 0 deletions Lib/test/test_embed.py
Original file line number Diff line number Diff line change
Expand Up @@ -1666,6 +1666,7 @@ def test_init_main_interpreter_settings(self):
# All optional features should be enabled.
'feature_flags':
OBMALLOC | FORK | EXEC | THREADS | DAEMON_THREADS,
'own_gil': True,
}
out, err = self.run_embedded_interpreter(
'test_init_main_interpreter_settings',
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_import/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -1640,7 +1640,7 @@ class SubinterpImportTests(unittest.TestCase):
)
ISOLATED = dict(
use_main_obmalloc=False,
own_gil=False,
own_gil=True,
)
NOT_ISOLATED = {k: not v for k, v in ISOLATED.items()}

Expand Down
7 changes: 7 additions & 0 deletions Modules/_testinternalcapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -729,6 +729,13 @@ get_interp_settings(PyObject *self, PyObject *args)
return NULL;
}

/* "own GIL" */
PyObject *own_gil = interp->ceval.own_gil ? Py_True : Py_False;
if (PyDict_SetItemString(settings, "own_gil", own_gil) != 0) {
Py_DECREF(settings);
return NULL;
}

return settings;
}

Expand Down
23 changes: 22 additions & 1 deletion Python/ceval_gil.c
Original file line number Diff line number Diff line change
Expand Up @@ -500,9 +500,18 @@ PyEval_ThreadsInitialized(void)
}

PyStatus
_PyEval_InitGIL(PyThreadState *tstate)
_PyEval_InitGIL(PyThreadState *tstate, int own_gil)
{
assert(tstate->interp->ceval.gil == NULL);
if (!own_gil) {
PyInterpreterState *main_interp = _PyInterpreterState_Main();
assert(tstate->interp != main_interp);
struct _gil_runtime_state *gil = main_interp->ceval.gil;
assert(gil_created(gil));
tstate->interp->ceval.gil = gil;
tstate->interp->ceval.own_gil = 0;
return _PyStatus_OK();
}

/* XXX per-interpreter GIL */
struct _gil_runtime_state *gil = &tstate->interp->runtime->ceval.gil;
Expand All @@ -512,15 +521,19 @@ _PyEval_InitGIL(PyThreadState *tstate)
and destroy it. */
assert(gil_created(gil));
tstate->interp->ceval.gil = gil;
// XXX For now we lie.
tstate->interp->ceval.own_gil = 1;
return _PyStatus_OK();
}
assert(own_gil);

assert(!gil_created(gil));

PyThread_init_thread();
create_gil(gil);
assert(gil_created(gil));
tstate->interp->ceval.gil = gil;
tstate->interp->ceval.own_gil = 1;
take_gil(tstate);
return _PyStatus_OK();
}
Expand All @@ -530,6 +543,14 @@ _PyEval_FiniGIL(PyInterpreterState *interp)
{
if (interp->ceval.gil == NULL) {
/* It was already finalized (or hasn't been initialized yet). */
assert(!interp->ceval.own_gil);
return;
}
else if (!interp->ceval.own_gil) {
PyInterpreterState *main_interp = _PyInterpreterState_Main();
assert(interp != main_interp);
assert(interp->ceval.gil == main_interp->ceval.gil);
interp->ceval.gil = NULL;
return;
}

Expand Down
8 changes: 4 additions & 4 deletions Python/pylifecycle.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,7 +585,7 @@ init_interp_settings(PyInterpreterState *interp,


static PyStatus
init_interp_create_gil(PyThreadState *tstate)
init_interp_create_gil(PyThreadState *tstate, int own_gil)
{
PyStatus status;

Expand All @@ -600,7 +600,7 @@ init_interp_create_gil(PyThreadState *tstate)
}

/* Create the GIL and take it */
status = _PyEval_InitGIL(tstate);
status = _PyEval_InitGIL(tstate, own_gil);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
Expand Down Expand Up @@ -647,7 +647,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
_PyThreadState_Bind(tstate);
(void) PyThreadState_Swap(tstate);

status = init_interp_create_gil(tstate);
status = init_interp_create_gil(tstate, config.own_gil);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
Expand Down Expand Up @@ -2049,7 +2049,7 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config)
goto error;
}

status = init_interp_create_gil(tstate);
status = init_interp_create_gil(tstate, config->own_gil);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}
Expand Down

0 comments on commit 37bf29c

Please sign in to comment.