Movatterモバイル変換


[0]ホーム

URL:


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

Sign up
Appearance settings

gh-125286: Share the Main Refchain With Legacy Interpreters#125709

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 ourterms of service andprivacy 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 from1 commit
Commits
Show all changes
16 commits
Select commitHold shift + click to select a range
53cfb82
Share the main refchain with legacy interpreters.
ericsnowcurrentlyOct 18, 2024
b2bf609
Add a has_own_refchain() helper function.
ericsnowcurrentlyOct 18, 2024
203c112
Drop _Py_NormalizeImmortalReference().
ericsnowcurrentlyOct 21, 2024
ffe2633
Drop has_own_refchain() calls where not needed.
ericsnowcurrentlyOct 21, 2024
8d52258
Call _PyObject_InitState() *after* computing the feature flags.
ericsnowcurrentlyOct 21, 2024
216dde2
Revert "Call _PyObject_InitState() *after* computing the feature flags."
ericsnowcurrentlyOct 21, 2024
fbc4e2d
Revert "Drop has_own_refchain() calls where not needed."
ericsnowcurrentlyOct 21, 2024
cb06847
has_own_refchain() -> maybe_fix_refchain()
ericsnowcurrentlyOct 21, 2024
7aa33a9
Handle late runtime fini correctly.
ericsnowcurrentlyOct 21, 2024
3421a19
Pass the interpreter config to init_interpreter().
ericsnowcurrentlyOct 22, 2024
b276454
Revert "Pass the interpreter config to init_interpreter()."
ericsnowcurrentlyOct 22, 2024
7ab086c
Move the _PyObject_InitState() call out of init_interpreter().
ericsnowcurrentlyOct 22, 2024
9d539f6
Add docs and a What's New entry
encukouOct 22, 2024
d80fe6a
Fix typos.
ericsnowcurrentlyOct 22, 2024
1360d86
Do not try to destroy the refchain if it is NULL.
ericsnowcurrentlyOct 22, 2024
090b528
Docs: Link to the new sys.getobjects() docs
encukouOct 23, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
PrevPrevious commit
NextNext commit
Revert "Pass the interpreter config to init_interpreter()."
This reverts commit3421a19.
  • Loading branch information
@ericsnowcurrently
ericsnowcurrently committedOct 22, 2024
commitb276454b1e92ca3f2917d06f17a461c59df243f7
1 change: 0 additions & 1 deletionInclude/internal/pycore_interp.h
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -399,7 +399,6 @@ extern int _PyInterpreterState_HasFeature(PyInterpreterState *interp,

PyAPI_FUNC(PyStatus) _PyInterpreterState_New(
PyThreadState *tstate,
const PyInterpreterConfig *config,
PyInterpreterState **pinterp);


Expand Down
96 changes: 80 additions & 16 deletionsPython/pylifecycle.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -551,6 +551,62 @@ pycore_init_runtime(_PyRuntimeState *runtime,
}


static PyStatus
init_interp_settings(PyInterpreterState *interp,
const PyInterpreterConfig *config)
{
assert(interp->feature_flags == 0);

if (config->use_main_obmalloc) {
interp->feature_flags |= Py_RTFLAGS_USE_MAIN_OBMALLOC;
}
else if (!config->check_multi_interp_extensions) {
/* The reason: PyModuleDef.m_base.m_copy leaks objects between
interpreters. */
return _PyStatus_ERR("per-interpreter obmalloc does not support "
"single-phase init extension modules");
}
#ifdef Py_GIL_DISABLED
if (!_Py_IsMainInterpreter(interp) &&
!config->check_multi_interp_extensions)
{
return _PyStatus_ERR("The free-threaded build does not support "
"single-phase init extension modules in "
"subinterpreters");
}
#endif

if (config->allow_fork) {
interp->feature_flags |= Py_RTFLAGS_FORK;
}
if (config->allow_exec) {
interp->feature_flags |= Py_RTFLAGS_EXEC;
}
// Note that fork+exec is always allowed.

if (config->allow_threads) {
interp->feature_flags |= Py_RTFLAGS_THREADS;
}
if (config->allow_daemon_threads) {
interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS;
}

if (config->check_multi_interp_extensions) {
interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
}

switch (config->gil) {
case PyInterpreterConfig_DEFAULT_GIL: break;
case PyInterpreterConfig_SHARED_GIL: break;
case PyInterpreterConfig_OWN_GIL: break;
default:
return _PyStatus_ERR("invalid interpreter config 'gil' value");
}

return _PyStatus_OK();
}


static void
init_interp_create_gil(PyThreadState *tstate, int gil)
{
Expand DownExpand Up@@ -587,15 +643,8 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
PyThreadState **tstate_p)
{
PyStatus status;

PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
// The main interpreter always has its own GIL and supports single-phase
// init extensions.
config.gil = PyInterpreterConfig_OWN_GIL;
config.check_multi_interp_extensions = 0;

PyInterpreterState *interp;
status = _PyInterpreterState_New(NULL, &config, &interp);
status = _PyInterpreterState_New(NULL, &interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
Expand All@@ -615,6 +664,16 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
return status;
}

PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;
// The main interpreter always has its own GIL and supports single-phase
// init extensions.
config.gil = PyInterpreterConfig_OWN_GIL;
config.check_multi_interp_extensions = 0;
status = init_interp_settings(interp, &config);
if (_PyStatus_EXCEPTION(status)) {
return status;
}

// initialize the interp->obmalloc state. This must be done after
// the settings are loaded (so that feature_flags are set) but before
// any calls are made to obmalloc functions.
Expand DownExpand Up@@ -2194,19 +2253,18 @@ new_interpreter(PyThreadState **tstate_p,
interpreters: disable PyGILState_Check(). */
runtime->gilstate.check_enabled = 0;

PyInterpreterState *interp = PyInterpreterState_New();
if (interp == NULL) {
*tstate_p = NULL;
return _PyStatus_OK();
}
_PyInterpreterState_SetWhence(interp, whence);
interp->_ready = 1;

// XXX Might new_interpreter() have been called without the GIL held?
PyThreadState *save_tstate = _PyThreadState_GET();
PyThreadState *tstate = NULL;

PyInterpreterState *interp;
status = _PyInterpreterState_New(save_tstate, config, &interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
_PyInterpreterState_SetWhence(interp, whence);
interp->_ready = 1;

/* From this point until the init_interp_create_gil() call,
we must not do anything that requires that the GIL be held
(or otherwise exist). That applies whether or not the new
Expand All@@ -2233,6 +2291,12 @@ new_interpreter(PyThreadState **tstate_p,
goto error;
}

/* This does not require that the GIL be held. */
status = init_interp_settings(interp, config);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}

// initialize the interp->obmalloc state. This must be done after
// the settings are loaded (so that feature_flags are set) but before
// any calls are made to obmalloc functions.
Expand Down
77 changes: 5 additions & 72 deletionsPython/pystate.c
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -581,66 +581,9 @@ free_interpreter(PyInterpreterState *interp)
PyMem_RawFree(interp);
}
}

static PyStatus
init_interp_settings(PyInterpreterState *interp,
const PyInterpreterConfig *config)
{
assert(interp->feature_flags == 0);

if (config->use_main_obmalloc) {
interp->feature_flags |= Py_RTFLAGS_USE_MAIN_OBMALLOC;
}
else if (!config->check_multi_interp_extensions) {
/* The reason: PyModuleDef.m_base.m_copy leaks objects between
interpreters. */
return _PyStatus_ERR("per-interpreter obmalloc does not support "
"single-phase init extension modules");
}
#ifdef Py_GIL_DISABLED
if (!_Py_IsMainInterpreter(interp) &&
!config->check_multi_interp_extensions)
{
return _PyStatus_ERR("The free-threaded build does not support "
"single-phase init extension modules in "
"subinterpreters");
}
#endif

if (config->allow_fork) {
interp->feature_flags |= Py_RTFLAGS_FORK;
}
if (config->allow_exec) {
interp->feature_flags |= Py_RTFLAGS_EXEC;
}
// Note that fork+exec is always allowed.

if (config->allow_threads) {
interp->feature_flags |= Py_RTFLAGS_THREADS;
}
if (config->allow_daemon_threads) {
interp->feature_flags |= Py_RTFLAGS_DAEMON_THREADS;
}

if (config->check_multi_interp_extensions) {
interp->feature_flags |= Py_RTFLAGS_MULTI_INTERP_EXTENSIONS;
}

switch (config->gil) {
case PyInterpreterConfig_DEFAULT_GIL: break;
case PyInterpreterConfig_SHARED_GIL: break;
case PyInterpreterConfig_OWN_GIL: break;
default:
return _PyStatus_ERR("invalid interpreter config 'gil' value");
}

return _PyStatus_OK();
}

#ifndef NDEBUG
static inline int check_interpreter_whence(long);
#endif

/* Get the interpreter state to a minimal consistent state.
Further init happens in pylifecycle.c before it can be used.
All fields not initialized here are expected to be zeroed out,
Expand All@@ -664,8 +607,7 @@ static PyStatus
init_interpreter(PyInterpreterState *interp,
_PyRuntimeState *runtime, int64_t id,
PyInterpreterState *next,
long whence,
const PyInterpreterConfig *config)
long whence)
{
if (interp->_initialized) {
return _PyStatus_ERR("interpreter already initialized");
Expand All@@ -687,15 +629,10 @@ init_interpreter(PyInterpreterState *interp,
assert(next != NULL || (interp == runtime->interpreters.main));
interp->next = next;

PyStatus status = init_interp_settings(interp, config);
if (_PyStatus_EXCEPTION(status)) {
return status;
}

// This relies on interp->feature_flags being set already,
// but currently we don't set that by this point.
// That's something to fix.
status = _PyObject_InitState(interp);
PyStatusstatus = _PyObject_InitState(interp);
if (_PyStatus_EXCEPTION(status)) {
return status;
}
Expand DownExpand Up@@ -736,9 +673,7 @@ init_interpreter(PyInterpreterState *interp,


PyStatus
_PyInterpreterState_New(PyThreadState *tstate,
const PyInterpreterConfig *config,
PyInterpreterState **pinterp)
_PyInterpreterState_New(PyThreadState *tstate, PyInterpreterState **pinterp)
{
*pinterp = NULL;

Expand DownExpand Up@@ -800,7 +735,7 @@ _PyInterpreterState_New(PyThreadState *tstate,

long whence = _PyInterpreterState_WHENCE_UNKNOWN;
status = init_interpreter(interp, runtime,
id, old_head, whence, config);
id, old_head, whence);
if (_PyStatus_EXCEPTION(status)) {
goto error;
}
Expand All@@ -827,10 +762,8 @@ PyInterpreterState_New(void)
// tstate can be NULL
PyThreadState *tstate = current_fast_get();

const PyInterpreterConfig config = _PyInterpreterConfig_LEGACY_INIT;

PyInterpreterState *interp;
PyStatus status = _PyInterpreterState_New(tstate, &config, &interp);
PyStatus status = _PyInterpreterState_New(tstate, &interp);
if (_PyStatus_EXCEPTION(status)) {
Py_ExitStatusException(status);
}
Expand Down

[8]ページ先頭

©2009-2025 Movatter.jp