Skip to content

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

Closed

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

Activity

  1. added 4 commits that reference this issue on Sep 16, 2024
  2. vstinner commented on Sep 16, 2024

    @vstinner
    MemberAuthor

    Previous issue about Py_TYPE(): #120600

  3. added a commit that references this issue on Sep 24, 2024
  4. vstinner commented on Sep 24, 2024

    @vstinner
    MemberAuthor

    Implemented in 9d344fa.

  5. vstinner commented on Sep 24, 2024

    @vstinner
    MemberAuthor

    Functions implemented as opaque function calls in limited C API 3.14:

    • Py_TYPE() (since 3.14)
    • Py_REFCNT() (since 3.14), Py_SET_REFCNT() (since 3.13)
    • Py_INCREF(), Py_XINCREF() (since 3.12)
    • Py_DECREF(), Py_XDECREF() (since 3.12)

    Py_SET_TYPE() is not implemented as an opaque function call since it should not be used in the limited C API, it's only useful with static types.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions