diff options
author | Sam Gross <colesbury@gmail.com> | 2023-09-19 15:54:29 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-09-19 15:54:29 (GMT) |
commit | 0c89056fe59ac42f09978582479d40e58a236856 (patch) | |
tree | 06cd5a790da2a6dd3862567419c25572f96ae373 /Include/cpython | |
parent | 0a31ff0050eec5079fd4c9cafd33b4e3e9afd9ab (diff) | |
download | cpython-0c89056fe59ac42f09978582479d40e58a236856.zip cpython-0c89056fe59ac42f09978582479d40e58a236856.tar.gz cpython-0c89056fe59ac42f09978582479d40e58a236856.tar.bz2 |
gh-108724: Add PyMutex and _PyParkingLot APIs (gh-109344)
PyMutex is a one byte lock with fast, inlineable lock and unlock functions for the common uncontended case. The design is based on WebKit's WTF::Lock.
PyMutex is built using the _PyParkingLot APIs, which provides a cross-platform futex-like API (based on WebKit's WTF::ParkingLot). This internal API will be used for building other synchronization primitives used to implement PEP 703, such as one-time initialization and events.
This also includes tests and a mini benchmark in Tools/lockbench/lockbench.py to compare with the existing PyThread_type_lock.
Uncontended acquisition + release:
* Linux (x86-64): PyMutex: 11 ns, PyThread_type_lock: 44 ns
* macOS (arm64): PyMutex: 13 ns, PyThread_type_lock: 18 ns
* Windows (x86-64): PyMutex: 13 ns, PyThread_type_lock: 38 ns
PR Overview:
The primary purpose of this PR is to implement PyMutex, but there are a number of support pieces (described below).
* PyMutex: A 1-byte lock that doesn't require memory allocation to initialize and is generally faster than the existing PyThread_type_lock. The API is internal only for now.
* _PyParking_Lot: A futex-like API based on the API of the same name in WebKit. Used to implement PyMutex.
* _PyRawMutex: A word sized lock used to implement _PyParking_Lot.
* PyEvent: A one time event. This was used a bunch in the "nogil" fork and is useful for testing the PyMutex implementation, so I've included it as part of the PR.
* pycore_llist.h: Defines common operations on doubly-linked list. Not strictly necessary (could do the list operations manually), but they come up frequently in the "nogil" fork. ( Similar to https://man.freebsd.org/cgi/man.cgi?queue)
---------
Co-authored-by: Eric Snow <ericsnowcurrently@gmail.com>
Diffstat (limited to 'Include/cpython')
-rw-r--r-- | Include/cpython/pyatomic.h | 9 | ||||
-rw-r--r-- | Include/cpython/pyatomic_msc.h | 2 |
2 files changed, 4 insertions, 7 deletions
diff --git a/Include/cpython/pyatomic.h b/Include/cpython/pyatomic.h index 73712db..ab18238 100644 --- a/Include/cpython/pyatomic.h +++ b/Include/cpython/pyatomic.h @@ -83,9 +83,9 @@ // # release // ... -#ifndef Py_ATOMIC_H -#define Py_ATOMIC_H - +#ifndef Py_CPYTHON_ATOMIC_H +# error "this header file must not be included directly" +#endif // --- _Py_atomic_add -------------------------------------------------------- // Atomically adds `value` to `obj` and returns the previous value @@ -501,6 +501,3 @@ static inline void _Py_atomic_fence_release(void); #else # error "no available pyatomic implementation for this platform/compiler" #endif - -#endif /* Py_ATOMIC_H */ - diff --git a/Include/cpython/pyatomic_msc.h b/Include/cpython/pyatomic_msc.h index c88bb03..287ed43 100644 --- a/Include/cpython/pyatomic_msc.h +++ b/Include/cpython/pyatomic_msc.h @@ -906,7 +906,7 @@ _Py_atomic_store_ptr_release(void *obj, void *value) #if defined(_M_X64) || defined(_M_IX86) *(void * volatile *)obj = value; #elif defined(_M_ARM64) - __stlr64(obj, (uintptr_t)value); + __stlr64((unsigned __int64 volatile *)obj, (uintptr_t)value); #else # error "no implementation of _Py_atomic_store_ptr_release" #endif |