Skip to content

Commit ef4665f

Browse files
pythongh-140544: store pointer to interpreter state as a thread local for fast access (python#140573)
1 parent 4ad5995 commit ef4665f

File tree

5 files changed

+22
-8
lines changed

5 files changed

+22
-8
lines changed

Include/internal/pycore_freelist.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,16 @@ extern "C" {
1717
static inline struct _Py_freelists *
1818
_Py_freelists_GET(void)
1919
{
20-
PyThreadState *tstate = _PyThreadState_GET();
2120
#ifdef Py_DEBUG
22-
_Py_EnsureTstateNotNULL(tstate);
21+
_Py_AssertHoldsTstate();
2322
#endif
2423

2524
#ifdef Py_GIL_DISABLED
25+
PyThreadState *tstate = _PyThreadState_GET();
2626
return &((_PyThreadStateImpl*)tstate)->freelists;
2727
#else
28-
return &tstate->interp->object_state.freelists;
28+
PyInterpreterState *interp = _PyInterpreterState_GET();
29+
return &interp->object_state.freelists;
2930
#endif
3031
}
3132

Include/internal/pycore_pystate.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ _Py_ThreadCanHandleSignals(PyInterpreterState *interp)
9191

9292
#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)
9393
extern _Py_thread_local PyThreadState *_Py_tss_tstate;
94+
extern _Py_thread_local PyInterpreterState *_Py_tss_interp;
9495
#endif
9596

9697
#ifndef NDEBUG
@@ -204,11 +205,15 @@ _Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
204205
See also PyInterpreterState_Get()
205206
and _PyGILState_GetInterpreterStateUnsafe(). */
206207
static inline PyInterpreterState* _PyInterpreterState_GET(void) {
207-
PyThreadState *tstate = _PyThreadState_GET();
208208
#ifdef Py_DEBUG
209+
PyThreadState *tstate = _PyThreadState_GET();
209210
_Py_EnsureTstateNotNULL(tstate);
210211
#endif
211-
return tstate->interp;
212+
#if !defined(Py_BUILD_CORE_MODULE)
213+
return _Py_tss_interp;
214+
#else
215+
return _PyThreadState_GET()->interp;
216+
#endif
212217
}
213218

214219

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Speed up accessing interpreter state by caching it in a thread local variable. Patch by Kumar Aditya.

Python/pystate.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ _Py_thread_local PyThreadState *_Py_tss_tstate = NULL;
7878
also known as a "gilstate." */
7979
_Py_thread_local PyThreadState *_Py_tss_gilstate = NULL;
8080

81+
/* The interpreter of the attached thread state,
82+
and is same as tstate->interp. */
83+
_Py_thread_local PyInterpreterState *_Py_tss_interp = NULL;
84+
8185
static inline PyThreadState *
8286
current_fast_get(void)
8387
{
@@ -89,12 +93,15 @@ current_fast_set(_PyRuntimeState *Py_UNUSED(runtime), PyThreadState *tstate)
8993
{
9094
assert(tstate != NULL);
9195
_Py_tss_tstate = tstate;
96+
assert(tstate->interp != NULL);
97+
_Py_tss_interp = tstate->interp;
9298
}
9399

94100
static inline void
95101
current_fast_clear(_PyRuntimeState *Py_UNUSED(runtime))
96102
{
97103
_Py_tss_tstate = NULL;
104+
_Py_tss_interp = NULL;
98105
}
99106

100107
#define tstate_verify_not_active(tstate) \
@@ -1281,9 +1288,8 @@ _PyInterpreterState_RequireIDRef(PyInterpreterState *interp, int required)
12811288
PyInterpreterState*
12821289
PyInterpreterState_Get(void)
12831290
{
1284-
PyThreadState *tstate = current_fast_get();
1285-
_Py_EnsureTstateNotNULL(tstate);
1286-
PyInterpreterState *interp = tstate->interp;
1291+
_Py_AssertHoldsTstate();
1292+
PyInterpreterState *interp = _Py_tss_interp;
12871293
if (interp == NULL) {
12881294
Py_FatalError("no current interpreter");
12891295
}

Tools/c-analyzer/cpython/ignored.tsv

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,7 @@ Python/pyfpe.c - PyFPE_counter -
194194
Python/import.c - pkgcontext -
195195
Python/pystate.c - _Py_tss_tstate -
196196
Python/pystate.c - _Py_tss_gilstate -
197+
Python/pystate.c - _Py_tss_interp -
197198

198199
##-----------------------
199200
## should be const

0 commit comments

Comments
 (0)