summaryrefslogtreecommitdiffstats
path: root/Include/cpython
diff options
context:
space:
mode:
authorSam Gross <colesbury@gmail.com>2024-02-16 20:25:19 (GMT)
committerGitHub <noreply@github.com>2024-02-16 20:25:19 (GMT)
commit590319072773bd6cdcca655c420d3adb84838e96 (patch)
treeb2e7ec5cb49ef21d0fe9f35b9f32d69e8578fb86 /Include/cpython
parent711f42de2e3749208cfa7effa0d45b04e4e1fdd4 (diff)
downloadcpython-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.h6
-rw-r--r--Include/cpython/pyatomic_gcc.h8
-rw-r--r--Include/cpython/pyatomic_msc.h28
-rw-r--r--Include/cpython/pyatomic_std.h16
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)
{