From f151d271591ec525eaf01fa7b128e575374888b9 Mon Sep 17 00:00:00 2001 From: Sam Gross Date: Tue, 11 Feb 2025 16:53:08 -0500 Subject: gh-117657: Enable test_opcache under TSAN (GH-129831) Fix a few thread-safety bugs to enable test_opcache when run with TSAN: * Use relaxed atomics when clearing `ht->_spec_cache.getitem` (gh-115999) * Add temporary suppression for type slot modifications (gh-127266) * Use atomic load when reading `*dictptr` --- Lib/test/libregrtest/tsan.py | 1 + Objects/object.c | 2 +- Objects/typeobject.c | 6 ++++-- Tools/tsan/suppressions_free_threading.txt | 3 +++ 4 files changed, 9 insertions(+), 3 deletions(-) diff --git a/Lib/test/libregrtest/tsan.py b/Lib/test/libregrtest/tsan.py index 10b12cc..5123372 100644 --- a/Lib/test/libregrtest/tsan.py +++ b/Lib/test/libregrtest/tsan.py @@ -13,6 +13,7 @@ TSAN_TESTS = [ 'test_importlib', 'test_io', 'test_logging', + 'test_opcache', 'test_queue', 'test_signal', 'test_socket', diff --git a/Objects/object.c b/Objects/object.c index f3c7fa6..c3f57f4 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1612,7 +1612,7 @@ _PyObject_GetMethod(PyObject *obj, PyObject *name, PyObject **method) else { PyObject **dictptr = _PyObject_ComputedDictPointer(obj); if (dictptr != NULL) { - dict = *dictptr; + dict = FT_ATOMIC_LOAD_PTR_ACQUIRE(*dictptr); } else { dict = NULL; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index f3238da..59ea2e3 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -1085,7 +1085,8 @@ type_modified_unlocked(PyTypeObject *type) if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { // This field *must* be invalidated if the type is modified (see the // comment on struct _specialization_cache): - ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + FT_ATOMIC_STORE_PTR_RELAXED( + ((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL); } } @@ -1166,7 +1167,8 @@ type_mro_modified(PyTypeObject *type, PyObject *bases) { if (PyType_HasFeature(type, Py_TPFLAGS_HEAPTYPE)) { // This field *must* be invalidated if the type is modified (see the // comment on struct _specialization_cache): - ((PyHeapTypeObject *)type)->_spec_cache.getitem = NULL; + FT_ATOMIC_STORE_PTR_RELAXED( + ((PyHeapTypeObject *)type)->_spec_cache.getitem, NULL); } } diff --git a/Tools/tsan/suppressions_free_threading.txt b/Tools/tsan/suppressions_free_threading.txt index c2509ca..e4cf2a7 100644 --- a/Tools/tsan/suppressions_free_threading.txt +++ b/Tools/tsan/suppressions_free_threading.txt @@ -49,5 +49,8 @@ race_top:rangeiter_next # gh-129748: test.test_free_threading.test_slots.TestSlots.test_object race_top:mi_block_set_nextx +# gh-127266: type slot updates are not thread-safe (test_opcache.test_load_attr_method_lazy_dict) +race_top:update_one_slot + # https://gist.github.com/mpage/6962e8870606cfc960e159b407a0cb40 thread:pthread_create -- cgit v0.12