8000 gh-112075: Use relaxed stores for places where we may race with when … · python/cpython@81c7996 · GitHub
[go: up one dir, main page]

Skip to content

Com 8000 mit 81c7996

Browse files
authored
gh-112075: Use relaxed stores for places where we may race with when reading lock-free (#115786)
1 parent 3409bc2 commit 81c7996

File tree

1 file changed

+25
-18
lines changed

1 file changed

+25
-18
lines changed

Objects/dictobject.c

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,14 @@ load_keys_nentries(PyDictObject *mp)
250250

251251
#endif
252252

253+
#define STORE_KEY(ep, key) FT_ATOMIC_STORE_PTR_RELEASE(ep->me_key, key)
254+
#define STORE_VALUE(ep, value) FT_ATOMIC_STORE_PTR_RELEASE(ep->me_value, value)
255+
#define STORE_SPLIT_VALUE(mp, idx, value) FT_ATOMIC_STORE_PTR_RELEASE(mp->ma_values->values[idx], value)
256+
#define STORE_HASH(ep, hash) FT_ATOMIC_STORE_SSIZE_RELAXED(ep->me_hash, hash)
257+
#define STORE_KEYS_USABLE(keys, usable) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_usable, usable)
258+
#define STORE_KEYS_NENTRIES(keys, nentries) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_nentries, nentries)
259+
#define STORE_USED(mp, used) FT_ATOMIC_STORE_SSIZE_RELAXED(mp->ma_used, used)
260+
253261
#define PERTURB_SHIFT 5
254262

255263
/*
@@ -1621,7 +1629,6 @@ insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
16211629
return ix;
16221630
}
16231631

1624-
16251632
static inline int
16261633
insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
16271634
Py_hash_t hash, PyObject *key, PyObject *value)
@@ -1639,18 +1646,18 @@ insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
16391646
if (DK_IS_UNICODE(mp->ma_keys)) {
16401647
PyDictUnicodeEntry *ep;
16411648
ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1642-
ep->me_key = key;
1643-
ep->me_value = value;
1649+
STORE_KEY(ep, key);
1650+
STORE_VALUE(ep, value);
16441651
}
16451652
else {
16461653
PyDictKeyEntry *ep;
16471654
ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1648-
ep->me_key = key;
1649-
ep->me_hash = hash;
1650-
ep->me_value = value;
1655+
STORE_KEY(ep, key);
1656+
STORE_VALUE(ep, value);
1657+
STORE_HASH(ep, hash);
16511658
}
1652-
mp->ma_keys->dk_usable--;
1653-
mp->ma_keys->dk_nentries++;
1659+
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - 1);
1660+
STORE_KEYS_NENTRIES(mp->ma_keys, mp->ma_keys->dk_nentries + 1);
16541661
assert(mp->ma_keys->dk_usable >= 0);
16551662
return 0;
16561663
}
@@ -1682,7 +1689,7 @@ insert_split_dict(PyInterpreterState *interp, PyDictObject *mp,
16821689
Py_ssize_t index = keys->dk_nentries;
16831690
_PyDictValues_AddToInsertionOrder(mp->ma_values, index);
16841691
assert (mp->ma_values->values[index] == NULL);
1685-
mp->ma_values->values[index] = value;
1692+
STORE_SPLIT_VALUE(mp, index, value);
16861693

16871694
split_keys_entry_added(keys);
16881695
assert(keys->dk_usable >= 0);
@@ -2013,8 +2020,8 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
20132020
}
20142021
}
20152022

2016-
mp->ma_keys->dk_usable -= numentries;
2017-
mp->ma_keys->dk_nentries = numentries;
2023+
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - numentries);
2024+
STORE_KEYS_NENTRIES(mp->ma_keys, numentries);
20182025
ASSERT_CONSISTENT(mp);
20192026
return 0;
20202027
}
@@ -2507,15 +2514,15 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
25072514
if (DK_IS_UNICODE(mp->ma_keys)) {
25082515
PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
25092516
old_key = ep->me_key;
2510-
ep->me_key = NULL;
2511-
ep->me_value = NULL;
2517+
STORE_KEY(ep, NULL);
2518+
STORE_VALUE(ep, NULL);
25122519
}
25132520
else {
25142521
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
25152522
old_key = ep->me_key;
2516-
ep->me_key = NULL;
2517-
ep->me_value = NULL;
2518-
ep->me_hash = 0;
2523+
STORE_KEY(ep, NULL);
2524+
STORE_VALUE(ep, NULL);
2525+
STORE_HASH(ep, 0);
25192526
}
25202527
Py_DECREF(old_key);
25212528
}
@@ -4393,8 +4400,8 @@ dict_popitem_impl(PyDictObject *self)
43934400
PyTuple_SET_ITEM(res, 0, key);
43944401
PyTuple_SET_ITEM(res, 1, value);
43954402
/* We can't dk_usable++ since there is DKIX_DUMMY in indices */
4396-
self->ma_keys->dk_nentries = i;
4397-
self->ma_used--;
4403+
STORE_KEYS_NENTRIES(self->ma_keys, i);
4404+
STORE_USED(self, self->ma_used - 1);
43984405
self->ma_version_tag = new_version;
43994406
ASSERT_CONSISTENT(self);
44004407
return res;

0 commit comments

Comments
 (0)
0