Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 4 additions & 3 deletions Include/internal/pycore_freelist.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
9 changes: 7 additions & 2 deletions Include/internal/pycore_pystate.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be

#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)

instead?

When testing the current main against mypyc, I'm seeing a new error message

In file included from /.../mypy/mypyc/lib-rt/misc_ops.c:1137:
In file included from /.../cpython/Include/internal/pycore_object.h:12:
In file included from /.../cpython/Include/internal/pycore_gc.h:12:
/.../cpython/Include/internal/pycore_pystate.h:213:12: error: use of undeclared identifier '_Py_tss_interp'
    return _Py_tss_interp;
           ^
1 error generated.

Mypyc does use some of the internal headers. In particular

#define Py_BUILD_CORE
...
#include "internal/pycore_object.h"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it is because mypyc doesn't define HAVE_THREAD_LOCAL which is defined when python is built, does #140623 fixes it for you?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just remove the check for HAVE_THREAD_LOCAL on line 92.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess it is because mypyc doesn't define HAVE_THREAD_LOCAL which is defined when python is built, does #140623 fixes it for you?

Yes, that works.

I think we should just remove the check for HAVE_THREAD_LOCAL on line 92.

Guess, this would work too.

return _Py_tss_interp;
#else
return _PyThreadState_GET()->interp;
#endif
}


Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Speed up accessing interpreter state by caching it in a thread local variable. Patch by Kumar Aditya.
12 changes: 9 additions & 3 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand All @@ -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) \
Expand Down Expand Up @@ -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");
}
Expand Down
1 change: 1 addition & 0 deletions Tools/c-analyzer/cpython/ignored.tsv
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading