@@ -13,84 +13,22 @@ extern "C" {
1313# error "this header requires Py_BUILD_CORE define"
1414#endif
1515
16-
17- // A mutex that occupies one byte. The lock can be zero initialized.
18- //
19- // Only the two least significant bits are used. The remaining bits should be
20- // zero:
21- // 0b00: unlocked
22- // 0b01: locked
23- // 0b10: unlocked and has parked threads
24- // 0b11: locked and has parked threads
25- //
26- // Typical initialization:
27- // PyMutex m = (PyMutex){0};
28- //
29- // Or initialize as global variables:
30- // static PyMutex m;
31- //
32- // Typical usage:
33- // PyMutex_Lock(&m);
34- // ...
35- // PyMutex_Unlock(&m);
36-
37- // NOTE: In Py_GIL_DISABLED builds, `struct _PyMutex` is defined in Include/object.h.
38- // The Py_GIL_DISABLED builds need the definition in Include/object.h for the
39- // `ob_mutex` field in PyObject. For the default (non-free-threaded) build,
40- // we define the struct here to avoid exposing it in the public API.
41- #ifndef Py_GIL_DISABLED
42- struct _PyMutex { uint8_t v; };
43- #endif
44-
45- typedef struct _PyMutex PyMutex;
46-
47- #define _Py_UNLOCKED 0
48- #define _Py_LOCKED 1
16+ // _Py_UNLOCKED is defined as 0 and _Py_LOCKED as 1 in Include/cpython/lock.h
4917#define _Py_HAS_PARKED 2
5018#define _Py_ONCE_INITIALIZED 4
5119
52- // (private) slow path for locking the mutex
53- PyAPI_FUNC (void ) _PyMutex_LockSlow(PyMutex *m);
54-
55- // (private) slow path for unlocking the mutex
56- PyAPI_FUNC (void ) _PyMutex_UnlockSlow(PyMutex *m);
57-
5820static inline int
5921PyMutex_LockFast (uint8_t *lock_bits)
6022{
6123 uint8_t expected = _Py_UNLOCKED;
6224 return _Py_atomic_compare_exchange_uint8 (lock_bits, &expected, _Py_LOCKED);
6325}
6426
65- // Locks the mutex.
66- //
67- // If the mutex is currently locked, the calling thread will be parked until
68- // the mutex is unlocked. If the current thread holds the GIL, then the GIL
69- // will be released while the thread is parked.
70- static inline void
71- PyMutex_Lock (PyMutex *m)
72- {
73- uint8_t expected = _Py_UNLOCKED;
74- if (!_Py_atomic_compare_exchange_uint8 (&m->v , &expected, _Py_LOCKED)) {
75- _PyMutex_LockSlow (m);
76- }
77- }
78-
79- // Unlocks the mutex.
80- static inline void
81- PyMutex_Unlock (PyMutex *m)
82- {
83- uint8_t expected = _Py_LOCKED;
84- if (!_Py_atomic_compare_exchange_uint8 (&m->v , &expected, _Py_UNLOCKED)) {
85- _PyMutex_UnlockSlow (m);
86- }
87- }
88-
8927// Checks if the mutex is currently locked.
9028static inline int
9129PyMutex_IsLocked (PyMutex *m)
9230{
93- return (_Py_atomic_load_uint8 (&m->v ) & _Py_LOCKED) != 0 ;
31+ return (_Py_atomic_load_uint8 (&m->_bits ) & _Py_LOCKED) != 0 ;
9432}
9533
9634// Re-initializes the mutex after a fork to the unlocked state.
@@ -121,7 +59,7 @@ static inline void
12159PyMutex_LockFlags (PyMutex *m, _PyLockFlags flags)
12260{
12361 uint8_t expected = _Py_UNLOCKED;
124- if (!_Py_atomic_compare_exchange_uint8 (&m->v , &expected, _Py_LOCKED)) {
62+ if (!_Py_atomic_compare_exchange_uint8 (&m->_bits , &expected, _Py_LOCKED)) {
12563 _PyMutex_LockTimed (m, -1 , flags);
12664 }
12765}
0 commit comments