@@ -115,19 +115,20 @@ As a consequence of this, split keys have a maximum size of 16.
115
115
#define PyDict_MINSIZE 8
116
116
117
117
#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()
131
132
132
133
#include <stdbool.h>
133
134
@@ -159,7 +160,6 @@ ASSERT_DICT_LOCKED(PyObject *op)
159
160
#define ASSERT_OWNED_OR_SHARED (mp ) \
160
161
assert(_Py_IsOwnedByCurrentThread((PyObject *)mp) || IS_DICT_SHARED(mp));
161
162
#define LOAD_KEYS_NENTRIES (d )
162
- #define DECREMENT (v ) _Py_atomic_add_ssize(&(v), -1)
163
163
164
164
static inline Py_ssize_t
165
165
load_keys_nentries (PyDictObject * mp )
@@ -222,7 +222,6 @@ static inline void split_keys_entry_added(PyDictKeysObject *keys)
222
222
#define SET_DICT_SHARED (mp )
223
223
#define LOAD_INDEX (keys , size , idx ) ((const int##size##_t*)(keys->dk_indices))[idx]
224
224
#define STORE_INDEX (keys , size , idx , value ) ((int##size##_t*)(keys->dk_indices))[idx] = (int##size##_t)value
225
- #define DECREMENT (v ) ((v)--)
226
225
227
226
static inline void split_keys_entry_added (PyDictKeysObject * keys )
228
227
{
@@ -5017,7 +5016,7 @@ dictiter_iternextkey_lock_held(PyDictObject *d, PyObject *self)
5017
5016
return NULL ;
5018
5017
}
5019
5018
5020
- #endif
5019
+ #endif /* Py_GIL_DISABLED */
5021
5020
5022
5021
static PyObject *
5023
5022
dictiter_iternextkey (PyObject * self )
@@ -5140,7 +5139,7 @@ dictiter_iternextvalue_lock_held(PyDictObject *d, PyObject *self)
5140
5139
return NULL ;
5141
5140
}
5142
5141
5143
- #endif
5142
+ #endif /* Py_GIL_DISABLED */
5144
5143
5145
5144
static PyObject *
5146
5145
dictiter_iternextvalue (PyObject * self )
@@ -5213,15 +5212,7 @@ dictiter_iternextitem_lock_held(PyDictObject *d, PyObject *self,
5213
5212
return 0 ;
5214
5213
}
5215
5214
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 );
5225
5216
5226
5217
assert (i >= 0 );
5227
5218
if (_PyDict_HasSplitTable (d )) {
@@ -5263,15 +5254,8 @@ dictiter_iternextitem_lock_held(PyDictObject *d, PyObject *self,
5263
5254
"dictionary keys changed during iteration" );
5264
5255
goto fail ;
5265
5256
}
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
5272
5257
di -> di_pos = i + 1 ;
5273
- #endif
5274
- DECREMENT (di -> len );
5258
+ di -> len -- ;
5275
5259
if (out_key != NULL ) {
5276
5260
* out_key = Py_NewRef (key );
5277
5261
}
0 commit comments