mirror of https://github.com/python/cpython
gh-117657: Fixes a few small TSAN issues in dictobject (#118200)
Fixup TSAN errors for dict
This commit is contained in:
parent
cce5ae6082
commit
5da0280648
|
@ -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))
|
||||||
|
|
||||||
|
|
|
@ -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 *
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue