Skip to content

Commit

Permalink
Atomic assigns
Browse files Browse the repository at this point in the history
  • Loading branch information
DinoV committed Feb 22, 2024
1 parent b348313 commit 596ceb4
Showing 1 changed file with 39 additions and 31 deletions.
70 changes: 39 additions & 31 deletions Objects/dictobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,20 @@ As a consequence of this, split keys have a maximum size of 16.
#define PyDict_MINSIZE 8

#include "Python.h"
#include "pycore_bitutils.h" // _Py_bit_length
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_code.h" // stats
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
#include "pycore_dict.h" // export _PyDict_SizeOf()
#include "pycore_freelist.h" // _PyFreeListState_GET()
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "stringlib/eq.h" // unicode_eq()
#include "pycore_bitutils.h" // _Py_bit_length
#include "pycore_call.h" // _PyObject_CallNoArgs()
#include "pycore_ceval.h" // _PyEval_GetBuiltin()
#include "pycore_code.h" // stats
#include "pycore_critical_section.h" // Py_BEGIN_CRITICAL_SECTION, Py_END_CRITICAL_SECTION
#include "pycore_dict.h" // export _PyDict_SizeOf()
#include "pycore_freelist.h" // _PyFreeListState_GET()
#include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_PTR_RELAXED
#include "pycore_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
#include "pycore_pyerrors.h" // _PyErr_GetRaisedException()
#include "pycore_pystate.h" // _PyThreadState_GET()
#include "pycore_setobject.h" // _PySet_NextEntry()
#include "stringlib/eq.h" // unicode_eq

#include <stdbool.h>

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

#endif

#define STORE_KEY(ep, key) FT_ATOMIC_STORE_PTR_RELAXED(ep->me_key, key)
#define STORE_VALUE(ep, value) FT_ATOMIC_STORE_PTR_RELAXED(ep->me_value, value)
#define STORE_SPLIT_VALUE(mp, idx, value) FT_ATOMIC_STORE_PTR_RELAXED(mp->ma_values->values[idx], value)
#define STORE_HASH(ep, hash) FT_ATOMIC_STORE_SSIZE_RELAXED(ep->me_hash, hash)
#define STORE_KEYS_USABLE(keys, usable) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_usable, usable)
#define STORE_KEYS_NENTRIES(keys, nentries) FT_ATOMIC_STORE_SSIZE_RELAXED(keys->dk_nentries, nentries)
#define STORE_USED(mp, used) FT_ATOMIC_STORE_SSIZE_RELAXED(mp->ma_used, used)

#define PERTURB_SHIFT 5

/*
Expand Down Expand Up @@ -1605,7 +1614,6 @@ insert_into_splitdictkeys(PyDictKeysObject *keys, PyObject *name)
return ix;
}


static inline int
insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
Py_hash_t hash, PyObject *key, PyObject *value)
Expand All @@ -1623,18 +1631,18 @@ insert_combined_dict(PyInterpreterState *interp, PyDictObject *mp,
if (DK_IS_UNICODE(mp->ma_keys)) {
PyDictUnicodeEntry *ep;
ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
ep->me_key = key;
ep->me_value = value;
STORE_KEY(ep, key);
STORE_VALUE(ep, value);
}
else {
PyDictKeyEntry *ep;
ep = &DK_ENTRIES(mp->ma_keys)[mp->ma_keys->dk_nentries];
ep->me_key = key;
ep->me_hash = hash;
ep->me_value = value;
STORE_KEY(ep, key);
STORE_VALUE(ep, value);
STORE_HASH(ep, hash);
}
mp->ma_keys->dk_usable--;
mp->ma_keys->dk_nentries++;
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - 1);
STORE_KEYS_NENTRIES(mp->ma_keys, mp->ma_keys->dk_nentries + 1);
assert(mp->ma_keys->dk_usable >= 0);
return 0;
}
Expand Down Expand Up @@ -1666,7 +1674,7 @@ insert_split_dict(PyInterpreterState *interp, PyDictObject *mp,
Py_ssize_t index = keys->dk_nentries;
_PyDictValues_AddToInsertionOrder(mp->ma_values, index);
assert (mp->ma_values->values[index] == NULL);
mp->ma_values->values[index] = value;
STORE_SPLIT_VALUE(mp, index, value);

split_keys_entry_added(keys);
assert(keys->dk_usable >= 0);
Expand Down Expand Up @@ -1997,8 +2005,8 @@ dictresize(PyInterpreterState *interp, PyDictObject *mp,
}
}

mp->ma_keys->dk_usable -= numentries;
mp->ma_keys->dk_nentries = numentries;
STORE_KEYS_USABLE(mp->ma_keys, mp->ma_keys->dk_usable - numentries);
STORE_KEYS_NENTRIES(mp->ma_keys, numentries);
ASSERT_CONSISTENT(mp);
return 0;
}
Expand Down Expand Up @@ -2491,15 +2499,15 @@ delitem_common(PyDictObject *mp, Py_hash_t hash, Py_ssize_t ix,
if (DK_IS_UNICODE(mp->ma_keys)) {
PyDictUnicodeEntry *ep = &DK_UNICODE_ENTRIES(mp->ma_keys)[ix];
old_key = ep->me_key;
ep->me_key = NULL;
ep->me_value = NULL;
STORE_KEY(ep, NULL);
STORE_VALUE(ep, NULL);
}
else {
PyDictKeyEntry *ep = &DK_ENTRIES(mp->ma_keys)[ix];
old_key = ep->me_key;
ep->me_key = NULL;
ep->me_value = NULL;
ep->me_hash = 0;
STORE_KEY(ep, NULL);
STORE_VALUE(ep, NULL);
STORE_HASH(ep, 0);
}
Py_DECREF(old_key);
}
Expand Down Expand Up @@ -4377,8 +4385,8 @@ dict_popitem_impl(PyDictObject *self)
PyTuple_SET_ITEM(res, 0, key);
PyTuple_SET_ITEM(res, 1, value);
/* We can't dk_usable++ since there is DKIX_DUMMY in indices */
self->ma_keys->dk_nentries = i;
self->ma_used--;
STORE_KEYS_NENTRIES(self->ma_keys, i);
STORE_USED(self, self->ma_used - 1);
self->ma_version_tag = new_version;
ASSERT_CONSISTENT(self);
return res;
Expand Down

0 comments on commit 596ceb4

Please sign in to comment.