Skip to content

[C API] Make Py_REFCNT() opaque in limited C API 3.14 #124127

Closed
@vstinner

Description

@vstinner

In the limited C API 3.14 and newer, I propose to change Py_REFCNT() implementation to an opaque function call to hide implementation details. I made a similar change for Py_INCREF() and Py_DECREF() in Python 3.12.

The problem is that with Free Threading (PEP 703), the implementation of this functions becomes less trivial than just getting the object member PyObject.ob_refcnt:

static inline Py_ssize_t _Py_REFCNT(PyObject *ob) {
    uint32_t local = _Py_atomic_load_uint32_relaxed(&ob->ob_ref_local);
    if (local == _Py_IMMORTAL_REFCNT_LOCAL) {
        return _Py_IMMORTAL_REFCNT;
    }
    Py_ssize_t shared = _Py_atomic_load_ssize_relaxed(&ob->ob_ref_shared);
    return _Py_STATIC_CAST(Py_ssize_t, local) +
           Py_ARITHMETIC_RIGHT_SHIFT(Py_ssize_t, shared, _Py_REF_SHARED_SHIFT);
}

_Py_atomic_load_uint32_relaxed() and _Py_atomic_load_ssize_relaxed() must now be called. But I would prefer to not "leak" such implementation detail into the limited C API.

cc @colesbury @Fidget-Spinner @encukou

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions