Skip to content

Avoid the weakref list lock when dereferencing weakrefs #159564

Open

Description

@nascheme

Feature or enhancement

In the free-threaded build, dereferencing a live weakref takes a striped weakref-list lock. This affects PyWeakref_GetRef(), calls to weakref.ref objects, and weakref hashing and comparison.

The 127 locks are packed into a small per-interpreter array. Threads accessing unrelated weakrefs can therefore contend on the same locks or cache lines, limiting throughput.

I propose using an atomic pointer load followed by _Py_TryIncrefCompare() instead of taking the lock in _PyWeakref_GET_REF().

This uses the allocator and reference-counting guarantees already used for optimistic dict and list reads. QSBR keeps reference-count fields readable during concurrent deallocation, and weakref creation already sets _Py_REF_MAYBE_WEAKREF on the referent. The pointer validation handles memory reuse: a weakref's target can only change from its original referent to Py_None.

Weakref creation, clearing, and deallocation would retain their existing synchronization.

Has this already been discussed elsewhere?

This is a minor feature, which does not need previous discussion elsewhere

Links to previous discussion of this feature:

No response

Linked PRs

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions