-
-
Notifications
You must be signed in to change notification settings - Fork 32.2k
gh-117511: Make PyMutex public in the non-limited API #117731
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
3c743f8
d340d28
e59e0f7
1cef880
28c90bc
e321817
6533089
215020a
c0f75f9
4ebc5e5
19a3492
7230134
6b2d377
476e493
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
colesbury marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
#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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef Py_LOCK_H | ||
#define Py_LOCK_H | ||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
#ifndef Py_LIMITED_API | ||
# define Py_CPYTHON_LOCK_H | ||
# include "cpython/lock.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't see the value of such header file. Just include cpython/lock.h in Python.h, and check Py_LIMITED_API in cpython/lock.h. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ericsnowcurrently expressed a preference for this style when There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. IMO, it's helpful to follow a consistent pattern when it comes to the Include/cpython header files. That means in some cases we end up with very minimal header files like this in Include/. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you mention consistency, there are already many header files in Include/cpython/ which have no companion Include/ header file:
|
||
# undef Py_CPYTHON_LOCK_H | ||
#endif | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif | ||
#endif /* !Py_LOCK_H */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Make the :c:type:`PyMutex` public in the non-limited C API. |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2372,7 +2372,7 @@ new_reference(PyObject *op) | |
#else | ||
op->ob_tid = _Py_ThreadId(); | ||
op->_padding = 0; | ||
op->ob_mutex = (struct _PyMutex){ 0 }; | ||
op->ob_mutex = (PyMutex){ 0 }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If there is no public PyMutex_STATIC_INIT, can you maybe add a private one in pycore_lock.h? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's consider that in a separate PR:
|
||
op->ob_gc_bits = 0; | ||
op->ob_ref_local = 1; | ||
op->ob_ref_shared = 0; | ||
|
Uh oh!
There was an error while loading. Please reload this page.