Coverage Report

Created: 2025-10-10 06:33

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython-install/include/python3.15/cpython/pylock.h
Line
Count
Source
1
#ifndef Py_LOCK_H
2
#define Py_LOCK_H
3
#ifndef Py_LIMITED_API
4
#ifdef __cplusplus
5
extern "C" {
6
#endif
7
8
9
#define _Py_UNLOCKED    0
10
#define _Py_LOCKED      1
11
12
// A mutex that occupies one byte. The lock can be zero initialized to
13
// represent the unlocked state.
14
//
15
// Typical initialization:
16
//   PyMutex m = (PyMutex){0};
17
//
18
// Or initialize as global variables:
19
//   static PyMutex m;
20
//
21
// Typical usage:
22
//   PyMutex_Lock(&m);
23
//   ...
24
//   PyMutex_Unlock(&m);
25
//
26
// The contents of the PyMutex are not part of the public API, but are
27
// described to aid in understanding the implementation and debugging. Only
28
// the two least significant bits are used. The remaining bits are always zero:
29
// 0b00: unlocked
30
// 0b01: locked
31
// 0b10: unlocked and has parked threads
32
// 0b11: locked and has parked threads
33
typedef struct PyMutex {
34
    uint8_t _bits;  // (private)
35
} PyMutex;
36
37
// exported function for locking the mutex
38
PyAPI_FUNC(void) PyMutex_Lock(PyMutex *m);
39
40
// exported function for unlocking the mutex
41
PyAPI_FUNC(void) PyMutex_Unlock(PyMutex *m);
42
43
// exported function for checking if the mutex is locked
44
PyAPI_FUNC(int) PyMutex_IsLocked(PyMutex *m);
45
46
// Locks the mutex.
47
//
48
// If the mutex is currently locked, the calling thread will be parked until
49
// the mutex is unlocked. If the current thread holds the GIL, then the GIL
50
// will be released while the thread is parked.
51
static inline void
52
_PyMutex_Lock(PyMutex *m)
53
0
{
54
0
    uint8_t expected = _Py_UNLOCKED;
55
0
    if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_LOCKED)) {
56
0
        PyMutex_Lock(m);
57
0
    }
58
0
}
59
#define PyMutex_Lock _PyMutex_Lock
60
61
// Unlocks the mutex.
62
static inline void
63
_PyMutex_Unlock(PyMutex *m)
64
0
{
65
0
    uint8_t expected = _Py_LOCKED;
66
0
    if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_UNLOCKED)) {
67
0
        PyMutex_Unlock(m);
68
0
    }
69
0
}
70
#define PyMutex_Unlock _PyMutex_Unlock
71
72
// Checks if the mutex is currently locked.
73
static inline int
74
_PyMutex_IsLocked(PyMutex *m)
75
0
{
76
0
    return (_Py_atomic_load_uint8(&m->_bits) & _Py_LOCKED) != 0;
77
0
}
78
#define PyMutex_IsLocked _PyMutex_IsLocked
79
80
81
#ifdef __cplusplus
82
}
83
#endif
84
#endif  // !Py_LIMITED_API
85
#endif  // !Py_LOCK_H