10000 gh-99113: Add PyInterpreterConfig.own_gil by ericsnowcurrently · Pull Request #104204 · python/cpython · GitHub
[go: up one dir, main page]

Skip to content

gh-99113: Add PyInterpreterConfig.own_gil #104204

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
8000 Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Use PyInterpreterConfig.own_gil.
  • Loading branch information
ericsnowcurrently committed May 5, 2023
commit 37bf29c95dd6256496712fa0313233f762b7478d
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