]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-140544: store pointer to interpreter state as a thread local for fast access ...
authorKumar Aditya <kumaraditya@python.org>
Sat, 25 Oct 2025 14:26:07 +0000 (19:56 +0530)
committerGitHub <noreply@github.com>
Sat, 25 Oct 2025 14:26:07 +0000 (19:56 +0530)
Include/internal/pycore_freelist.h
Include/internal/pycore_pystate.h
Misc/NEWS.d/next/Core_and_Builtins/2025-10-25-07-25-52.gh-issue-140544.lwjtQe.rst [new file with mode: 0644]
Python/pystate.c
Tools/c-analyzer/cpython/ignored.tsv

index f3c9a669ad3512abfa3cfad4dcba6e1dc8266a58..3a41ec4b54bb069d5936310e910340430718e53b 100644 (file)
@@ -17,15 +17,16 @@ extern "C" {
 static inline struct _Py_freelists *
 _Py_freelists_GET(void)
 {
-    PyThreadState *tstate = _PyThreadState_GET();
 #ifdef Py_DEBUG
-    _Py_EnsureTstateNotNULL(tstate);
+    _Py_AssertHoldsTstate();
 #endif
 
 #ifdef Py_GIL_DISABLED
+    PyThreadState *tstate = _PyThreadState_GET();
     return &((_PyThreadStateImpl*)tstate)->freelists;
 #else
-    return &tstate->interp->object_state.freelists;
+    PyInterpreterState *interp = _PyInterpreterState_GET();
+    return &interp->object_state.freelists;
 #endif
 }
 
index ea3dfbd2eef9c1594e851b41864d0effef9db4d6..503cddc73fc4642c8de9df1826bf9fa4d250c1f0 100644 (file)
@@ -91,6 +91,7 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
 
 #if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)
 extern _Py_thread_local PyThreadState *_Py_tss_tstate;
+extern _Py_thread_local PyInterpreterState *_Py_tss_interp;
 #endif
 
 #ifndef NDEBUG
@@ -204,11 +205,15 @@ _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
    See also PyInterpreterState_Get()
    and _PyGILState_GetInterpreterStateUnsafe(). */
 static inline PyInterpreterState* _PyInterpreterState_GET(void) {
-    PyThreadState *tstate = _PyThreadState_GET();
 #ifdef Py_DEBUG
+    PyThreadState *tstate = _PyThreadState_GET();
     _Py_EnsureTstateNotNULL(tstate);
 #endif
-    return tstate->interp;
+#if !defined(Py_BUILD_CORE_MODULE)
+    return _Py_tss_interp;
+#else
+    return _PyThreadState_GET()->interp;
+#endif
 }
 
 
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-25-07-25-52.gh-issue-140544.lwjtQe.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-25-07-25-52.gh-issue-140544.lwjtQe.rst
new file mode 100644 (file)
index 0000000..51d2b22
--- /dev/null
@@ -0,0 +1 @@
+Speed up accessing interpreter state by caching it in a thread local variable. Patch by Kumar Aditya.
index 2f76adf5026012592c761c92a49b9e198a9634ff..5d0927c6c081965aaeef74b10c8ff91cda517f1e 100644 (file)
@@ -78,6 +78,10 @@ _Py_thread_local PyThreadState *_Py_tss_tstate = NULL;
    also known as a "gilstate." */
 _Py_thread_local PyThreadState *_Py_tss_gilstate = NULL;
 
+/* The interpreter of the attached thread state,
+   and is same as tstate->interp. */
+_Py_thread_local PyInterpreterState *_Py_tss_interp = NULL;
+
 static inline PyThreadState *
 current_fast_get(void)
 {
@@ -89,12 +93,15 @@ current_fast_set(_PyRuntimeState *Py_UNUSED(runtime), PyThreadState *tstate)
 {
     assert(tstate != NULL);
     _Py_tss_tstate = tstate;
+    assert(tstate->interp != NULL);
+    _Py_tss_interp = tstate->interp;
 }
 
 static inline void
 current_fast_clear(_PyRuntimeState *Py_UNUSED(runtime))
 {
     _Py_tss_tstate = NULL;
+    _Py_tss_interp = NULL;
 }
 
 #define tstate_verify_not_active(tstate) \
@@ -1281,9 +1288,8 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required)
 PyInterpreterState*
 PyInterpreterState_Get(void)
 {
-    PyThreadState *tstate = current_fast_get();
-    _Py_EnsureTstateNotNULL(tstate);
-    PyInterpreterState *interp = tstate->interp;
+    _Py_AssertHoldsTstate();
+    PyInterpreterState *interp = _Py_tss_interp;
     if (interp == NULL) {
         Py_FatalError("no current interpreter");
     }
index c3b13d69f0de8e0e07d36c656913fa4ead210b24..8b73189fb07dc5e23ffa62a3af65d88bb283e60b 100644 (file)
@@ -194,6 +194,7 @@ Python/pyfpe.c      -       PyFPE_counter   -
 Python/import.c        -       pkgcontext      -
 Python/pystate.c       -       _Py_tss_tstate  -
 Python/pystate.c       -       _Py_tss_gilstate        -
+Python/pystate.c       -       _Py_tss_interp  -
 
 ##-----------------------
 ## should be const