8000 Less atomics · python/cpython@cb1f8bd · GitHub
[go: up one dir, main page]

Skip to content

Commit cb1f8bd

Browse files
committed
Less atomics
1 parent 78d8d03 commit cb1f8bd

File tree

1 file changed

+18
-34
lines changed

1 file changed

+18
-34
lines changed

Objects/dictobject.c

Lines changed: 18 additions & 34 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_object.h" // _PyObject_GC_TRACK(), _PyDebugAllocatorStats()
127+
#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_LOAD_SSIZE_RELAXED
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

@@ -159,7 +160,6 @@ ASSERT_DICT_LOCKED(PyObject *op)
159160
#define ASSERT_OWNED_OR_SHARED(mp) \
160161
assert(_Py_IsOwnedByCurrentThread((PyObject *)mp) || IS_DICT_SHARED(mp));
161162
#define LOAD_KEYS_NENTRIES(d)
162-
#define DECREMENT(v) _Py_atomic_add_ssize(&(v), -1)
163163

164164
static inline Py_ssize_t
165165
load_keys_nentries(PyDictObject *mp)
@@ -222,7 +222,6 @@ static inline void split_keys_entry_added(PyDictKeysObject *keys)
222222
#define SET_DICT_SHARED(mp)
223223
#define LOAD_INDEX(keys, size, idx) ((const int##size##_t*)(keys->dk_indices))[idx]
224224
#define STORE_INDEX(keys, size, idx, value) ((int##size##_t*)(keys->dk_indices))[idx] = (int##size##_t)value
225-
#define DECREMENT(v) ((v)--)
226225

227226
static inline void split_keys_entry_added(PyDictKeysObject *keys)
228227
{
@@ -5017,7 +5016,7 @@ dictiter_iternextkey_lock_held(PyDictObject *d, PyObject *self)
50175016
return NULL;
50185017
}
50195018

5020-
#endif
5019+
#endif /* Py_GIL_DISABLED */
50215020

50225021
static PyObject*
50235022
dictiter_iternextkey(PyObject *self)
@@ -5140,7 +5139,7 @@ dictiter_iternextvalue_lock_held(PyDictObject *d, PyObject *self)
51405139
return NULL;
51415140
}
51425141

5143-
#endif
5142+
#endif /* Py_GIL_DISABLED */
51445143

51455144
static PyObject *
51465145
dictiter_iternextvalue(PyObject *self)
@@ -5213,15 +5212,7 @@ dictiter_iternextitem_lock_held(PyDictObject *d, PyObject *self,
52135212
return 0;
52145213
}
52155214

5216-
#ifdef Py_GIL_DISABLED
5217-
Py_ssize_t start_pos;
5218-
// Even though we hold the lock here we may still lose a race against
5219-
// a lock-free iterator, therefore we may end up retrying our iteration.
5220-
retry:
5221-
start_pos = i = _Py_atomic_load_ssize_relaxed(&di->di_pos);
5222-
#else
5223-
i = di->di_pos;
5224-
#endif
5215+
i = FT_ATOMIC_LOAD_SSIZE_RELAXED(di->di_pos);
52255216

52265217
assert(i >= 0);
52275218
if (_PyDict_HasSplitTable(d)) {
@@ -5263,15 +5254,8 @@ dictiter_iternextitem_lock_held(PyDictObject *d, PyObject *self,
52635254
"dictionary keys changed during iteration");
52645255
goto fail;
52655256
}
5266-
#ifdef Py_GIL_DISABLED
5267-
if (!_Py_atomic_compare_exchange_ssize(&di->di_pos, &start_pos, i+1)) {
5268-
// We lost a a race with a lock-free iterator!
5269-
goto retry;
5270-
}
5271-
#else
52725257
di->di_pos = i+1;
5273-
#endif
5274-
DECREMENT(di->len);
5258+
di->len--;
52755259
if (out_key != NULL) {
52765260
*out_key = Py_NewRef(key);
52775261
}

0 commit comments

Comments
 (0)
0