You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Make list, tuple and range iteration more thread-safe, and actually test
concurrent iteration. (This is prep work for enabling specialization of
FOR_ITER in free-threaded builds.) The basic premise is:
- Iterating over a shared _iterable_ (list, tuple or range) should be safe,
not involve data races, and behave like iteration normally does.
- Using a shared _iterator_ should not crash or involve data races, and
should only produce items regular iteration would produce. It is _not_
guaranteed to produce all items, or produce each item only once.
Providing stronger guarantees is possible for some of these iterators, but
it's not always straight-forward and can significantly hamper the common
case. Since iterators in general aren't shared between threads, and it's
simply impossible to concurrently use many iterators (like generators),
better to make sharing iterators without explicit synchronization clearly
wrong.
Specific issues fixed in order to make the tests pass:
- List iteration could occasionally crash when a shared list wasn't already
marked as shared when reallocated.
- Tuple iteration could occasionally crash when the iterator's reference to
the tuple was cleared on exhaustion. Like with list iteration, in
free-threaded builds we can't safely and efficiently clear the iterator's
reference to the iterable (doing it safely would mean extra, slow
refcount operations), so just keep the iterable reference around.
- Fast range iterators (for integers that fit in C longs) shared between
threads would sometimes produce values past the end of the range, because
the iterators use two bits of state that we can't efficiently update
atomically. Rewriting the iterators to have a single bit of state is
possible, but probably means more math for each iteration and may not be
worth it.
- Long range iterators (for other numbers) shared between threads would
crash catastrophically in a variety of ways. This now uses a critical
section. Rewriting this to be more efficient is probably possible, but
since it deals with arbitrary Python objects it's difficult to get right.
There seem to be no more exising races in list_get_item_ref, so drop it from
the tsan suppression list.
0 commit comments