@@ -13,84 +13,22 @@ extern "C" {
13
13
# error "this header requires Py_BUILD_CORE define"
14
14
#endif
15
15
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
49
17
#define _Py_HAS_PARKED 2
50
18
#define _Py_ONCE_INITIALIZED 4
51
19
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
-
58
20
static inline int
59
21
PyMutex_LockFast (uint8_t *lock_bits)
60
22
{
61
23
uint8_t expected = _Py_UNLOCKED;
62
24
return _Py_atomic_compare_exchange_uint8 (lock_bits, &expected, _Py_LOCKED);
63
25
}
64
26
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
-
89
27
// Checks if the mutex is currently locked.
90
28
static inline int
91
29
PyMutex_IsLocked (PyMutex *m)
92
30
{
93
- return (_Py_atomic_load_uint8 (&m->v ) & _Py_LOCKED) != 0 ;
31
+ return (_Py_atomic_load_uint8 (&m->_bits ) & _Py_LOCKED) != 0 ;
94
32
}
95
33
96
34
// Re-initializes the mutex after a fork to the unlocked state.
@@ -121,7 +59,7 @@ static inline void
121
59
PyMutex_LockFlags (PyMutex *m, _PyLockFlags flags)
122
60
{
123
61
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)) {
125
63
_PyMutex_LockTimed (m, -1 , flags);
126
64
}
127
65
}
0 commit comments