diff options
author | Sam Gross <colesbury@gmail.com> | 2024-02-16 20:25:19 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-02-16 20:25:19 (GMT) |
commit | 590319072773bd6cdcca655c420d3adb84838e96 (patch) | |
tree | b2e7ec5cb49ef21d0fe9f35b9f32d69e8578fb86 /Include/cpython | |
parent | 711f42de2e3749208cfa7effa0d45b04e4e1fdd4 (diff) | |
download | cpython-590319072773bd6cdcca655c420d3adb84838e96.zip cpython-590319072773bd6cdcca655c420d3adb84838e96.tar.gz cpython-590319072773bd6cdcca655c420d3adb84838e96.tar.bz2 |
gh-115103: Implement delayed memory reclamation (QSBR) (#115180)
This adds a safe memory reclamation scheme based on FreeBSD's "GUS" and
quiescent state based reclamation (QSBR). The API provides a mechanism
for callers to detect when it is safe to free memory that may be
concurrently accessed by readers.
Diffstat (limited to 'Include/cpython')
-rw-r--r-- | Include/cpython/pyatomic.h | 6 | ||||
-rw-r--r-- | Include/cpython/pyatomic_gcc.h | 8 | ||||
-rw-r--r-- | Include/cpython/pyatomic_msc.h | 28 | ||||
-rw-r--r-- | Include/cpython/pyatomic_std.h | 16 |
4 files changed, 57 insertions, 1 deletions
diff --git a/Include/cpython/pyatomic.h b/Include/cpython/pyatomic.h index 9b57741..737eed8 100644 --- a/Include/cpython/pyatomic.h +++ b/Include/cpython/pyatomic.h @@ -475,6 +475,12 @@ _Py_atomic_store_int_release(int *obj, int value); static inline int _Py_atomic_load_int_acquire(const int *obj); +static inline void +_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value); + +static inline uint64_t +_Py_atomic_load_uint64_acquire(const uint64_t *obj); + static inline uint32_t _Py_atomic_load_uint32_acquire(const uint32_t *obj); diff --git a/Include/cpython/pyatomic_gcc.h b/Include/cpython/pyatomic_gcc.h index bc74149..de23edf 100644 --- a/Include/cpython/pyatomic_gcc.h +++ b/Include/cpython/pyatomic_gcc.h @@ -504,6 +504,14 @@ static inline int _Py_atomic_load_int_acquire(const int *obj) { return __atomic_load_n(obj, __ATOMIC_ACQUIRE); } +static inline void +_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value) +{ __atomic_store_n(obj, value, __ATOMIC_RELEASE); } + +static inline uint64_t +_Py_atomic_load_uint64_acquire(const uint64_t *obj) +{ return __atomic_load_n(obj, __ATOMIC_ACQUIRE); } + static inline uint32_t _Py_atomic_load_uint32_acquire(const uint32_t *obj) { return __atomic_load_n(obj, __ATOMIC_ACQUIRE); } diff --git a/Include/cpython/pyatomic_msc.h b/Include/cpython/pyatomic_msc.h index 6ab6401..9809d98 100644 --- a/Include/cpython/pyatomic_msc.h +++ b/Include/cpython/pyatomic_msc.h @@ -952,13 +952,39 @@ _Py_atomic_load_int_acquire(const int *obj) #endif } +static inline void +_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value) +{ +#if defined(_M_X64) || defined(_M_IX86) + *(uint64_t volatile *)obj = value; +#elif defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(unsigned __int64); + __stlr64((unsigned __int64 volatile *)obj, (unsigned __int64)value); +#else +# error "no implementation of _Py_atomic_store_uint64_release" +#endif +} + +static inline uint64_t +_Py_atomic_load_uint64_acquire(const uint64_t *obj) +{ +#if defined(_M_X64) || defined(_M_IX86) + return *(uint64_t volatile *)obj; +#elif defined(_M_ARM64) + _Py_atomic_ASSERT_ARG_TYPE(__int64); + return (uint64_t)__ldar64((unsigned __int64 volatile *)obj); +#else +# error "no implementation of _Py_atomic_load_uint64_acquire" +#endif +} + static inline uint32_t _Py_atomic_load_uint32_acquire(const uint32_t *obj) { #if defined(_M_X64) || defined(_M_IX86) return *(uint32_t volatile *)obj; #elif defined(_M_ARM64) - return (int)__ldar32((uint32_t volatile *)obj); + return (uint32_t)__ldar32((uint32_t volatile *)obj); #else # error "no implementation of _Py_atomic_load_uint32_acquire" #endif diff --git a/Include/cpython/pyatomic_std.h b/Include/cpython/pyatomic_std.h index d3004db..f5bd73a 100644 --- a/Include/cpython/pyatomic_std.h +++ b/Include/cpython/pyatomic_std.h @@ -887,6 +887,22 @@ _Py_atomic_load_int_acquire(const int *obj) memory_order_acquire); } +static inline void +_Py_atomic_store_uint64_release(uint64_t *obj, uint64_t value) +{ + _Py_USING_STD; + atomic_store_explicit((_Atomic(uint64_t)*)obj, value, + memory_order_release); +} + +static inline uint64_t +_Py_atomic_load_uint64_acquire(const uint64_t *obj) +{ + _Py_USING_STD; + return atomic_load_explicit((const _Atomic(uint64_t)*)obj, + memory_order_acquire); +} + static inline uint32_t _Py_atomic_load_uint32_acquire(const uint32_t *obj) { |