Skip to main content

Include/internal/pycore_lock.h

Source:

cpython 3.14 @ ab2d84fe1023/Include/internal/pycore_lock.h

pycore_lock.h defines the internal locking primitives introduced for free-threaded Python (PEP 703). These are lighter-weight than PyThread_type_lock and use futex-based waiting where available.

Map

LinesSymbolRole
1-60_PyMutexSlim mutex: one byte, futex on Linux, os_unfair_lock on macOS
61-120_PyRawMutexLike _PyMutex but no-GIL-drop on contention
121-180_PyEventOne-shot event (signal/wait)
181-220_PyOnceFlagRun initialization code exactly once (like sync.Once in Go)
221-250Accessor macros_PyMutex_Lock, _PyMutex_Unlock, _PyEvent_Notify

Reading

_PyMutex

// CPython: Include/internal/pycore_lock.h:28 _PyMutex
typedef struct {
uint8_t v; /* 0=unlocked, 1=locked, 2=locked+waiters */
} _PyMutex;

/* Lock, releasing the GIL if blocked (for free-threaded build) */
static inline void _PyMutex_Lock(_PyMutex *m);
static inline void _PyMutex_Unlock(_PyMutex *m);
static inline int _PyMutex_TryLock(_PyMutex *m);

The single byte encodes three states. When a thread finds v == 1, it sets v = 2 (signaling waiters are present) and calls futex_wait. The unlock path only calls futex_wake when v == 2.

_PyRawMutex

// CPython: Include/internal/pycore_lock.h:75 _PyRawMutex
/* Like _PyMutex but does not drop the GIL on contention.
Used where the GIL is not held or dropping it would be unsafe. */
typedef struct {
uintptr_t v;
} _PyRawMutex;

_PyRawMutex is used for internal structures that must be protected even in the no-GIL build without allowing re-entry.

_PyEvent

// CPython: Include/internal/pycore_lock.h:130 _PyEvent
typedef struct {
uint8_t v; /* 0=not set, 1=set */
} _PyEvent;

/* Signal the event (idempotent) */
static inline void _PyEvent_Notify(_PyEvent *evt);
/* Block until the event is set; releases GIL while waiting */
void _PyEvent_Wait(_PyEvent *evt);
/* Non-blocking check */
static inline int _PyEvent_IsSet(_PyEvent *evt);

_PyEvent is a one-shot: once set it stays set. Used to signal thread startup completion.

_PyOnceFlag

// CPython: Include/internal/pycore_lock.h:195 _PyOnceFlag
typedef struct {
uint8_t v;
} _PyOnceFlag;

/* Run func(arg) exactly once across all threads.
Returns 0 on success, -1 if func raised an exception. */
int _PyOnceFlag_CallOnce(_PyOnceFlag *flag, _Py_once_fn_t *func, void *arg);

Analogous to pthread_once and Go's sync.Once. Used for lazy initialization of per-interpreter caches.

gopy notes

gopy does not have a GIL, so _PyMutex maps to sync.Mutex in Go. _PyEvent maps to a chan struct{} (closed on notify, blocking on wait). _PyOnceFlag maps directly to sync.Once. These types appear in vm/lock.go.