|
6 | 6 | #include "pycore_moduleobject.h" // _PyModule_GetState() |
7 | 7 | #include "pycore_typeobject.h" // _PyType_GetModuleState() |
8 | 8 | #include "pycore_object.h" // _PyObject_GC_TRACK() |
| 9 | +#include "pycore_pyatomic_ft_wrappers.h" // FT_ATOMIC_STORE_SSIZE_RELAXED() |
9 | 10 | #include "pycore_tuple.h" // _PyTuple_ITEMS() |
10 | 11 |
|
11 | 12 | #include <stddef.h> // offsetof() |
@@ -1620,33 +1621,39 @@ islice_next(PyObject *op) |
1620 | 1621 | Py_ssize_t oldnext; |
1621 | 1622 | PyObject *(*iternext)(PyObject *); |
1622 | 1623 |
|
1623 | | - if (it == NULL) |
| 1624 | + Py_ssize_t cnt = FT_ATOMIC_LOAD_SSIZE_RELAXED(lz->cnt); |
| 1625 | + if (cnt < 0) |
1624 | 1626 | return NULL; |
1625 | 1627 |
|
1626 | 1628 | iternext = *Py_TYPE(it)->tp_iternext; |
1627 | | - while (lz->cnt < lz->next) { |
| 1629 | + while (cnt < lz->next) { |
1628 | 1630 | item = iternext(it); |
1629 | 1631 | if (item == NULL) |
1630 | 1632 | goto empty; |
1631 | 1633 | Py_DECREF(item); |
1632 | | - lz->cnt++; |
| 1634 | + cnt++; |
1633 | 1635 | } |
1634 | | - if (stop != -1 && lz->cnt >= stop) |
| 1636 | + if (stop != -1 && cnt >= stop) |
1635 | 1637 | goto empty; |
1636 | 1638 | item = iternext(it); |
1637 | 1639 | if (item == NULL) |
1638 | 1640 | goto empty; |
1639 | | - lz->cnt++; |
1640 | | - oldnext = lz->next; |
| 1641 | + cnt++; |
| 1642 | + FT_ATOMIC_STORE_SSIZE_RELAXED(lz->cnt, cnt); |
| 1643 | + oldnext = FT_ATOMIC_LOAD_SSIZE_RELAXED(lz->next); |
1641 | 1644 | /* The (size_t) cast below avoids the danger of undefined |
1642 | 1645 | behaviour from signed integer overflow. */ |
1643 | | - lz->next += (size_t)lz->step; |
1644 | | - if (lz->next < oldnext || (stop != -1 && lz->next > stop)) |
1645 | | - lz->next = stop; |
| 1646 | + FT_ATOMIC_STORE_SSIZE_RELAXED(lz->next, oldnext + (size_t)lz->step); |
| 1647 | + if (lz->next < oldnext || (stop != -1 && lz->next > stop)) { |
| 1648 | + FT_ATOMIC_STORE_SSIZE_RELAXED(lz->next, stop); |
| 1649 | + } |
1646 | 1650 | return item; |
1647 | 1651 |
|
1648 | 1652 | empty: |
| 1653 | + FT_ATOMIC_STORE_SSIZE_RELAXED(lz->cnt, -1); |
| 1654 | +#ifndef PY_GIL_DISABLED |
1649 | 1655 | Py_CLEAR(lz->it); |
| 1656 | +#endif |
1650 | 1657 | return NULL; |
1651 | 1658 | } |
1652 | 1659 |
|
@@ -3555,7 +3562,7 @@ count_next(PyObject *op) |
3555 | 3562 | PyObject *returned; |
3556 | 3563 | Py_ssize_t cnt; |
3557 | 3564 |
|
3558 | | - cnt = _Py_atomic_load_ssize_relaxed(&lz->cnt); |
| 3565 | + cnt = FT_ATOMIC_LOAD_SSIZE_RELAXED(lz->cnt); |
3559 | 3566 | for (;;) { |
3560 | 3567 | if (cnt == PY_SSIZE_T_MAX) { |
3561 | 3568 | Py_BEGIN_CRITICAL_SECTION(lz); |
|
0 commit comments