Feature or enhancement
The set object is not currently thread-safe in --disable-gil builds. We should make it thread-safe by using the "critical section" API. to acquire the per-object locks around operations. There should be no effective change in the default build (i.e., with GIL) because critical sections are no-ops in the default build.
Notes:
- Unlike
dict and list, I don't think it's worth the complexity to try to "optimistically avoid locking" around any set operation (except set_len). We could consider doing this in the future if there is a performance justification, but not for 3.13.
set_len can avoid locking and instead use relaxed atomics for reading the "used" field. Note that writes to "used" should then also use relaxed atomics.
- Some operations require locking two containers (like
set_merge). Some of these will need refactorings so that the critical sections macros can be added in the correct places.
For context, here is the change from the nogil-3.12 fork: colesbury/nogil-3.12@4ca2924f0d. Note that the critical section API is slightly changed in 3.13 from nogil-3.12; In 3.13 Py_BEGIN_CRITICAL_SECTION takes a PyObject instead of a PyMutex.
TODO:
Linked PRs
Feature or enhancement
The
setobject is not currently thread-safe in--disable-gilbuilds. We should make it thread-safe by using the "critical section" API. to acquire the per-object locks around operations. There should be no effective change in the default build (i.e., with GIL) because critical sections are no-ops in the default build.Notes:
dictandlist, I don't think it's worth the complexity to try to "optimistically avoid locking" around any set operation (exceptset_len). We could consider doing this in the future if there is a performance justification, but not for 3.13.set_lencan avoid locking and instead use relaxed atomics for reading the "used" field. Note that writes to "used" should then also use relaxed atomics.set_merge). Some of these will need refactorings so that the critical sections macros can be added in the correct places.For context, here is the change from the
nogil-3.12fork: colesbury/nogil-3.12@4ca2924f0d. Note that the critical section API is slightly changed in 3.13 fromnogil-3.12; In 3.13Py_BEGIN_CRITICAL_SECTIONtakes a PyObject instead of a PyMutex.TODO:
set_init(see gh-112069: Make sets thread-safe with the GIL disabled #113800 (comment)). We also want to avoid locking inset_initif possible_PySet_NextEntrysetiter_iternextLinked PRs