Skip to content

Commit e3c9012

Browse files
committed
Remove "while" loop for setting flags.
We only need the "while" loop if we are setting multiple flag bits concurrently. That's not needed, we only set RELEASED. So, restructure code, no while loop needed and someone can't accidently call the function in the wrong way.
1 parent ab2d602 commit e3c9012

1 file changed

Lines changed: 17 additions & 13 deletions

File tree

‎Objects/memoryobject.c‎

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -104,20 +104,24 @@ _PyManagedBuffer_FromObject(PyObject *base, int flags)
104104
}
105105

106106
static inline int
107-
flags_test_and_set(int *flags, int bit)
107+
flags_set_released(int *flags, int released)
108108
{
109109
#ifdef Py_GIL_DISABLED
110110
int prev = _Py_atomic_load_int_relaxed(flags);
111-
while (!_Py_atomic_compare_exchange_int(flags, &prev, prev | bit)) {
112-
// Compare-exchange updates prev. Note that retries are bounded by the
113-
// number of flag bits being concurrently set. So, yielding here is
114-
// unnecessary.
111+
if (prev & released) {
112+
return 1;
115113
}
114+
if (!_Py_atomic_compare_exchange_int(flags, &prev, prev | released)) {
115+
// RELEASED is the only flag that can change concurrently.
116+
assert(prev & released);
117+
return 1;
118+
}
119+
return 0;
116120
#else
117121
int prev = *flags;
118-
*flags = prev | bit;
122+
*flags = prev | released;
123+
return (prev & released) != 0;
119124
#endif
120-
return (prev & bit) != 0;
121125
}
122126

123127
static inline int
@@ -133,9 +137,9 @@ mv_has_flag(PyMemoryViewObject *mv, int bits)
133137
}
134138

135139
static inline int
136-
mv_set_flag(PyMemoryViewObject *mv, int bit)
140+
mv_set_released(PyMemoryViewObject *mv)
137141
{
138-
return flags_test_and_set(&mv->flags, bit);
142+
return flags_set_released(&mv->flags, _Py_MEMORYVIEW_RELEASED);
139143
}
140144

141145
static inline int
@@ -145,15 +149,15 @@ mbuf_has_flag(_PyManagedBufferObject *mbuf, int bits)
145149
}
146150

147151
static inline int
148-
mbuf_set_flag(_PyManagedBufferObject *mbuf, int bit)
152+
mbuf_set_released(_PyManagedBufferObject *mbuf)
149153
{
150-
return flags_test_and_set(&mbuf->flags, bit);
154+
return flags_set_released(&mbuf->flags, _Py_MANAGED_BUFFER_RELEASED);
151155
}
152156

153157
static void
154158
mbuf_release(_PyManagedBufferObject *self)
155159
{
156-
if (mbuf_set_flag(self, _Py_MANAGED_BUFFER_RELEASED)) {
160+
if (mbuf_set_released(self)) {
157161
return;
158162
}
159163

@@ -1227,7 +1231,7 @@ static void
12271231
_memory_release(PyMemoryViewObject *self)
12281232
{
12291233
assert(get_exports(self) == 0);
1230-
if (mv_set_flag(self, _Py_MEMORYVIEW_RELEASED)) {
1234+
if (mv_set_released(self)) {
12311235
return;
12321236
}
12331237

0 commit comments

Comments
 (0)