[Python-checkins] bpo-36818: Add PyInterpreterState.runtime field. (gh-13129)

Eric Snow webhook-mailer at python.org
Fri May 31 23:16:53 EDT 2019


https://github.com/python/cpython/commit/396e0a8d9dc65453cb9d53500d0a620602656cfe
commit: 396e0a8d9dc65453cb9d53500d0a620602656cfe
branch: master
author: Eric Snow <ericsnowcurrently at gmail.com>
committer: GitHub <noreply at github.com>
date: 2019-05-31T21:16:47-06:00
summary:

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

https://bugs.python.org/issue36818

files:
A Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst
M Include/cpython/pystate.h
M Include/internal/pycore_object.h
M Include/internal/pycore_pylifecycle.h
M Include/internal/pycore_pystate.h
M Modules/_threadmodule.c
M Python/ceval.c
M Python/import.c
M Python/pylifecycle.c
M Python/pystate.c
M Python/sysmodule.c

diff --git a/Include/cpython/pystate.h b/Include/cpython/pystate.h
index 94b0809cd4f0..74e7fc96bec9 100644
--- a/Include/cpython/pystate.h
+++ b/Include/cpython/pystate.h
@@ -110,9 +110,9 @@ struct _ts {
      * 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
      * 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
-     * of C code can be allowed to run (in particular it must not be possible to
-     * release the GIL).
+     * _PyRuntimeState.gilstate.tstate_current is already NULL, so only the
+     * simplest of C code can be allowed to run (in particular it must not be
+     * possible to release the GIL).
      * 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
      * weakref is harmless.
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index 81548f819198..1c5beb01f458 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -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
  * ob_traverse method.
  *
- * Internal note: _PyRuntime.gc.generation0->_gc_prev doesn't have any bit flags
- * because it's not object header.  So we don't use _PyGCHead_PREV() and
- * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
+ * Internal note: _PyRuntimeState.gc.generation0->_gc_prev doesn't have
+ * any bit flags because it's not object header.  So we don't use
+ * _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.
  */
diff --git a/Include/internal/pycore_pylifecycle.h b/Include/internal/pycore_pylifecycle.h
index 8a692ea16495..e30341710c20 100644
--- a/Include/internal/pycore_pylifecycle.h
+++ b/Include/internal/pycore_pylifecycle.h
@@ -39,13 +39,10 @@ extern PyStatus _PyFaulthandler_Init(int enable);
 extern int _PyTraceMalloc_Init(int enable);
 extern PyObject * _PyBuiltin_Init(void);
 extern PyStatus _PySys_Create(
-    _PyRuntimeState *runtime,
     PyInterpreterState *interp,
     PyObject **sysmod_p);
 extern PyStatus _PySys_SetPreliminaryStderr(PyObject *sysdict);
-extern int _PySys_InitMain(
-    _PyRuntimeState *runtime,
-    PyInterpreterState *interp);
+extern int _PySys_InitMain(PyInterpreterState *interp);
 extern PyStatus _PyImport_Init(PyInterpreterState *interp);
 extern PyStatus _PyExc_Init(void);
 extern PyStatus _PyErr_Init(void);
@@ -86,10 +83,7 @@ extern void _PyHash_Fini(void);
 extern int _PyTraceMalloc_Fini(void);
 extern void _PyWarnings_Fini(PyInterpreterState *interp);
 
-extern void _PyGILState_Init(
-    _PyRuntimeState *runtime,
-    PyInterpreterState *interp,
-    PyThreadState *tstate);
+extern void _PyGILState_Init(PyThreadState *tstate);
 extern void _PyGILState_Fini(_PyRuntimeState *runtime);
 
 PyAPI_FUNC(void) _PyGC_DumpShutdownStats(_PyRuntimeState *runtime);
diff --git a/Include/internal/pycore_pystate.h b/Include/internal/pycore_pystate.h
index 3ab4009770c9..520a74b8a61f 100644
--- a/Include/internal/pycore_pystate.h
+++ b/Include/internal/pycore_pystate.h
@@ -19,6 +19,9 @@ extern "C" {
 #include "pycore_pymem.h"
 #include "pycore_warnings.h"
 
+// forward
+struct pyruntimestate;
+
 
 /* ceval state */
 
@@ -68,6 +71,7 @@ struct _is {
 
     struct _is *next;
     struct _ts *tstate_head;
+    struct pyruntimestate *runtime;
 
     int64_t id;
     int64_t id_refcount;
@@ -296,12 +300,8 @@ PyAPI_FUNC(void) _PyRuntime_Finalize(void);
 
 /* Other */
 
-PyAPI_FUNC(void) _PyThreadState_Init(
-    _PyRuntimeState *runtime,
-    PyThreadState *tstate);
-PyAPI_FUNC(void) _PyThreadState_DeleteExcept(
-    _PyRuntimeState *runtime,
-    PyThreadState *tstate);
+PyAPI_FUNC(void) _PyThreadState_Init(PyThreadState *tstate);
+PyAPI_FUNC(void) _PyThreadState_DeleteExcept(PyThreadState *tstate);
 
 PyAPI_FUNC(PyThreadState *) _PyThreadState_Swap(
     struct _gilstate_runtime_state *gilstate,
diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst
new file mode 100644
index 000000000000..bb6c56a628e9
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2019-05-06-14-46-48.bpo-36818.5UDDLj.rst	
@@ -0,0 +1 @@
+Add PyInterpreterState.runtime (and use it).
diff --git a/Modules/_threadmodule.c b/Modules/_threadmodule.c
index d5e40ef999e3..099afd86d055 100644
--- a/Modules/_threadmodule.c
+++ b/Modules/_threadmodule.c
@@ -996,7 +996,7 @@ t_bootstrap(void *boot_raw)
 
     tstate = boot->tstate;
     tstate->thread_id = PyThread_get_thread_ident();
-    _PyThreadState_Init(&_PyRuntime, tstate);
+    _PyThreadState_Init(tstate);
     PyEval_AcquireThread(tstate);
     tstate->interp->num_threads++;
     res = PyObject_Call(boot->func, boot->args, boot->keyw);
diff --git a/Python/ceval.c b/Python/ceval.c
index 71e6eb8ebcfd..f9ff4e09f17e 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -217,8 +217,9 @@ _PyEval_FiniThreads(struct _ceval_runtime_state *ceval)
 }
 
 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 */
     if (runtime->finalizing != NULL && !_Py_CURRENTLY_FINALIZING(runtime, tstate)) {
         drop_gil(&runtime->ceval, tstate);
@@ -236,7 +237,7 @@ PyEval_AcquireLock(void)
         Py_FatalError("PyEval_AcquireLock: current thread state is NULL");
     }
     take_gil(ceval, tstate);
-    exit_thread_if_finalizing(runtime, tstate);
+    exit_thread_if_finalizing(tstate);
 }
 
 void
@@ -257,14 +258,15 @@ PyEval_AcquireThread(PyThreadState *tstate)
     if (tstate == NULL) {
         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;
 
     /* Check someone has called PyEval_InitThreads() to create the lock */
     assert(gil_created(&ceval->gil));
     take_gil(ceval, tstate);
-    exit_thread_if_finalizing(runtime, tstate);
+    exit_thread_if_finalizing(tstate);
     if (_PyThreadState_Swap(&runtime->gilstate, tstate) != NULL) {
         Py_FatalError("PyEval_AcquireThread: non-NULL old thread state");
     }
@@ -276,8 +278,9 @@ PyEval_ReleaseThread(PyThreadState *tstate)
     if (tstate == NULL) {
         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);
     if (new_tstate != tstate) {
         Py_FatalError("PyEval_ReleaseThread: wrong thread state");
@@ -308,7 +311,7 @@ _PyEval_ReInitThreads(_PyRuntimeState *runtime)
     }
 
     /* 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
@@ -337,17 +340,18 @@ PyEval_SaveThread(void)
 void
 PyEval_RestoreThread(PyThreadState *tstate)
 {
-    _PyRuntimeState *runtime = &_PyRuntime;
-    struct _ceval_runtime_state *ceval = &runtime->ceval;
-
     if (tstate == NULL) {
         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));
 
     int err = errno;
     take_gil(ceval, tstate);
-    exit_thread_if_finalizing(runtime, tstate);
+    exit_thread_if_finalizing(tstate);
     errno = err;
 
     _PyThreadState_Swap(&runtime->gilstate, tstate);
@@ -1141,7 +1145,7 @@ _PyEval_EvalFrameDefault(PyFrameObject *f, int throwflag)
                 take_gil(ceval, tstate);
 
                 /* 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) {
                     Py_FatalError("ceval: orphan tstate");
diff --git a/Python/import.c b/Python/import.c
index ab7db6bc17f6..68d1f4003abc 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -541,7 +541,8 @@ PyImport_Cleanup(void)
     _PyGC_CollectNoFail();
     /* Dump GC stats before it's too late, since it uses the warnings
        machinery. */
-    _PyGC_DumpShutdownStats(&_PyRuntime);
+    _PyRuntimeState *runtime = interp->runtime;
+    _PyGC_DumpShutdownStats(runtime);
 
     /* Now, if there are any modules left alive, clear their globals to
        minimize potential leaks.  All C extension modules actually end
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index 10a28813faa8..6590ef8e9a27 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -545,7 +545,7 @@ pycore_create_interpreter(_PyRuntimeState *runtime,
     _PyEval_FiniThreads(&runtime->ceval);
 
     /* Auto-thread-state API */
-    _PyGILState_Init(runtime, interp, tstate);
+    _PyGILState_Init(tstate);
 
     /* Create the GIL */
     PyEval_InitThreads();
@@ -683,7 +683,7 @@ pyinit_config(_PyRuntimeState *runtime,
     }
 
     PyObject *sysmod;
-    status = _PySys_Create(runtime, interp, &sysmod);
+    status = _PySys_Create(interp, &sysmod);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }
@@ -892,8 +892,9 @@ _Py_ReconfigureMainInterpreter(PyInterpreterState *interp)
  * non-zero return code.
  */
 static PyStatus
-pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
+pyinit_main(PyInterpreterState *interp)
 {
+    _PyRuntimeState *runtime = interp->runtime;
     if (!runtime->core_initialized) {
         return _PyStatus_ERR("runtime core not initialized");
     }
@@ -919,7 +920,7 @@ pyinit_main(_PyRuntimeState *runtime, PyInterpreterState *interp)
         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");
     }
 
@@ -999,7 +1000,7 @@ _Py_InitializeMain(void)
     _PyRuntimeState *runtime = &_PyRuntime;
     PyInterpreterState *interp = _PyRuntimeState_GetThreadState(runtime)->interp;
 
-    return pyinit_main(runtime, interp);
+    return pyinit_main(interp);
 }
 
 
@@ -1026,7 +1027,7 @@ Py_InitializeFromConfig(const PyConfig *config)
     config = &interp->config;
 
     if (config->_init_main) {
-        status = pyinit_main(runtime, interp);
+        status = pyinit_main(interp);
         if (_PyStatus_EXCEPTION(status)) {
             return status;
         }
@@ -1453,7 +1454,7 @@ new_interpreter(PyThreadState **tstate_p)
         }
         Py_INCREF(interp->sysdict);
         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");
         }
     }
diff --git a/Python/pystate.c b/Python/pystate.c
index 833e0fb30dcb..2b7db0e48deb 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -39,7 +39,6 @@ extern "C" {
 
 /* Forward declarations */
 static PyThreadState *_PyGILState_GetThisThreadState(struct _gilstate_runtime_state *gilstate);
-static void _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate);
 
 
 static PyStatus
@@ -192,6 +191,8 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
 PyInterpreterState *
 PyInterpreterState_New(void)
 {
+    _PyRuntimeState *runtime = &_PyRuntime;
+
     if (PySys_Audit("cpython.PyInterpreterState_New", NULL) < 0) {
         return NULL;
     }
@@ -202,6 +203,9 @@ PyInterpreterState_New(void)
     }
 
     memset(interp, 0, sizeof(*interp));
+
+    interp->runtime = runtime;
+
     interp->id_refcount = -1;
     interp->check_interval = 100;
 
@@ -223,7 +227,6 @@ PyInterpreterState_New(void)
 #endif
 #endif
 
-    _PyRuntimeState *runtime = &_PyRuntime;
     struct pyinterpreters *interpreters = &runtime->interpreters;
 
     HEAD_LOCK(runtime);
@@ -257,9 +260,11 @@ PyInterpreterState_New(void)
 }
 
 
-static void
-_PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp)
+void
+PyInterpreterState_Clear(PyInterpreterState *interp)
 {
+    _PyRuntimeState *runtime = interp->runtime;
+
     if (PySys_Audit("cpython.PyInterpreterState_Clear", NULL) < 0) {
         PyErr_Clear();
     }
@@ -297,31 +302,25 @@ _PyInterpreterState_Clear(_PyRuntimeState *runtime, PyInterpreterState *interp)
     // objects have been cleaned up at the point.
 }
 
-void
-PyInterpreterState_Clear(PyInterpreterState *interp)
-{
-    _PyInterpreterState_Clear(&_PyRuntime, interp);
-}
-
 
 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
        when the threads are all really dead (XXX famous last words). */
-    while ((p = interp->tstate_head) != NULL) {
-        _PyThreadState_Delete(runtime, p);
+    while ((ts = interp->tstate_head) != NULL) {
+        PyThreadState_Delete(ts);
     }
 }
 
 
-static void
-_PyInterpreterState_Delete(_PyRuntimeState *runtime,
-                           PyInterpreterState *interp)
+void
+PyInterpreterState_Delete(PyInterpreterState *interp)
 {
+    _PyRuntimeState *runtime = interp->runtime;
     struct pyinterpreters *interpreters = &runtime->interpreters;
-    zapthreads(runtime, interp);
+    zapthreads(interp);
     HEAD_LOCK(runtime);
     PyInterpreterState **p;
     for (p = &interpreters->head; ; p = &(*p)->next) {
@@ -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
  * is a current interpreter state, it *must* be the main interpreter.
@@ -383,8 +375,8 @@ _PyInterpreterState_DeleteExceptMain(_PyRuntimeState *runtime)
             continue;
         }
 
-        _PyInterpreterState_Clear(runtime, interp);  // XXX must activate?
-        zapthreads(runtime, interp);
+        PyInterpreterState_Clear(interp);  // XXX must activate?
+        zapthreads(interp);
         if (interp->id_mutex != NULL) {
             PyThread_free_lock(interp->id_mutex);
         }
@@ -497,7 +489,8 @@ _PyInterpreterState_IDDecref(PyInterpreterState *interp)
     if (interp->id_mutex == NULL) {
         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);
     assert(interp->id_refcount != 0);
     interp->id_refcount -= 1;
@@ -559,7 +552,7 @@ threadstate_getframe(PyThreadState *self)
 static PyThreadState *
 new_threadstate(PyInterpreterState *interp, int init)
 {
-    _PyRuntimeState *runtime = &_PyRuntime;
+    _PyRuntimeState *runtime = interp->runtime;
     PyThreadState *tstate = (PyThreadState *)PyMem_RawMalloc(sizeof(PyThreadState));
     if (tstate == NULL) {
         return NULL;
@@ -615,7 +608,7 @@ new_threadstate(PyInterpreterState *interp, int init)
     tstate->id = ++interp->tstate_next_unique_id;
 
     if (init) {
-        _PyThreadState_Init(runtime, tstate);
+        _PyThreadState_Init(tstate);
     }
 
     HEAD_LOCK(runtime);
@@ -642,8 +635,9 @@ _PyThreadState_Prealloc(PyInterpreterState *interp)
 }
 
 void
-_PyThreadState_Init(_PyRuntimeState *runtime, PyThreadState *tstate)
+_PyThreadState_Init(PyThreadState *tstate)
 {
+    _PyRuntimeState *runtime = tstate->interp->runtime;
     _PyGILState_NoteThreadState(&runtime->gilstate, tstate);
 }
 
@@ -808,7 +802,7 @@ PyThreadState_Clear(PyThreadState *tstate)
 
 /* Common code for PyThreadState_Delete() and PyThreadState_DeleteCurrent() */
 static void
-tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate)
+tstate_delete_common(PyThreadState *tstate)
 {
     if (tstate == NULL) {
         Py_FatalError("PyThreadState_Delete: NULL tstate");
@@ -817,6 +811,7 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate)
     if (interp == NULL) {
         Py_FatalError("PyThreadState_Delete: NULL interp");
     }
+    _PyRuntimeState *runtime = interp->runtime;
     HEAD_LOCK(runtime);
     if (tstate->prev)
         tstate->prev->next = tstate->next;
@@ -832,9 +827,10 @@ tstate_delete_common(_PyRuntimeState *runtime, PyThreadState *tstate)
 }
 
 
-static void
-_PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate)
+void
+PyThreadState_Delete(PyThreadState *tstate)
 {
+    _PyRuntimeState *runtime = tstate->interp->runtime;
     struct _gilstate_runtime_state *gilstate = &runtime->gilstate;
     if (tstate == _PyRuntimeGILState_GetThreadState(gilstate)) {
         Py_FatalError("PyThreadState_Delete: tstate is still current");
@@ -844,14 +840,7 @@ _PyThreadState_Delete(_PyRuntimeState *runtime, PyThreadState *tstate)
     {
         PyThread_tss_set(&gilstate->autoTSSkey, NULL);
     }
-    tstate_delete_common(runtime, tstate);
-}
-
-
-void
-PyThreadState_Delete(PyThreadState *tstate)
-{
-    _PyThreadState_Delete(&_PyRuntime, tstate);
+    tstate_delete_common(tstate);
 }
 
 
@@ -863,7 +852,7 @@ _PyThreadState_DeleteCurrent(_PyRuntimeState *runtime)
     if (tstate == NULL)
         Py_FatalError(
             "PyThreadState_DeleteCurrent: no current tstate");
-    tstate_delete_common(runtime, tstate);
+    tstate_delete_common(tstate);
     if (gilstate->autoInterpreterState &&
         PyThread_tss_get(&gilstate->autoTSSkey) == tstate)
     {
@@ -888,9 +877,10 @@ PyThreadState_DeleteCurrent()
  * be kept in those other interpreteres.
  */
 void
-_PyThreadState_DeleteExcept(_PyRuntimeState *runtime, PyThreadState *tstate)
+_PyThreadState_DeleteExcept(PyThreadState *tstate)
 {
     PyInterpreterState *interp = tstate->interp;
+    _PyRuntimeState *runtime = interp->runtime;
     PyThreadState *p, *next, *garbage;
     HEAD_LOCK(runtime);
     /* Remove all thread states, except tstate, from the linked list of
@@ -1129,8 +1119,9 @@ _PyThread_CurrentFrames(void)
 static int
 PyThreadState_IsCurrent(PyThreadState *tstate)
 {
+    _PyRuntimeState *runtime = tstate->interp->runtime;
     /* 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);
     return tstate == _PyRuntimeGILState_GetThreadState(gilstate);
 }
@@ -1139,12 +1130,14 @@ PyThreadState_IsCurrent(PyThreadState *tstate)
    Py_Initialize/Py_FinalizeEx
 */
 void
-_PyGILState_Init(_PyRuntimeState *runtime,
-                 PyInterpreterState *interp, PyThreadState *tstate)
+_PyGILState_Init(PyThreadState *tstate)
 {
     /* must init with valid states */
-    assert(interp != 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;
 
diff --git a/Python/sysmodule.c b/Python/sysmodule.c
index 12b1bd7711d5..97bff94d8b41 100644
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -120,8 +120,9 @@ should_audit(void)
     if (!ts) {
         return 0;
     }
-    PyInterpreterState *is = ts ? ts->interp : NULL;
-    return _PyRuntime.audit_hook_head
+    PyInterpreterState *is = ts->interp;
+    _PyRuntimeState *runtime = is->runtime;
+    return runtime->audit_hook_head
         || (is && is->audit_hooks)
         || PyDTrace_AUDIT_ENABLED();
 }
@@ -280,8 +281,8 @@ void _PySys_ClearAuditHooks(void) {
     PySys_Audit("cpython._PySys_ClearAuditHooks", NULL);
     PyErr_Clear();
 
-    _Py_AuditHookEntry *e = _PyRuntime.audit_hook_head, *n;
-    _PyRuntime.audit_hook_head = NULL;
+    _Py_AuditHookEntry *e = runtime->audit_hook_head, *n;
+    runtime->audit_hook_head = NULL;
     while (e) {
         n = e->next;
         PyMem_RawFree(e);
@@ -292,6 +293,7 @@ void _PySys_ClearAuditHooks(void) {
 int
 PySys_AddAuditHook(Py_AuditHookFunction hook, void *userData)
 {
+    _PyRuntimeState *runtime = &_PyRuntime;
     /* Invoke existing audit hooks to allow them an opportunity to abort. */
     /* Cannot invoke hooks until we are initialized */
     if (Py_IsInitialized()) {
@@ -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) {
         e = (_Py_AuditHookEntry*)PyMem_RawMalloc(sizeof(_Py_AuditHookEntry));
-        _PyRuntime.audit_hook_head = e;
+        runtime->audit_hook_head = e;
     } else {
         while (e->next)
             e = e->next;
@@ -2413,8 +2415,9 @@ static PyStructSequence_Desc flags_desc = {
 };
 
 static PyObject*
-make_flags(_PyRuntimeState *runtime, PyInterpreterState *interp)
+make_flags(PyInterpreterState *interp)
 {
+    _PyRuntimeState *runtime = interp->runtime;
     int pos = 0;
     PyObject *seq;
     const PyPreConfig *preconfig = &runtime->preconfig;
@@ -2633,8 +2636,7 @@ static struct PyModuleDef sysmodule = {
     } while (0)
 
 static PyStatus
-_PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
-                PyObject *sysdict)
+_PySys_InitCore(PyInterpreterState *interp, PyObject *sysdict)
 {
     PyObject *version_info;
     int res;
@@ -2728,7 +2730,7 @@ _PySys_InitCore(_PyRuntimeState *runtime, PyInterpreterState *interp,
         }
     }
     /* 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)
     /* getwindowsversion */
@@ -2849,7 +2851,7 @@ sys_create_xoptions_dict(const PyConfig *config)
 
 
 int
-_PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
+_PySys_InitMain(PyInterpreterState *interp)
 {
     PyObject *sysdict = interp->sysdict;
     const PyConfig *config = &interp->config;
@@ -2903,7 +2905,7 @@ _PySys_InitMain(_PyRuntimeState *runtime, PyInterpreterState *interp)
 #undef SET_SYS_FROM_WSTR
 
     /* 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 */
     FlagsType.tp_init = NULL;
     FlagsType.tp_new = NULL;
@@ -2970,8 +2972,7 @@ _PySys_SetPreliminaryStderr(PyObject *sysdict)
 /* Create sys module without all attributes: _PySys_InitMain() should be called
    later to add remaining attributes. */
 PyStatus
-_PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
-              PyObject **sysmod_p)
+_PySys_Create(PyInterpreterState *interp, PyObject **sysmod_p)
 {
     PyObject *modules = PyDict_New();
     if (modules == NULL) {
@@ -3000,7 +3001,7 @@ _PySys_Create(_PyRuntimeState *runtime, PyInterpreterState *interp,
         return status;
     }
 
-    status = _PySys_InitCore(runtime, interp, sysdict);
+    status = _PySys_InitCore(interp, sysdict);
     if (_PyStatus_EXCEPTION(status)) {
         return status;
     }



More information about the Python-checkins mailing list