gh-117657: Fixes a few small TSAN issues in dictobject (#118200)

Fixup TSAN errors for dict
This commit is contained in:
Dino Viehland 2024-04-25 08:53:29 -07:00 committed by GitHub
parent cce5ae6082
commit 5da0280648
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 19 additions and 15 deletions

View File

@ -56,7 +56,11 @@ static inline Py_ssize_t PyDict_GET_SIZE(PyObject *op) {
PyDictObject *mp; PyDictObject *mp;
assert(PyDict_Check(op)); assert(PyDict_Check(op));
mp = _Py_CAST(PyDictObject*, op); mp = _Py_CAST(PyDictObject*, op);
#ifdef Py_GIL_DISABLED
return _Py_atomic_load_ssize_relaxed(&mp->ma_used);
#else
return mp->ma_used; return mp->ma_used;
#endif
} }
#define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op)) #define PyDict_GET_SIZE(op) PyDict_GET_SIZE(_PyObject_CAST(op))

View File

@ -688,7 +688,7 @@ static inline PyDictObject *
_PyObject_GetManagedDict(PyObject *obj) _PyObject_GetManagedDict(PyObject *obj)
{ {
PyManagedDictPointer *dorv = _PyObject_ManagedDictPointer(obj); PyManagedDictPointer *dorv = _PyObject_ManagedDictPointer(obj);
return (PyDictObject *)FT_ATOMIC_LOAD_PTR_RELAXED(dorv->dict); return (PyDictObject *)FT_ATOMIC_LOAD_PTR_ACQUIRE(dorv->dict);
} }
static inline PyDictValues * static inline PyDictValues *

View File

@ -1097,10 +1097,11 @@ compare_unicode_unicode(PyDictObject *mp, PyDictKeysObject *dk,
void *ep0, Py_ssize_t ix, PyObject *key, Py_hash_t hash) void *ep0, Py_ssize_t ix, PyObject *key, Py_hash_t hash)
{ {
PyDictUnicodeEntry *ep = &((PyDictUnicodeEntry *)ep0)[ix]; PyDictUnicodeEntry *ep = &((PyDictUnicodeEntry *)ep0)[ix];
assert(ep->me_key != NULL); PyObject *ep_key = FT_ATOMIC_LOAD_PTR_RELAXED(ep->me_key);
assert(PyUnicode_CheckExact(ep->me_key)); assert(ep_key != NULL);
if (ep->me_key == key || assert(PyUnicode_CheckExact(ep_key));
(unicode_get_hash(ep->me_key) == hash && unicode_eq(ep->me_key, key))) { if (ep_key == key ||
(unicode_get_hash(ep_key) == hash && unicode_eq(ep_key, key))) {
return 1; return 1;
} }
return 0; return 0;
@ -1761,10 +1762,12 @@ insertdict(PyInterpreterState *interp, PyDictObject *mp,
else { else {
assert(old_value != NULL); assert(old_value != NULL);
if (DK_IS_UNICODE(mp->ma_keys)) { if (DK_IS_UNICODE(mp->ma_keys)) {
DK_UNICODE_ENTRIES(mp->ma_keys)[ix].me_value = value; PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
STORE_VALUE(ep, value);
} }
else { else {
DK_ENTRIES(mp->ma_keys)[ix].me_value = value; PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
STORE_VALUE(ep, value);
} }
} }
mp->ma_version_tag = new_version; mp->ma_version_tag = new_version;
@ -1810,15 +1813,15 @@ insert_to_emptydict(PyInterpreterState *interp, PyDictObject *mp,
if (unicode) { if (unicode) {
PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(newkeys); PyDictUnicodeEntry *ep = DK_UNICODE_ENTRIES(newkeys);
ep->me_key = key; ep->me_key = key;
ep->me_value = value; STORE_VALUE(ep, value);
} }
else { else {
PyDictKeyEntry *ep = DK_ENTRIES(newkeys); PyDictKeyEntry *ep = DK_ENTRIES(newkeys);
ep->me_key = key; ep->me_key = key;
ep->me_hash = hash; ep->me_hash = hash;
ep->me_value = value; STORE_VALUE(ep, value);
} }
mp->ma_used++; FT_ATOMIC_STORE_SSIZE_RELAXED(mp->ma_used, FT_ATOMIC_LOAD_SSIZE_RELAXED(mp->ma_used) + 1);
mp->ma_version_tag = new_version; mp->ma_version_tag = new_version;
newkeys->dk_usable--; newkeys->dk_usable--;
newkeys->dk_nentries++; newkeys->dk_nentries++;
@ -2510,7 +2513,7 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix); Py_ssize_t hashpos = lookdict_index(mp->ma_keys, hash, ix);
assert(hashpos >= 0); assert(hashpos >= 0);
mp->ma_used--; FT_ATOMIC_STORE_SSIZE_RELAXED(mp->ma_used, FT_ATOMIC_LOAD_SSIZE(mp->ma_used) - 1);
mp->ma_version_tag = new_version; mp->ma_version_tag = new_version;
if (_PyDict_HasSplitTable(mp)) { if (_PyDict_HasSplitTable(mp)) {
assert(old_value == mp->ma_values->values[ix]); assert(old_value == mp->ma_values->values[ix]);
@ -6895,7 +6898,7 @@ _PyObject_TryGetInstanceAttribute(PyObject *obj, PyObject *name, PyObject **attr
} }
#ifdef Py_GIL_DISABLED #ifdef Py_GIL_DISABLED
PyObject *value = _Py_atomic_load_ptr_relaxed(&values->values[ix]); PyObject *value = _Py_atomic_load_ptr_acquire(&values->values[ix]);
if (value == NULL || _Py_TryIncrefCompare(&values->values[ix], value)) { if (value == NULL || _Py_TryIncrefCompare(&values->values[ix], value)) {
*attr = value; *attr = value;
return true; return true;

View File

@ -28,9 +28,6 @@ race:_PyObject_GC_TRACK
race:_PyParkingLot_Park race:_PyParkingLot_Park
race:_PyType_HasFeature race:_PyType_HasFeature
race:assign_version_tag race:assign_version_tag
race:compare_unicode_unicode
race:delitem_common
race:dictresize
race:gc_collect_main race:gc_collect_main
race:gc_restore_tid race:gc_restore_tid
race:initialize_new_array race:initialize_new_array