
On Thu, Nov 14, 2019, at 07:43, Antoine Pitrou wrote:
On Wed, 13 Nov 2019 14:52:32 +0100 Victor Stinner <vstinner@python.org> wrote:
#define _PyRuntimeState_GetThreadState(runtime) \ ((PyThreadState*)_Py_atomic_load_relaxed(&(runtime)->gilstate.tstate_current)) #define _PyThreadState_GET() _PyRuntimeState_GetThreadState(&_PyRuntime)
_PyThreadState_GET() uses "_Py_atomic_load_relaxed". I'm not used to C99 atomic conventions. The "memory_order_relaxed" documentation says:
"Relaxed operation: there are no synchronization or ordering constraints imposed on other reads or writes, only this operation's atomicity is guaranteed (see Relaxed ordering below)"
Note: I'm not even sure why Python currently uses an atomic operation.
Is it protected by a lock? If not, you need to use an atomic. Since it's theoretically possible to read the current thread state without the GIL held (though not very useful), then an atomic is required.
It sounds like you are saying PyRuntimeState_GetThreadState has two duties, then: "get this thread's thread state" (from the GIL holder - how do other threads get their own thread state), and "get the GIL-holding thread's thread state (from non-GIL holder thread). The former shouldn't need atomic/overhead locking (unless the thread state can be written from other threads), even if the latter does.