]> git.ipfire.org Git - thirdparty/Python/cpython.git/commit
gh-132657: Add lock-free set contains implementation (#132290)
authorNeil Schemenauer <nas-github@arctrix.com>
Sat, 13 Dec 2025 09:50:23 +0000 (01:50 -0800)
committerGitHub <noreply@github.com>
Sat, 13 Dec 2025 09:50:23 +0000 (09:50 +0000)
commitc98182be8d47a69b9a43c08f58bac7a70c109cc9
tree056dfe03525cc312ce2f724066f86ab96caadd3f
parent3e36d375352632be85b9ac3a0eeb075a4e03ef6f
gh-132657: Add lock-free set contains implementation (#132290)

This roughly follows what was done for dictobject to make a lock-free
lookup operation. With this change, the set contains operation scales much
better when used from multiple-threads. The frozenset contains performance
seems unchanged (as already lock-free).

Summary of changes:

* refactor set_lookkey() into set_do_lookup() which now takes a function
  pointer that does the entry comparison. This is similar to dictobject and
  do_lookup(). In an optimized build, the comparison function is inlined and
  there should be no performance cost to this.

* change set_do_lookup() to return a status separately from the entry value

* add set_compare_frozenset() and use if the object is a frozenset. For the
  free-threaded build, this avoids some overhead (locking, atomic operations,
  incref/decref on key)

* use FT_ATOMIC_* macros as needed for atomic loads and stores

* use a deferred free on the set table array, if shared (only on free-threaded
  build, normal build always does an immediate free)

* for free-threaded build, use explicit for loop to zero the table, rather than memcpy()

* when mutating the set, assign so->table to NULL while the change is a
  happening. Assign the real table array after the change is done.
Include/internal/pycore_pyatomic_ft_wrappers.h
Lib/test/test_free_threading/test_set.py
Misc/NEWS.d/next/Core_and_Builtins/2025-07-11-19-57-27.gh-issue-132657.vwDuO2.rst [new file with mode: 0644]
Objects/clinic/setobject.c.h
Objects/setobject.c