diff options
| author | Sam Gross <colesbury@gmail.com> | 2024-06-20 16:00:25 (GMT) |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-06-20 16:00:25 (GMT) |
| commit | 3cb6c4cd60bec1acbcd960f5e7bd65f78152dbdd (patch) | |
| tree | f5b72124507a3c8ea7e5938bdb2cdb7563ca1ac1 /Include/cpython | |
| parent | 7c7aa5a99cce256ff726654038092a333a1f0531 (diff) | |
| download | cpython-3cb6c4cd60bec1acbcd960f5e7bd65f78152dbdd.zip cpython-3cb6c4cd60bec1acbcd960f5e7bd65f78152dbdd.tar.gz cpython-3cb6c4cd60bec1acbcd960f5e7bd65f78152dbdd.tar.bz2 | |
[3.13] gh-117511: Make PyMutex public in the non-limited API (GH-117731) (#120800)
(cherry picked from commit 3af7263037de1d0ef63b070fc7bfc2cf042eaebe)
Diffstat (limited to 'Include/cpython')
| -rw-r--r-- | Include/cpython/lock.h | 63 | ||||
| -rw-r--r-- | Include/cpython/weakrefobject.h | 2 |
2 files changed, 64 insertions, 1 deletions
diff --git a/Include/cpython/lock.h b/Include/cpython/lock.h new file mode 100644 index 0000000..8ee03e8 --- /dev/null +++ b/Include/cpython/lock.h @@ -0,0 +1,63 @@ +#ifndef Py_CPYTHON_LOCK_H +# error "this header file must not be included directly" +#endif + +#define _Py_UNLOCKED 0 +#define _Py_LOCKED 1 + +// A mutex that occupies one byte. The lock can be zero initialized to +// represent the unlocked state. +// +// Typical initialization: +// PyMutex m = (PyMutex){0}; +// +// Or initialize as global variables: +// static PyMutex m; +// +// Typical usage: +// PyMutex_Lock(&m); +// ... +// PyMutex_Unlock(&m); +// +// The contents of the PyMutex are not part of the public API, but are +// described to aid in understanding the implementation and debugging. Only +// the two least significant bits are used. The remaining bits are always zero: +// 0b00: unlocked +// 0b01: locked +// 0b10: unlocked and has parked threads +// 0b11: locked and has parked threads +typedef struct PyMutex { + uint8_t _bits; // (private) +} PyMutex; + +// exported function for locking the mutex +PyAPI_FUNC(void) PyMutex_Lock(PyMutex *m); + +// exported function for unlocking the mutex +PyAPI_FUNC(void) PyMutex_Unlock(PyMutex *m); + +// Locks the mutex. +// +// If the mutex is currently locked, the calling thread will be parked until +// the mutex is unlocked. If the current thread holds the GIL, then the GIL +// will be released while the thread is parked. +static inline void +_PyMutex_Lock(PyMutex *m) +{ + uint8_t expected = _Py_UNLOCKED; + if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_LOCKED)) { + PyMutex_Lock(m); + } +} +#define PyMutex_Lock _PyMutex_Lock + +// Unlocks the mutex. +static inline void +_PyMutex_Unlock(PyMutex *m) +{ + uint8_t expected = _Py_LOCKED; + if (!_Py_atomic_compare_exchange_uint8(&m->_bits, &expected, _Py_UNLOCKED)) { + PyMutex_Unlock(m); + } +} +#define PyMutex_Unlock _PyMutex_Unlock diff --git a/Include/cpython/weakrefobject.h b/Include/cpython/weakrefobject.h index dcca166..28acf72 100644 --- a/Include/cpython/weakrefobject.h +++ b/Include/cpython/weakrefobject.h @@ -36,7 +36,7 @@ struct _PyWeakReference { * Normally this can be derived from wr_object, but in some cases we need * to lock after wr_object has been set to Py_None. */ - struct _PyMutex *weakrefs_lock; + PyMutex *weakrefs_lock; #endif }; |
