From 658f35770e0fc57c08324dca94022fdeacd77e9d Mon Sep 17 00:00:00 2001 From: Thomas Wouters Date: Tue, 6 May 2025 12:52:03 +0200 Subject: [PATCH] Fix data race detected by tsan (https://github.com/python/cpython/actions/runs/14857021107/job/41712717208?pr=133502): young.count can be modified by other threads even while the gcstate is locked. This is the simplest fix to (potentially) unblock beta 1, although this particular code path seems like it could just be an atomic swap followed by an atomic add, without having the lock at all. --- Python/gc_free_threading.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c index f1ba5de51704e1..757e9cb3227e26 100644 --- a/Python/gc_free_threading.c +++ b/Python/gc_free_threading.c @@ -2074,10 +2074,9 @@ gc_should_collect_mem_usage(GCState *gcstate) // clear the young object count so we don't check memory usage again // on the next call to gc_should_collect(). PyMutex_Lock(&gcstate->mutex); + int young_count = _Py_atomic_exchange_int(&gcstate->young.count, 0); _Py_atomic_store_ssize_relaxed(&gcstate->deferred_count, - gcstate->deferred_count + - gcstate->young.count); - _Py_atomic_store_int(&gcstate->young.count, 0); + gcstate->deferred_count + young_count); PyMutex_Unlock(&gcstate->mutex); return false; }