Commit 396e0a8d authored by Eric Snow's avatar Eric Snow Committed by GitHub

bpo-36818: Add PyInterpreterState.runtime field. (gh-13129)

https://bugs.python.org/issue36818
parent 1c263e39
...@@ -110,9 +110,9 @@ struct _ts { ...@@ -110,9 +110,9 @@ struct _ts {
* if the thread holds the last reference to the lock, decref'ing the * if the thread holds the last reference to the lock, decref'ing the
* lock will delete the lock, and that may trigger arbitrary Python code * lock will delete the lock, and that may trigger arbitrary Python code
* if there's a weakref, with a callback, to the lock. But by this time * if there's a weakref, with a callback, to the lock. But by this time
* _PyRuntime.gilstate.tstate_current is already NULL, so only the simplest * _PyRuntimeState.gilstate.tstate_current is already NULL, so only the
* of C code can be allowed to run (in particular it must not be possible to * simplest of C code can be allowed to run (in particular it must not be
* release the GIL). * possible to release the GIL).
* So instead of holding the lock directly, the tstate holds a weakref to * So instead of holding the lock directly, the tstate holds a weakref to
* the lock: that's the value of on_delete_data below. Decref'ing a * the lock: that's the value of on_delete_data below. Decref'ing a
* weakref is harmless. * weakref is harmless.
......
...@@ -19,9 +19,10 @@ PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content); ...@@ -19,9 +19,10 @@ PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
* NB: While the object is tracked by the collector, it must be safe to call the * NB: While the object is tracked by the collector, it must be safe to call the
* ob_traverse method. * ob_traverse method.
* *
* Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags * Internal note: _PyRuntimeState.gc.generation0->_gc_prev doesn't have
* because it's not object header. So we don't use _PyGCHead_PREV() and * any bit flags because it's not object header. So we don't use
* _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations. * _PyGCHead_PREV() and _PyGCHead_SET_PREV() for it to avoid unnecessary
* bitwise operations.
* *
* The PyObject_GC_Track() function is the public version of this macro. * The PyObject_GC_Track() function is the public version of this macro.
*/ */
......
...@@ -39,13 +39,10 @@ extern PyStatus _PyFaulthandler_Init(int enable); ...@@ -39,13 +39,10 @@ extern PyStatus _PyFaulthandler_Init(int enable);
extern int _PyTraceMalloc_Init(int enable); extern int _PyTraceMalloc_Init(int enable);
extern PyObject * _PyBuiltin_Init(void); extern PyObject * _PyBuiltin_Init(void);
extern PyStatus _PySys_Create( extern PyStatus _PySys_Create(
_PyRuntimeState *runtime,
PyInterpreterState *interp, PyInterpreterState *interp,
PyObject **sysmod_p); PyObject **sysmod_p);
extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict); extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
extern int _PySys_InitMain( extern int _PySys_InitMain(PyInterpreterState *interp);
_PyRuntimeState *runtime,
PyInterpreterState *interp);
extern PyStatus _PyImport_Init(PyInterpreterState *interp); extern PyStatus _PyImport_Init(PyInterpreterState *interp);
extern PyStatus _PyExc_Init(void); extern PyStatus _PyExc_Init(void);
extern PyStatus _PyErr_Init(void); extern PyStatus _PyErr_Init(void);
...@@ -86,10 +83,7 @@ extern void _PyHash_Fini(void); ...@@ -86,10 +83,7 @@ extern void _PyHash_Fini(void);
extern int _PyTraceMalloc_Fini(void); extern int _PyTraceMalloc_Fini(void);
extern void _PyWarnings_Fini(PyInterpreterState *interp); extern void _PyWarnings_Fini(PyInterpreterState *interp);
extern void _PyGILState_Init( extern void _PyGILState_Init(PyThreadState *tstate);
_PyRuntimeState *runtime,
PyInterpreterState *interp,
PyThreadState *tstate);
extern void _PyGILState_Fini(_PyRuntimeState *runtime); extern void _PyGILState_Fini(_PyRuntimeState *runtime);
PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime); PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime);
......
...@@ -19,6 +19,9 @@ extern "C" { ...@@ -19,6 +19,9 @@ extern "C" {
#include "pycore_pymem.h" #include "pycore_pymem.h"
#include "pycore_warnings.h" #include "pycore_warnings.h"
// forward
struct pyruntimestate;
/* ceval state */ /* ceval state */
...@@ -68,6 +71,7 @@ struct _is { ...@@ -68,6 +71,7 @@ struct _is {
struct _is *next; struct _is *next;
struct _ts *tstate_head; struct _ts *tstate_head;
struct pyruntimestate *runtime;
int64_t id; int64_t id;
int64_t id_refcount; int64_t id_refcount;
...@@ -296,12 +300,8 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void); ...@@ -296,12 +300,8 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);
/* Other */ /* Other */
PyAPI_FUNC(void) _PyThreadState_Init( PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *tstate);
_PyRuntimeState *runtime, PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
PyThreadState *tstate);
PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
_PyRuntimeState *runtime,
PyThreadState *tstate);
PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap( PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
struct _gilstate_runtime_state *gilstate, struct _gilstate_runtime_state *gilstate,
......
...@@ -996,7 +996,7 @@ t_bootstrap(void *boot_raw) ...@@ -996,7 +996,7 @@ t_bootstrap(void *boot_raw)
tstate = boot->tstate; tstate = boot->tstate;
tstate->thread_id = PyThread_get_thread_ident(); tstate->thread_id = PyThread_get_thread_ident();
_PyThreadState_Init(&_PyRuntime, tstate); _PyThreadState_Init(tstate);
PyEval_AcquireThread(tstate); PyEval_AcquireThread(tstate);
tstate->interp->num_threads++; tstate->interp->num_threads++;
res = PyObject_Call(boot->func, boot->args, boot->keyw); res = PyObject_Call(boot->func, boot->args, boot->keyw);
......
...@@ -217,8 +217,9 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval) ...@@ -217,8 +217,9 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval)
} }
static inline void static inline void
exit_thread_if_finalizing(_PyRuntimeState *runtime, PyThreadState *tstate) exit_thread_if_finalizing(PyThreadState *tstate)
{ {
_PyRuntimeState *runtime = tstate->interp->runtime;
/* _Py_Finalizing is protected by the GIL */ /* _Py_Finalizing is protected by the GIL */
if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) { if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) {
drop_gil(&runtime->ceval, tstate); drop_gil(&runtime->ceval, tstate);
...@@ -236,7 +237,7 @@ PyEval_AcquireLock(void) ...@@ -236,7 +237,7 @@ PyEval_AcquireLock(void)
Py_FatalError("PyEval_AcquireLock: current thread state is NULL"); Py_FatalError("PyEval_AcquireLock: current thread state is NULL");
} }
take_gil(ceval, tstate); take_gil(ceval, tstate);
exit_thread_if_finalizing(runtime, tstate); exit_thread_if_finalizing(tstate);
} }
void void
...@@ -257,14 +258,15 @@ PyEval_AcquireThread(PyThreadState *tstate) ...@@ -257,14 +258,15 @@ PyEval_AcquireThread(PyThreadState *tstate)
if (tstate == NULL) { if (tstate == NULL) {
Py_FatalError("PyEval_AcquireThread: NULL new thread state"); Py_FatalError("PyEval_AcquireThread: NULL new thread state");
} }
assert(tstate->interp != NULL);
_PyRuntimeState *runtime = &_PyRuntime; _PyRuntimeState *runtime = tstate->interp->runtime;
struct _ceval_runtime_state *ceval = &runtime->ceval; struct _ceval_runtime_state *ceval = &runtime->ceval;
/* Check someone has called PyEval_InitThreads() to create the lock */ /* Check someone has called PyEval_InitThreads() to create the lock */
assert(gil_created(&ceval->gil)); assert(gil_created(&ceval->gil));
take_gil(ceval, tstate); take_gil(ceval, tstate);
exit_thread_if_finalizing(runtime, tstate); exit_thread_if_finalizing(tstate);
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
Py_FatalError("PyEval_AcquireThread: non-NULL old thread state"); Py_FatalError("PyEval_AcquireThread: non-NULL old thread state");
} }
...@@ -276,8 +278,9 @@ PyEval_ReleaseThread(PyThreadState *tstate) ...@@ -276,8 +278,9 @@ PyEval_ReleaseThread(PyThreadState *tstate)
if (tstate == NULL) { if (tstate == NULL) {
Py_FatalError("PyEval_ReleaseThread: NULL thread state"); Py_FatalError("PyEval_ReleaseThread: NULL thread state");
} }
assert(tstate->interp != NULL);
_PyRuntimeState *runtime = &_PyRuntime; _PyRuntimeState *runtime = tstate->interp->runtime;
PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL); PyThreadState *new_tstate = _PyThreadState_Swap(&runtime->gilstate, NULL);
if (new_tstate != tstate) { if (new_tstate != tstate) {
Py_FatalError("PyEval_ReleaseThread: wrong thread state"); Py_FatalError("PyEval_ReleaseThread: wrong thread state");
...@@ -308,7 +311,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime) ...@@ -308,7 +311,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime)
} }
/* Destroy all threads except the current one */ /* Destroy all threads except the current one */
_PyThreadState_DeleteExcept(runtime, current_tstate); _PyThreadState_DeleteExcept(current_tstate);
} }
/* This function is used to signal that async exceptions are waiting to be /* This function is used to signal that async exceptions are waiting to be
...@@ -337,17 +340,18 @@ PyEval_SaveThread(void) ...@@ -337,17 +340,18 @@ PyEval_SaveThread(void)
void void
PyEval_RestoreThread(PyThreadState *tstate) PyEval_RestoreThread(PyThreadState *tstate)
{ {
_PyRuntimeState *runtime = &_PyRuntime;
struct _ceval_runtime_state *ceval = &runtime->ceval;
if (tstate == NULL) { if (tstate == NULL) {
Py_FatalError("PyEval_RestoreThread: NULL tstate"); Py_FatalError("PyEval_RestoreThread: NULL tstate");
} }
assert(tstate->interp != NULL);
_PyRuntimeState *runtime = tstate->interp->runtime;
struct _ceval_runtime_state *ceval = &runtime->ceval;
assert(gil_created(&ceval->gil)); assert(gil_created(&ceval->gil));
int err = errno; int err = errno;
take_gil(ceval, tstate); take_gil(ceval, tstate);
exit_thread_if_finalizing(runtime, tstate); exit_thread_if_finalizing(tstate);
errno = err; errno = err;
_PyThreadState_Swap(&runtime->gilstate, tstate); _PyThreadState_Swap(&runtime->gilstate, tstate);
...@@ -1141,7 +1145,7 @@ main_loop: ...@@ -1141,7 +1145,7 @@ main_loop:
take_gil(ceval, tstate); take_gil(ceval, tstate);
/* Check if we should make a quick exit. */ /* Check if we should make a quick exit. */
exit_thread_if_finalizing(runtime, tstate); exit_thread_if_finalizing(tstate);
if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) { if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
Py_FatalError("ceval: orphan tstate"); Py_FatalError("ceval: orphan tstate");
......
...@@ -541,7 +541,8 @@ PyImport_Cleanup(void) ...@@ -541,7 +541,8 @@ PyImport_Cleanup(void)
_PyGC_CollectNoFail(); _PyGC_CollectNoFail();
/* Dump GC stats before it's too late, since it uses the warnings /* Dump GC stats before it's too late, since it uses the warnings
machinery. */ machinery. */
_PyGC_DumpShutdownStats(&_PyRuntime); _PyRuntimeState *runtime = interp->runtime;
_PyGC_DumpShutdownStats(runtime);
/* Now, if there are any modules left alive, clear their globals to /* Now, if there are any modules left alive, clear their globals to
minimize potential leaks. All C extension modules actually end minimize potential leaks. All C extension modules actually end
......
...@@ -545,7 +545,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime, ...@@ -545,7 +545,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
_PyEval_FiniThreads(&runtime->ceval); _PyEval_FiniThreads(&runtime->ceval);
/* Auto-thread-state API */ /* Auto-thread-state API */
_PyGILState_Init(runtime, interp, tstate); _PyGILState_Init(tstate);
/* Create the GIL */ /* Create the GIL */
PyEval_InitThreads(); PyEval_InitThreads();
...@@ -683,7 +683,7 @@ pyinit_config(_PyRuntimeState *runtime, ...@@ -683,7 +683,7 @@ pyinit_config(_PyRuntimeState *runtime,
} }
PyObject *sysmod; PyObject *sysmod;
status = _PySys_Create(runtime, interp, &sysmod); status = _PySys_Create(interp, &sysmod);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
...@@ -892,8 +892,9 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp) ...@@ -892,8 +892,9 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
* non-zero return code. * non-zero return code.
*/ */
static PyStatus static PyStatus
pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) pyinit_main(PyInterpreterState *interp)
{ {
_PyRuntimeState *runtime = interp->runtime;
if (!runtime->core_initialized) { if (!runtime->core_initialized) {
return _PyStatus_ERR("runtime core not initialized"); return _PyStatus_ERR("runtime core not initialized");
} }
...@@ -919,7 +920,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp) ...@@ -919,7 +920,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
return _PyStatus_ERR("can't initialize time"); return _PyStatus_ERR("can't initialize time");
} }
if (_PySys_InitMain(runtime, interp) < 0) { if (_PySys_InitMain(interp) < 0) {
return _PyStatus_ERR("can't finish initializing sys"); return _PyStatus_ERR("can't finish initializing sys");
} }
...@@ -999,7 +1000,7 @@ _Py_InitializeMain(void) ...@@ -999,7 +1000,7 @@ _Py_InitializeMain(void)
_PyRuntimeState *runtime = &_PyRuntime; _PyRuntimeState *runtime = &_PyRuntime;
PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp; PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
return pyinit_main(runtime, interp); return pyinit_main(interp);
} }
...@@ -1026,7 +1027,7 @@ Py_InitializeFromConfig(const PyConfig *config) ...@@ -1026,7 +1027,7 @@ Py_InitializeFromConfig(const PyConfig *config)
config = &interp->config; config = &interp->config;
if (config->_init_main) { if (config->_init_main) {
status = pyinit_main(runtime, interp); status = pyinit_main(interp);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
...@@ -1453,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p) ...@@ -1453,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p)
} }
Py_INCREF(interp->sysdict); Py_INCREF(interp->sysdict);
PyDict_SetItemString(interp->sysdict, "modules", modules); PyDict_SetItemString(interp->sysdict, "modules", modules);
if (_PySys_InitMain(runtime, interp) < 0) { if (_PySys_InitMain(interp) < 0) {
return _PyStatus_ERR("can't finish initializing sys"); return _PyStatus_ERR("can't finish initializing sys");
} }
} }
......
...@@ -39,7 +39,6 @@ extern "C" { ...@@ -39,7 +39,6 @@ extern "C" {
/* Forward declarations */ /* Forward declarations */
static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate); static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate);
static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate);
static PyStatus static PyStatus
...@@ -192,6 +191,8 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime) ...@@ -192,6 +191,8 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
PyInterpreterState * PyInterpreterState *
PyInterpreterState_New(void) PyInterpreterState_New(void)
{ {
_PyRuntimeState *runtime = &_PyRuntime;
if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) { if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) {
return NULL; return NULL;
} }
...@@ -202,6 +203,9 @@ PyInterpreterState_New(void) ...@@ -202,6 +203,9 @@ PyInterpreterState_New(void)
} }
memset(interp, 0, sizeof(*interp)); memset(interp, 0, sizeof(*interp));
interp->runtime = runtime;
interp->id_refcount = -1; interp->id_refcount = -1;
interp->check_interval = 100; interp->check_interval = 100;
...@@ -223,7 +227,6 @@ PyInterpreterState_New(void) ...@@ -223,7 +227,6 @@ PyInterpreterState_New(void)
#endif #endif
#endif #endif
_PyRuntimeState *runtime = &_PyRuntime;
struct pyinterpreters *interpreters = &runtime->interpreters; struct pyinterpreters *interpreters = &runtime->interpreters;
HEAD_LOCK(runtime); HEAD_LOCK(runtime);
...@@ -257,9 +260,11 @@ PyInterpreterState_New(void) ...@@ -257,9 +260,11 @@ PyInterpreterState_New(void)
} }
static void void
_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) PyInterpreterState_Clear(PyInterpreterState *interp)
{ {
_PyRuntimeState *runtime = interp->runtime;
if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) { if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) {
PyErr_Clear(); PyErr_Clear();
} }
...@@ -297,31 +302,25 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp) ...@@ -297,31 +302,25 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp)
// objects have been cleaned up at the point. // objects have been cleaned up at the point.
} }
void
PyInterpreterState_Clear(PyInterpreterState *interp)
{
_PyInterpreterState_Clear(&_PyRuntime, interp);
}
static void static void
zapthreads(_PyRuntimeState *runtime, PyInterpreterState *interp) zapthreads(PyInterpreterState *interp)
{ {
PyThreadState *p; PyThreadState *ts;
/* No need to lock the mutex here because this should only happen /* No need to lock the mutex here because this should only happen
when the threads are all really dead (XXX famous last words). */ when the threads are all really dead (XXX famous last words). */
while ((p = interp->tstate_head) != NULL) { while ((ts = interp->tstate_head) != NULL) {
_PyThreadState_Delete(runtime, p); PyThreadState_Delete(ts);
} }
} }
static void void
_PyInterpreterState_Delete(_PyRuntimeState *runtime, PyInterpreterState_Delete(PyInterpreterState *interp)
PyInterpreterState *interp)
{ {
_PyRuntimeState *runtime = interp->runtime;
struct pyinterpreters *interpreters = &runtime->interpreters; struct pyinterpreters *interpreters = &runtime->interpreters;
zapthreads(runtime, interp); zapthreads(interp);
HEAD_LOCK(runtime); HEAD_LOCK(runtime);
PyInterpreterState **p; PyInterpreterState **p;
for (p = &interpreters->head; ; p = &(*p)->next) { for (p = &interpreters->head; ; p = &(*p)->next) {
...@@ -350,13 +349,6 @@ _PyInterpreterState_Delete(_PyRuntimeState *runtime, ...@@ -350,13 +349,6 @@ _PyInterpreterState_Delete(_PyRuntimeState *runtime,
} }
void
PyInterpreterState_Delete(PyInterpreterState *interp)
{
_PyInterpreterState_Delete(&_PyRuntime, interp);
}
/* /*
* Delete all interpreter states except the main interpreter. If there * Delete all interpreter states except the main interpreter. If there
* is a current interpreter state, it *must* be the main interpreter. * is a current interpreter state, it *must* be the main interpreter.
...@@ -383,8 +375,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime) ...@@ -383,8 +375,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
continue; continue;
} }
_PyInterpreterState_Clear(runtime, interp); // XXX must activate? PyInterpreterState_Clear(interp); // XXX must activate?
zapthreads(runtime, interp); zapthreads(interp);
if (interp->id_mutex != NULL) { if (interp->id_mutex != NULL) {
PyThread_free_lock(interp->id_mutex); PyThread_free_lock(interp->id_mutex);
} }
...@@ -497,7 +489,8 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp) ...@@ -497,7 +489,8 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp)
if (interp->id_mutex == NULL) { if (interp->id_mutex == NULL) {
return; return;
} }
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; _PyRuntimeState *runtime = interp->runtime;
struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK); PyThread_acquire_lock(interp->id_mutex, WAIT_LOCK);
assert(interp->id_refcount != 0); assert(interp->id_refcount != 0);
interp->id_refcount -= 1; interp->id_refcount -= 1;
...@@ -559,7 +552,7 @@ threadstate_getframe(PyThreadState *self) ...@@ -559,7 +552,7 @@ threadstate_getframe(PyThreadState *self)
static PyThreadState * static PyThreadState *
new_threadstate(PyInterpreterState *interp, int init) new_threadstate(PyInterpreterState *interp, int init)
{ {
_PyRuntimeState *runtime = &_PyRuntime; _PyRuntimeState *runtime = interp->runtime;
PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState)); PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState));
if (tstate == NULL) { if (tstate == NULL) {
return NULL; return NULL;
...@@ -615,7 +608,7 @@ new_threadstate(PyInterpreterState *interp, int init) ...@@ -615,7 +608,7 @@ new_threadstate(PyInterpreterState *interp, int init)
tstate->id = ++interp->tstate_next_unique_id; tstate->id = ++interp->tstate_next_unique_id;
if (init) { if (init) {
_PyThreadState_Init(runtime, tstate); _PyThreadState_Init(tstate);
} }
HEAD_LOCK(runtime); HEAD_LOCK(runtime);
...@@ -642,8 +635,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp) ...@@ -642,8 +635,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp)
} }
void void
_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate) _PyThreadState_Init(PyThreadState *tstate)
{ {
_PyRuntimeState *runtime = tstate->interp->runtime;
_PyGILState_NoteThreadState(&runtime->gilstate, tstate); _PyGILState_NoteThreadState(&runtime->gilstate, tstate);
} }
...@@ -808,7 +802,7 @@ PyThreadState_Clear(PyThreadState *tstate) ...@@ -808,7 +802,7 @@ PyThreadState_Clear(PyThreadState *tstate)
/* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */ /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
static void static void
tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) tstate_delete_common(PyThreadState *tstate)
{ {
if (tstate == NULL) { if (tstate == NULL) {
Py_FatalError("PyThreadState_Delete: NULL tstate"); Py_FatalError("PyThreadState_Delete: NULL tstate");
...@@ -817,6 +811,7 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) ...@@ -817,6 +811,7 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate)
if (interp == NULL) { if (interp == NULL) {
Py_FatalError("PyThreadState_Delete: NULL interp"); Py_FatalError("PyThreadState_Delete: NULL interp");
} }
_PyRuntimeState *runtime = interp->runtime;
HEAD_LOCK(runtime); HEAD_LOCK(runtime);
if (tstate->prev) if (tstate->prev)
tstate->prev->next = tstate->next; tstate->prev->next = tstate->next;
...@@ -832,9 +827,10 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate) ...@@ -832,9 +827,10 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate)
} }
static void void
_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) PyThreadState_Delete(PyThreadState *tstate)
{ {
_PyRuntimeState *runtime = tstate->interp->runtime;
struct _gilstate_runtime_state *gilstate = &runtime->gilstate; struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) { if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
Py_FatalError("PyThreadState_Delete: tstate is still current"); Py_FatalError("PyThreadState_Delete: tstate is still current");
...@@ -844,14 +840,7 @@ _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate) ...@@ -844,14 +840,7 @@ _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate)
{ {
PyThread_tss_set(&gilstate->autoTSSkey, NULL); PyThread_tss_set(&gilstate->autoTSSkey, NULL);
} }
tstate_delete_common(runtime, tstate); tstate_delete_common(tstate);
}
void
PyThreadState_Delete(PyThreadState *tstate)
{
_PyThreadState_Delete(&_PyRuntime, tstate);
} }
...@@ -863,7 +852,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime) ...@@ -863,7 +852,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime)
if (tstate == NULL) if (tstate == NULL)
Py_FatalError( Py_FatalError(
"PyThreadState_DeleteCurrent: no current tstate"); "PyThreadState_DeleteCurrent: no current tstate");
tstate_delete_common(runtime, tstate); tstate_delete_common(tstate);
if (gilstate->autoInterpreterState && if (gilstate->autoInterpreterState &&
PyThread_tss_get(&gilstate->autoTSSkey) == tstate) PyThread_tss_get(&gilstate->autoTSSkey) == tstate)
{ {
...@@ -888,9 +877,10 @@ PyThreadState_DeleteCurrent() ...@@ -888,9 +877,10 @@ PyThreadState_DeleteCurrent()
* be kept in those other interpreteres. * be kept in those other interpreteres.
*/ */
void void
_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate) _PyThreadState_DeleteExcept(PyThreadState *tstate)
{ {
PyInterpreterState *interp = tstate->interp; PyInterpreterState *interp = tstate->interp;
_PyRuntimeState *runtime = interp->runtime;
PyThreadState *p, *next, *garbage; PyThreadState *p, *next, *garbage;
HEAD_LOCK(runtime); HEAD_LOCK(runtime);
/* Remove all thread states, except tstate, from the linked list of /* Remove all thread states, except tstate, from the linked list of
...@@ -1129,8 +1119,9 @@ _PyThread_CurrentFrames(void) ...@@ -1129,8 +1119,9 @@ _PyThread_CurrentFrames(void)
static int static int
PyThreadState_IsCurrent(PyThreadState *tstate) PyThreadState_IsCurrent(PyThreadState *tstate)
{ {
_PyRuntimeState *runtime = tstate->interp->runtime;
/* Must be the tstate for this thread */ /* Must be the tstate for this thread */
struct _gilstate_runtime_state *gilstate = &_PyRuntime.gilstate; struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
assert(_PyGILState_GetThisThreadState(gilstate) == tstate); assert(_PyGILState_GetThisThreadState(gilstate) == tstate);
return tstate == _PyRuntimeGILState_GetThreadState(gilstate); return tstate == _PyRuntimeGILState_GetThreadState(gilstate);
} }
...@@ -1139,12 +1130,14 @@ PyThreadState_IsCurrent(PyThreadState *tstate) ...@@ -1139,12 +1130,14 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
Py_Initialize/Py_FinalizeEx Py_Initialize/Py_FinalizeEx
*/ */
void void
_PyGILState_Init(_PyRuntimeState *runtime, _PyGILState_Init(PyThreadState *tstate)
PyInterpreterState *interp, PyThreadState *tstate)
{ {
/* must init with valid states */ /* must init with valid states */
assert(interp != NULL);
assert(tstate != NULL); assert(tstate != NULL);
PyInterpreterState *interp = tstate->interp;
assert(interp != NULL);
_PyRuntimeState *runtime = interp->runtime;
assert(runtime != NULL);
struct _gilstate_runtime_state *gilstate = &runtime->gilstate; struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
......
...@@ -120,8 +120,9 @@ should_audit(void) ...@@ -120,8 +120,9 @@ should_audit(void)
if (!ts) { if (!ts) {
return 0; return 0;
} }
PyInterpreterState *is = ts ? ts->interp : NULL; PyInterpreterState *is = ts->interp;
return _PyRuntime.audit_hook_head _PyRuntimeState *runtime = is->runtime;
return runtime->audit_hook_head
|| (is && is->audit_hooks) || (is && is->audit_hooks)
|| PyDTrace_AUDIT_ENABLED(); || PyDTrace_AUDIT_ENABLED();
} }
...@@ -280,8 +281,8 @@ void _PySys_ClearAuditHooks(void) { ...@@ -280,8 +281,8 @@ void _PySys_ClearAuditHooks(void) {
PySys_Audit("cpython._PySys_ClearAuditHooks", NULL); PySys_Audit("cpython._PySys_ClearAuditHooks", NULL);
PyErr_Clear(); PyErr_Clear();
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n; _Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
_PyRuntime.audit_hook_head = NULL; runtime->audit_hook_head = NULL;
while (e) { while (e) {
n = e->next; n = e->next;
PyMem_RawFree(e); PyMem_RawFree(e);
...@@ -292,6 +293,7 @@ void _PySys_ClearAuditHooks(void) { ...@@ -292,6 +293,7 @@ void _PySys_ClearAuditHooks(void) {
int int
PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
{ {
_PyRuntimeState *runtime = &_PyRuntime;
/* Invoke existing audit hooks to allow them an opportunity to abort. */ /* Invoke existing audit hooks to allow them an opportunity to abort. */
/* Cannot invoke hooks until we are initialized */ /* Cannot invoke hooks until we are initialized */
if (Py_IsInitialized()) { if (Py_IsInitialized()) {
...@@ -305,10 +307,10 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData) ...@@ -305,10 +307,10 @@ PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
} }
} }
_Py_AuditHookEntry *e = _PyRuntime.audit_hook_head; _Py_AuditHookEntry *e = runtime->audit_hook_head;
if (!e) { if (!e) {
e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry)); e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
_PyRuntime.audit_hook_head = e; runtime->audit_hook_head = e;
} else { } else {
while (e->next) while (e->next)
e = e->next; e = e->next;
...@@ -2413,8 +2415,9 @@ static PyStructSequence_Desc flags_desc = { ...@@ -2413,8 +2415,9 @@ static PyStructSequence_Desc flags_desc = {
}; };
static PyObject* static PyObject*
make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp) make_flags(PyInterpreterState *interp)
{ {
_PyRuntimeState *runtime = interp->runtime;
int pos = 0; int pos = 0;
PyObject *seq; PyObject *seq;
const PyPreConfig *preconfig = &runtime->preconfig; const PyPreConfig *preconfig = &runtime->preconfig;
...@@ -2633,8 +2636,7 @@ static struct PyModuleDef sysmodule = { ...@@ -2633,8 +2636,7 @@ static struct PyModuleDef sysmodule = {
} while (0) } while (0)
static PyStatus static PyStatus
_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, _PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict)
PyObject *sysdict)
{ {
PyObject *version_info; PyObject *version_info;
int res; int res;
...@@ -2728,7 +2730,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp, ...@@ -2728,7 +2730,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
} }
} }
/* Set flags to their default values (updated by _PySys_InitMain()) */ /* Set flags to their default values (updated by _PySys_InitMain()) */
SET_SYS_FROM_STRING("flags", make_flags(runtime, interp)); SET_SYS_FROM_STRING("flags", make_flags(interp));
#if defined(MS_WINDOWS) #if defined(MS_WINDOWS)
/* getwindowsversion */ /* getwindowsversion */
...@@ -2849,7 +2851,7 @@ sys_create_xoptions_dict(const PyConfig *config) ...@@ -2849,7 +2851,7 @@ sys_create_xoptions_dict(const PyConfig *config)
int int
_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) _PySys_InitMain(PyInterpreterState *interp)
{ {
PyObject *sysdict = interp->sysdict; PyObject *sysdict = interp->sysdict;
const PyConfig *config = &interp->config; const PyConfig *config = &interp->config;
...@@ -2903,7 +2905,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp) ...@@ -2903,7 +2905,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
#undef SET_SYS_FROM_WSTR #undef SET_SYS_FROM_WSTR
/* Set flags to their final values */ /* Set flags to their final values */
SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(runtime, interp)); SET_SYS_FROM_STRING_INT_RESULT("flags", make_flags(interp));
/* prevent user from creating new instances */ /* prevent user from creating new instances */
FlagsType.tp_init = NULL; FlagsType.tp_init = NULL;
FlagsType.tp_new = NULL; FlagsType.tp_new = NULL;
...@@ -2970,8 +2972,7 @@ error: ...@@ -2970,8 +2972,7 @@ error:
/* Create sys module without all attributes: _PySys_InitMain() should be called /* Create sys module without all attributes: _PySys_InitMain() should be called
later to add remaining attributes. */ later to add remaining attributes. */
PyStatus PyStatus
_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, _PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p)
PyObject **sysmod_p)
{ {
PyObject *modules = PyDict_New(); PyObject *modules = PyDict_New();
if (modules == NULL) { if (modules == NULL) {
...@@ -3000,7 +3001,7 @@ _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp, ...@@ -3000,7 +3001,7 @@ _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
return status; return status;
} }
status = _PySys_InitCore(runtime, interp, sysdict); status = _PySys_InitCore(interp, sysdict);
if (_PyStatus_EXCEPTION(status)) { if (_PyStatus_EXCEPTION(status)) {
return status; return status;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment