• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #ifndef Py_CPYTHON_LOCK_H
2 #  error "this header file must not be included directly"
3 #endif
4 
5 #define _Py_UNLOCKED    0
6 #define _Py_LOCKED      1
7 
8 // A mutex that occupies one byte. The lock can be zero initialized to
9 // represent the unlocked state.
10 //
11 // Typical initialization:
12 //   PyMutex m = (PyMutex){0};
13 //
14 // Or initialize as global variables:
15 //   static PyMutex m;
16 //
17 // Typical usage:
18 //   PyMutex_Lock(&m);
19 //   ...
20 //   PyMutex_Unlock(&m);
21 //
22 // The contents of the PyMutex are not part of the public API, but are
23 // described to aid in understanding the implementation and debugging. Only
24 // the two least significant bits are used. The remaining bits are always zero:
25 // 0b00: unlocked
26 // 0b01: locked
27 // 0b10: unlocked and has parked threads
28 // 0b11: locked and has parked threads
29 typedef struct PyMutex {
30     uint8_t _bits;  // (private)
31 } PyMutex;
32 
33 // exported function for locking the mutex
34 PyAPI_FUNC(void) PyMutex_Lock(PyMutex *m);
35 
36 // exported function for unlocking the mutex
37 PyAPI_FUNC(void) PyMutex_Unlock(PyMutex *m);
38 
39 // Locks the mutex.
40 //
41 // If the mutex is currently locked, the calling thread will be parked until
42 // the mutex is unlocked. If the current thread holds the GIL, then the GIL
43 // will be released while the thread is parked.
44 static inline void
_PyMutex_Lock(PyMutex * m)45 _PyMutex_Lock(PyMutex *m)
46 {
47     uint8_t expected = _Py_UNLOCKED;
48     if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_LOCKED)) {
49         PyMutex_Lock(m);
50     }
51 }
52 #define PyMutex_Lock _PyMutex_Lock
53 
54 // Unlocks the mutex.
55 static inline void
_PyMutex_Unlock(PyMutex * m)56 _PyMutex_Unlock(PyMutex *m)
57 {
58     uint8_t expected = _Py_LOCKED;
59     if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_UNLOCKED)) {
60         PyMutex_Unlock(m);
61     }
62 }
63 #define PyMutex_Unlock _PyMutex_Unlock
64