Skip to content

gh-123619: Add an unstable C API function for enabling deferred reference counting #123635

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 38 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
7107103
Implement PyUnstable_Object_SetDeferredRefcount
ZeroIntensity Sep 3, 2024
3928ea6
Update documentation.
ZeroIntensity Sep 3, 2024
6d2d34e
Add docstring.
ZeroIntensity Sep 3, 2024
6af0adf
Add NEWS entry.
ZeroIntensity Sep 3, 2024
1cc3aae
Fix indentation.
ZeroIntensity Sep 3, 2024
fd087a5
Fix hyperlink reference.
ZeroIntensity Sep 3, 2024
2dacc0d
Update object.c
ZeroIntensity Sep 19, 2024
0c8b98d
Update object.rst
ZeroIntensity Sep 19, 2024
50ff96e
Rename to EnableDeferredRefcount
ZeroIntensity Sep 19, 2024
6be9286
No-op if the object already has DRC enabled
ZeroIntensity Sep 19, 2024
10f3a2d
Fix indentation.
ZeroIntensity Sep 19, 2024
78889d5
Use 1 for success.
ZeroIntensity Sep 19, 2024
fe2cb46
Remove redundant line.
ZeroIntensity Sep 19, 2024
7b95459
Add simple unit test.
ZeroIntensity Sep 19, 2024
042f610
Make thread-safe.
ZeroIntensity Oct 7, 2024
c1d9c74
Fix test.
ZeroIntensity Oct 7, 2024
a88aa31
Add owned-by-current-thread check back.
ZeroIntensity Oct 7, 2024
3f31693
Use atomic storage for ob_ref_shared
ZeroIntensity Oct 7, 2024
cedf106
No-op if the object is not a GC type.
ZeroIntensity Oct 21, 2024
b5f8df6
Update the documentation.
ZeroIntensity Oct 21, 2024
7e2653a
Update the docstring.
ZeroIntensity Oct 21, 2024
b831c77
Clarify thread safety in the documentation.
ZeroIntensity Oct 21, 2024
d0b5ed2
Fix thread safety on GC bits.
ZeroIntensity Oct 21, 2024
f2b2c78
Retain old reference count.
ZeroIntensity Oct 21, 2024
5728bc3
Require CPU resources for tests.
ZeroIntensity Nov 2, 2024
e6dd1f7
Fix typo.
ZeroIntensity Nov 2, 2024
85ce7dd
Add a what's new entry.
ZeroIntensity Nov 2, 2024
51a8a30
Merge branch 'main' into api-deferred-rc
ZeroIntensity Nov 2, 2024
1e4413f
Remove extra newline.
ZeroIntensity Nov 2, 2024
b57078c
Merge branch 'api-deferred-rc' of https://github.com/ZeroIntensity/cp…
ZeroIntensity Nov 2, 2024
99e9b64
Fix retainment of shared reference count.
ZeroIntensity Nov 2, 2024
d8e8af8
Update object.rst
ZeroIntensity Nov 4, 2024
7b3510d
Update object.rst
ZeroIntensity Nov 4, 2024
4c29547
Update Doc/c-api/object.rst
ZeroIntensity Nov 4, 2024
55443b6
Use _Py_atomic_add_ssize instead of store.
ZeroIntensity Nov 4, 2024
00debea
Merge branch 'api-deferred-rc' of https://github.com/ZeroIntensity/cp…
ZeroIntensity Nov 4, 2024
1a20d14
Don't load the GC bits more than once.
ZeroIntensity Nov 4, 2024
93e1030
Merge in the main branch
encukou Nov 13, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions Doc/c-api/object.rst
Original file line number Diff line number Diff line change
Expand Up @@ -575,3 +575,18 @@ Object Protocol
has the :c:macro:`Py_TPFLAGS_MANAGED_DICT` flag set.

.. versionadded:: 3.13

.. c:function:: int PyUnstable_Object_SetDeferredRefcount(PyObject *obj)

Enable `deferred reference counting <https://peps.python.org/pep-0703/#deferred-reference-counting>`_ on *obj*.

*obj* must be an object tracked by the garbage collector (see :func:`gc.is_tracked`), must have been
created by the calling thread, and must not be in use by any existing threads.

If any of the above conditions are not met, this function returns a negative value
and sets an exception.

This function is a no-op on builds with the :term:`GIL` enabled.

.. versionadded:: 3.14

7 changes: 7 additions & 0 deletions Include/cpython/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -526,3 +526,10 @@ typedef enum {
typedef int (*PyRefTracer)(PyObject *, PyRefTracerEvent event, void *);
PyAPI_FUNC(int) PyRefTracer_SetTracer(PyRefTracer tracer, void *data);
PyAPI_FUNC(PyRefTracer) PyRefTracer_GetTracer(void**);

/* Enable PEP-703 deferred reference counting on the object.
*
* If this is called on a build with the GIL enabled, this
* function does nothing.
*/
PyAPI_FUNC(int) PyUnstable_Object_SetDeferredRefcount(PyObject *);
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Added the :c:func:`PyUnstable_Object_SetDeferredRefcount` function for
enabling :pep:`703` deferred reference counting.
31 changes: 31 additions & 0 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2482,6 +2482,37 @@ _PyObject_SetDeferredRefcount(PyObject *op)
#endif
}

int
PyUnstable_Object_SetDeferredRefcount(PyObject *op)
{
#ifdef Py_GIL_DISABLED
if (!PyType_IS_GC(Py_TYPE(op)))
{
PyErr_SetString(PyExc_TypeError,
"object is not tracked by the garbage collector");
return -1;
}

if (!_Py_IsOwnedByCurrentThread(op))
{
PyErr_SetString(PyExc_ValueError,
"object is not owned by this thread");
return -1;
}

if (op->ob_ref_shared != 0)
{
PyErr_SetString(PyExc_ValueError,
"object is already in use by another thread");
return -1;
}

_PyObject_SET_GC_BITS(op, _PyGC_BITS_DEFERRED);
op->ob_ref_shared = _Py_REF_SHARED(_Py_REF_DEFERRED, 0);
#endif
return 0;
}

void
_Py_ResurrectReference(PyObject *op)
{
Expand Down
Loading