diff options
author | Dino Viehland <dinoviehland@meta.com> | 2024-03-08 17:56:36 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-08 17:56:36 (GMT) |
commit | 7db871e4fa48eef20ea22414b226998f83facfd6 (patch) | |
tree | 6b0b81db65dbf71864138847f32978cb831eeaed /Include/internal | |
parent | 61831585b637eb621bc80ae39e2e59541c135dc5 (diff) | |
download | cpython-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.h | 27 | ||||
-rw-r--r-- | Include/internal/pycore_pymem.h | 3 |
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); |