summaryrefslogtreecommitdiffstats
path: root/Objects
diff options
context:
space:
mode:
authorPeter Bierma <zintensitydev@gmail.com>2024-11-13 13:27:16 (GMT)
committerGitHub <noreply@github.com>2024-11-13 13:27:16 (GMT)
commitd00878b06a05ea04790813dba70b09cc1d11bf45 (patch)
treee7508c9d7769379ae50a0f6e7572a61bb6dc952f /Objects
parent29b5323c4567dc7772e1d30a7ba1cbad52fe10a9 (diff)
downloadcpython-d00878b06a05ea04790813dba70b09cc1d11bf45.zip
cpython-d00878b06a05ea04790813dba70b09cc1d11bf45.tar.gz
cpython-d00878b06a05ea04790813dba70b09cc1d11bf45.tar.bz2
gh-123619: Add an unstable C API function for enabling deferred reference counting (GH-123635)
Co-authored-by: Sam Gross <colesbury@gmail.com>
Diffstat (limited to 'Objects')
-rw-r--r--Objects/object.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/Objects/object.c b/Objects/object.c
index 7cc74a8..052dea9 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -2519,6 +2519,35 @@ _PyObject_SetDeferredRefcount(PyObject *op)
#endif
}
+int
+PyUnstable_Object_EnableDeferredRefcount(PyObject *op)
+{
+#ifdef Py_GIL_DISABLED
+ if (!PyType_IS_GC(Py_TYPE(op))) {
+ // Deferred reference counting doesn't work
+ // on untracked types.
+ return 0;
+ }
+
+ uint8_t bits = _Py_atomic_load_uint8(&op->ob_gc_bits);
+ if ((bits & _PyGC_BITS_DEFERRED) != 0)
+ {
+ // Nothing to do.
+ return 0;
+ }
+
+ if (_Py_atomic_compare_exchange_uint8(&op->ob_gc_bits, &bits, bits | _PyGC_BITS_DEFERRED) == 0)
+ {
+ // Someone beat us to it!
+ return 0;
+ }
+ _Py_atomic_add_ssize(&op->ob_ref_shared, _Py_REF_SHARED(_Py_REF_DEFERRED, 0));
+ return 1;
+#else
+ return 0;
+#endif
+}
+
void
_Py_ResurrectReference(PyObject *op)
{