mirror of
https://github.com/python/cpython.git
synced 2025-11-01 18:51:43 +00:00
gh-103323: Get the "Current" Thread State from a Thread-Local Variable (gh-103324)
We replace _PyRuntime.tstate_current with a thread-local variable. As part of this change, we add a _Py_thread_local macro in pyport.h (only for the core runtime) to smooth out the compiler differences. The main motivation here is in support of a per-interpreter GIL, but this change also provides some performance improvement opportunities. Note that we do not provide a fallback to the thread-local, either falling back to the old tstate_current or to thread-specific storage (PyThread_tss_*()). If that proves problematic then we can circle back. I consider it unlikely, but will run the buildbots to double-check. Also note that this does not change any of the code related to the GILState API, where it uses a thread state stored in thread-specific storage. I suspect we can combine that with _Py_tss_tstate (from here). However, that can be addressed separately and is not urgent (nor critical). (While this change was mostly done independently, I did take some inspiration from earlier (~2020) work by @markshannon (main...markshannon:threadstate_in_tls) and @vstinner (#23976).)
This commit is contained in:
parent
7ef614c1ad
commit
f8abfa3314
5 changed files with 73 additions and 18 deletions
|
|
@ -64,17 +64,14 @@ _Py_ThreadCanHandlePendingCalls(void)
|
|||
/* Variable and macro for in-line access to current thread
|
||||
and interpreter state */
|
||||
|
||||
static inline PyThreadState*
|
||||
_PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
|
||||
{
|
||||
return (PyThreadState*)_Py_atomic_load_relaxed(&runtime->tstate_current);
|
||||
}
|
||||
#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)
|
||||
extern _Py_thread_local PyThreadState *_Py_tss_tstate;
|
||||
#endif
|
||||
PyAPI_DATA(PyThreadState *) _PyThreadState_GetCurrent(void);
|
||||
|
||||
/* Get the current Python thread state.
|
||||
|
||||
Efficient macro reading directly the 'tstate_current' atomic
|
||||
variable. The macro is unsafe: it does not check for error and it can
|
||||
return NULL.
|
||||
This function is unsafe: it does not check for error and it can return NULL.
|
||||
|
||||
The caller must hold the GIL.
|
||||
|
||||
|
|
@ -82,9 +79,20 @@ _PyRuntimeState_GetThreadState(_PyRuntimeState *runtime)
|
|||
static inline PyThreadState*
|
||||
_PyThreadState_GET(void)
|
||||
{
|
||||
return _PyRuntimeState_GetThreadState(&_PyRuntime);
|
||||
#if defined(HAVE_THREAD_LOCAL) && !defined(Py_BUILD_CORE_MODULE)
|
||||
return _Py_tss_tstate;
|
||||
#else
|
||||
return _PyThreadState_GetCurrent();
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline PyThreadState*
|
||||
_PyRuntimeState_GetThreadState(_PyRuntimeState *Py_UNUSED(runtime))
|
||||
{
|
||||
return _PyThreadState_GET();
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
_Py_EnsureFuncTstateNotNULL(const char *func, PyThreadState *tstate)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue