Skip to content

Commit 596ceb4

Browse files
committed
Atomic assigns
1 parent b348313 commit 596ceb4

File tree

1 file changed

+39
-31
lines changed

1 file changed

+39
-31
lines changed

Objects/dictobject.c

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,20 @@ As a consequence of this, split keys have a maximum size of 16.
115115
#define PyDict_MINSIZE 8
116116

117117
#include "Python.h"
118-
#include "pycore_bitutils.h" // _Py_bit_length
119-
#include "pycore_call.h" // _PyObject_CallNoArgs()
120-
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
121-
#include "pycore_code.h" // stats
122-
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
123-
#include "pycore_dict.h" // export _PyDict_SizeOf()
124-
#include "pycore_freelist.h" // _PyFreeListState_GET()
125-
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
126-
#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
127-
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
128-
#include "pycore_pystate.h" // _PyThreadState_GET()
129-
#include "pycore_setobject.h" // _PySet_NextEntry()
130-
#include "stringlib/eq.h" // unicode_eq()
118+
#include "pycore_bitutils.h" // _Py_bit_length
119+
#include "pycore_call.h" // _PyObject_CallNoArgs()
120+
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
121+
#include "pycore_code.h" // stats
122+
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
123+
#include "pycore_dict.h" // export _PyDict_SizeOf()
124+
#include "pycore_freelist.h" // _PyFreeListState_GET()
125+
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
126+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED
127+
#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
128+
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
129+
#include "pycore_pystate.h" // _PyThreadState_GET()
130+
#include "pycore_setobject.h" // _PySet_NextEntry()
131+
#include "stringlib/eq.h" // unicode_eq
131132

132133
#include <stdbool.h>
133134

@@ -234,6 +235,14 @@ set_values(PyDictObject *mp, PyDictValues *values)
234235

235236
#endif
236237

238+
#define STORE_KEY(ep, key) FT_ATOMIC_STORE_PTR_RELAXED(ep->me_key, key)
239+
#define STORE_VALUE(ep, value) FT_ATOMIC_STORE_PTR_RELAXED(ep->me_value, value)
240+
#define STORE_SPLIT_VALUE(mp, idx, value) FT_ATOMIC_STORE_PTR_RELAXED(mp->ma_values->values[idx], value)
241+
#define STORE_HASH(ep, hash) FT_ATOMIC_STORE_SSIZE_RELAXED(ep->me_hash, hash)
242+
#define STORE_KEYS_USABLE(keys, usable) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_usable, usable)
243+
#define STORE_KEYS_NENTRIES(keys, nentries) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_nentries, nentries)
244+
#define STORE_USED(mp, used) FT_ATOMIC_STORE_SSIZE_RELAXED(mp->ma_used, used)
245+
237246
#define PERTURB_SHIFT 5
238247

239248
/*
@@ -1605,7 +1614,6 @@ insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
16051614
return ix;
16061615
}
16071616

1608-
16091617
static inline int
16101618
insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
16111619
Py_hash_t hash, PyObject *key, PyObject *value)
@@ -1623,18 +1631,18 @@ insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
16231631
if (DK_IS_UNICODE(mp->ma_keys)) {
16241632
PyDictUnicodeEntry *ep;
16251633
ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1626-
ep->me_key = key;
1627-
ep->me_value = value;
1634+
STORE_KEY(ep, key);
1635+
STORE_VALUE(ep, value);
16281636
}
16291637
else {
16301638
PyDictKeyEntry *ep;
16311639
ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
1632-
ep->me_key = key;
1633-
ep->me_hash = hash;
1634-
ep->me_value = value;
1640+
STORE_KEY(ep, key);
1641+
STORE_VALUE(ep, value);
1642+
STORE_HASH(ep, hash);
16351643
}
1636-
mp->ma_keys->dk_usable--;
1637-
mp->ma_keys->dk_nentries++;
1644+
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - 1);
1645+
STORE_KEYS_NENTRIES(mp->ma_keys, mp->ma_keys->dk_nentries + 1);
16381646
assert(mp->ma_keys->dk_usable >= 0);
16391647
return 0;
16401648
}
@@ -1666,7 +1674,7 @@ insert_split_dict(PyInterpreterState *interp, PyDictObject *mp,
16661674
Py_ssize_t index = keys->dk_nentries;
16671675
_PyDictValues_AddToInsertionOrder(mp->ma_values, index);
16681676
assert (mp->ma_values->values[index] == NULL);
1669-
mp->ma_values->values[index] = value;
1677+
STORE_SPLIT_VALUE(mp, index, value);
16701678

16711679
split_keys_entry_added(keys);
16721680
assert(keys->dk_usable >= 0);
@@ -1997,8 +2005,8 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
19972005
}
19982006
}
19992007

2000-
mp->ma_keys->dk_usable -= numentries;
2001-
mp->ma_keys->dk_nentries = numentries;
2008+
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - numentries);
2009+
STORE_KEYS_NENTRIES(mp->ma_keys, numentries);
20022010
ASSERT_CONSISTENT(mp);
20032011
return 0;
20042012
}
@@ -2491,15 +2499,15 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
24912499
if (DK_IS_UNICODE(mp->ma_keys)) {
24922500
PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
24932501
old_key = ep->me_key;
2494-
ep->me_key = NULL;
2495-
ep->me_value = NULL;
2502+
STORE_KEY(ep, NULL);
2503+
STORE_VALUE(ep, NULL);
24962504
}
24972505
else {
24982506
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
24992507
old_key = ep->me_key;
2500-
ep->me_key = NULL;
2501-
ep->me_value = NULL;
2502-
ep->me_hash = 0;
2508+
STORE_KEY(ep, NULL);
2509+
STORE_VALUE(ep, NULL);
2510+
STORE_HASH(ep, 0);
25032511
}
25042512
Py_DECREF(old_key);
25052513
}
@@ -4377,8 +4385,8 @@ dict_popitem_impl(PyDictObject *self)
43774385
PyTuple_SET_ITEM(res, 0, key);
43784386
PyTuple_SET_ITEM(res, 1, value);
43794387
/* We can't dk_usable++ since there is DKIX_DUMMY in indices */
4380-
self->ma_keys->dk_nentries = i;
4381-
self->ma_used--;
4388+
STORE_KEYS_NENTRIES(self->ma_keys, i);
4389+
STORE_USED(self, self->ma_used - 1);
43824390
self->ma_version_tag = new_version;
43834391
ASSERT_CONSISTENT(self);
43844392
return res;

0 commit comments

Comments
 (0)