summaryrefslogtreecommitdiffstats
path: root/Include/internal
diff options
context:
space:
mode:
authorDino Viehland <dinoviehland@meta.com>2024-03-08 17:56:36 (GMT)
committerGitHub <noreply@github.com>2024-03-08 17:56:36 (GMT)
commit7db871e4fa48eef20ea22414b226998f83facfd6 (patch)
tree6b0b81db65dbf71864138847f32978cb831eeaed /Include/internal
parent61831585b637eb621bc80ae39e2e59541c135dc5 (diff)
downloadcpython-7db871e4fa48eef20ea22414b226998f83facfd6.zip
cpython-7db871e4fa48eef20ea22414b226998f83facfd6.tar.gz
cpython-7db871e4fa48eef20ea22414b226998f83facfd6.tar.bz2
gh-112075: Support freeing object memory via QSBR (#116344)
Free objects with qsbr if shared
Diffstat (limited to 'Include/internal')
-rw-r--r--Include/internal/pycore_gc.h27
-rw-r--r--Include/internal/pycore_pymem.h3
2 files changed, 27 insertions, 3 deletions
diff --git a/Include/internal/pycore_gc.h b/Include/internal/pycore_gc.h
index cf0b148..4a7191a 100644
--- a/Include/internal/pycore_gc.h
+++ b/Include/internal/pycore_gc.h
@@ -44,6 +44,7 @@ static inline PyObject* _Py_FROM_GC(PyGC_Head *gc) {
# define _PyGC_BITS_UNREACHABLE (4)
# define _PyGC_BITS_FROZEN (8)
# define _PyGC_BITS_SHARED (16)
+# define _PyGC_BITS_SHARED_INLINE (32)
#endif
/* True if the object is currently tracked by the GC. */
@@ -71,9 +72,12 @@ static inline int _PyObject_GC_MAY_BE_TRACKED(PyObject *obj) {
#ifdef Py_GIL_DISABLED
-/* True if an object is shared between multiple threads and
- * needs special purpose when freeing to do the possibility
- * of in-flight lock-free reads occurring */
+/* True if memory the object references is shared between
+ * multiple threads and needs special purpose when freeing
+ * those references due to the possibility of in-flight
+ * lock-free reads occurring. The object is responsible
+ * for calling _PyMem_FreeDelayed on the referenced
+ * memory. */
static inline int _PyObject_GC_IS_SHARED(PyObject *op) {
return (op->ob_gc_bits & _PyGC_BITS_SHARED) != 0;
}
@@ -84,6 +88,23 @@ static inline void _PyObject_GC_SET_SHARED(PyObject *op) {
}
#define _PyObject_GC_SET_SHARED(op) _PyObject_GC_SET_SHARED(_Py_CAST(PyObject*, op))
+/* True if the memory of the object is shared between multiple
+ * threads and needs special purpose when freeing due to
+ * the possibility of in-flight lock-free reads occurring.
+ * Objects with this bit that are GC objects will automatically
+ * delay-freed by PyObject_GC_Del. */
+static inline int _PyObject_GC_IS_SHARED_INLINE(PyObject *op) {
+ return (op->ob_gc_bits & _PyGC_BITS_SHARED_INLINE) != 0;
+}
+#define _PyObject_GC_IS_SHARED_INLINE(op) \
+ _PyObject_GC_IS_SHARED_INLINE(_Py_CAST(PyObject*, op))
+
+static inline void _PyObject_GC_SET_SHARED_INLINE(PyObject *op) {
+ op->ob_gc_bits |= _PyGC_BITS_SHARED_INLINE;
+}
+#define _PyObject_GC_SET_SHARED_INLINE(op) \
+ _PyObject_GC_SET_SHARED_INLINE(_Py_CAST(PyObject*, op))
+
#endif
/* Bit flags for _gc_prev */
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index 1aea91a..dd6b076 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -119,6 +119,9 @@ extern int _PyMem_DebugEnabled(void);
// Enqueue a pointer to be freed possibly after some delay.
extern void _PyMem_FreeDelayed(void *ptr);
+// Enqueue an object to be freed possibly after some delay
+extern void _PyObject_FreeDelayed(void *ptr);
+
// Periodically process delayed free requests.
extern void _PyMem_ProcessDelayed(PyThreadState *tstate);