https://github.com/python/cpython/commit/75f38af7810af1c3ca567d6224a975f85aef970f
commit: 75f38af7810af1c3ca567d6224a975f85aef970f
branch: main
author: Sam Gross <colesb...@gmail.com>
committer: colesbury <colesb...@gmail.com>
date: 2025-02-28T16:57:48-05:00
summary:

Revert "gh-128942: make `array` module thread safe (#128943)" (#130707)

The change regressed performance on scimark benchmarks from the
pyperformance benchmark suite.

This reverts commit 8ba0d7bbc295781bf27902380521db97a272c442.

files:
D Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
M Lib/test/test_array.py
M Modules/arraymodule.c
M Modules/clinic/arraymodule.c.h

diff --git a/Lib/test/test_array.py b/Lib/test/test_array.py
index bc3eeef8000190..58ea89c4fac833 100755
--- a/Lib/test/test_array.py
+++ b/Lib/test/test_array.py
@@ -3,21 +3,16 @@
 """
 
 import collections.abc
-import io
 import unittest
 from test import support
 from test.support import import_helper
 from test.support import os_helper
-from test.support import threading_helper
 from test.support import _2G
 import weakref
 import pickle
 import operator
-import random
 import struct
 import sys
-import sysconfig
-import threading
 import warnings
 
 import array
@@ -1678,266 +1673,5 @@ def test_gh_128961(self):
         self.assertRaises(StopIteration, next, it)
 
 
-class FreeThreadingTest(unittest.TestCase):
-    # Test pretty much everything that can break under free-threading.
-    # Non-deterministic, but at least one of these things will fail if
-    # array module is not free-thread safe.
-
-    @unittest.skipUnless(support.Py_GIL_DISABLED, 'this test can only possibly 
fail with GIL disabled')
-    @threading_helper.reap_threads
-    @threading_helper.requires_working_threading()
-    def test_free_threading(self):
-        def pop1(b, a):  # MODIFIES!
-            b.wait()
-            try: a.pop()
-            except IndexError: pass
-
-        def append1(b, a):  # MODIFIES!
-            b.wait()
-            a.append(2)
-
-        def insert1(b, a):  # MODIFIES!
-            b.wait()
-            a.insert(0, 2)
-
-        def extend(b, a):  # MODIFIES!
-            c = array.array('i', [2])
-            b.wait()
-            a.extend(c)
-
-        def extend2(b, a, c):  # MODIFIES!
-            b.wait()
-            a.extend(c)
-
-        def inplace_concat(b, a):  # MODIFIES!
-            c = array.array('i', [2])
-            b.wait()
-            a += c
-
-        def inplace_concat2(b, a, c):  # MODIFIES!
-            b.wait()
-            a += c
-
-        def inplace_repeat2(b, a):  # MODIFIES!
-            b.wait()
-            a *= 2
-
-        def clear(b, a, *args):  # MODIFIES!
-            b.wait()
-            a.clear()
-
-        def clear2(b, a, c):  # MODIFIES c!
-            b.wait()
-            try: c.clear()
-            except BufferError: pass
-
-        def remove1(b, a):  # MODIFIES!
-            b.wait()
-            try: a.remove(1)
-            except ValueError: pass
-
-        def fromunicode(b, a):  # MODIFIES!
-            b.wait()
-            a.fromunicode('test')
-
-        def frombytes(b, a):  # MODIFIES!
-            b.wait()
-            a.frombytes(b'0000')
-
-        def frombytes2(b, a, c):  # MODIFIES!
-            b.wait()
-            a.frombytes(c)
-
-        def fromlist(b, a):  # MODIFIES!
-            n = random.randint(0, 100)
-            b.wait()
-            a.fromlist([2] * n)
-
-        def ass_subscr2(b, a, c):  # MODIFIES!
-            b.wait()
-            a[:] = c
-
-        def ass0(b, a):  # modifies inplace
-            b.wait()
-            try: a[0] = 0
-            except IndexError: pass
-
-        def byteswap(b, a):  # modifies inplace
-            b.wait()
-            a.byteswap()
-
-        def tounicode(b, a):
-            b.wait()
-            a.tounicode()
-
-        def tobytes(b, a):
-            b.wait()
-            a.tobytes()
-
-        def tolist(b, a):
-            b.wait()
-            a.tolist()
-
-        def tofile(b, a):
-            f = io.BytesIO()
-            b.wait()
-            a.tofile(f)
-
-        def reduce_ex2(b, a):
-            b.wait()
-            a.__reduce_ex__(2)
-
-        def reduce_ex3(b, a):
-            b.wait()
-            c = a.__reduce_ex__(3)
-            assert not c[1] or 0xdd not in c[1][3]
-
-        def copy(b, a):
-            b.wait()
-            c = a.__copy__()
-            assert not c or 0xdd not in c
-
-        def repr1(b, a):
-            b.wait()
-            repr(a)
-
-        def repeat2(b, a):
-            b.wait()
-            a * 2
-
-        def count1(b, a):
-            b.wait()
-            a.count(1)
-
-        def index1(b, a):
-            b.wait()
-            try: a.index(1)
-            except ValueError: pass
-
-        def contains1(b, a):
-            b.wait()
-            try: 1 in a
-            except ValueError: pass
-
-        def subscr0(b, a):
-            b.wait()
-            try: a[0]
-            except IndexError: pass
-
-        def concat(b, a):
-            b.wait()
-            a + a
-
-        def concat2(b, a, c):
-            b.wait()
-            a + c
-
-        def richcmplhs(b, a):
-            c = a[:]
-            b.wait()
-            a == c
-
-        def richcmprhs(b, a):
-            c = a[:]
-            b.wait()
-            c == a
-
-        def new(b, a):
-            tc = a.typecode
-            b.wait()
-            array.array(tc, a)
-
-        def repr_(b, a):
-            b.wait()
-            repr(a)
-
-        def irepeat(b, a):  # MODIFIES!
-            b.wait()
-            a *= 2
-
-        def newi(b, l):
-            b.wait()
-            array.array('i', l)
-
-        def fromlistl(b, a, l):  # MODIFIES!
-            b.wait()
-            a.fromlist(l)
-
-        def fromlistlclear(b, a, l):  # MODIFIES LIST!
-            b.wait()
-            l.clear()
-
-        def iter_next(b, a, it):  # MODIFIES ITERATOR!
-            b.wait()
-            list(it)
-
-        def iter_reduce(b, a, it):
-            b.wait()
-            c = it.__reduce__()
-            assert not c[1] or 0xdd not in c[1][0]
-
-        def check(funcs, a=None, *args):
-            if a is None:
-                a = array.array('i', [1])
-
-            barrier = threading.Barrier(len(funcs))
-            threads = []
-
-            for func in funcs:
-                thread = threading.Thread(target=func, args=(barrier, a, 
*args))
-
-                threads.append(thread)
-
-            with threading_helper.start_threads(threads):
-                pass
-
-        check([pop1] * 10)
-        check([pop1] + [subscr0] * 10)
-        check([append1] * 10)
-        check([insert1] * 10)
-        check([pop1] + [index1] * 10)
-        check([pop1] + [contains1] * 10)
-        check([insert1] + [repeat2] * 10)
-        check([pop1] + [repr1] * 10)
-        check([inplace_repeat2] * 10)
-        check([byteswap] * 10)
-        check([insert1] + [clear] * 10)
-        check([pop1] + [count1] * 10)
-        check([remove1] * 10)
-        check([clear] + [copy] * 10, array.array('B', b'0' * 0x400000))
-        check([pop1] + [reduce_ex2] * 10)
-        check([clear] + [reduce_ex3] * 10, array.array('B', b'0' * 0x400000))
-        check([pop1] + [tobytes] * 10)
-        check([pop1] + [tolist] * 10)
-        check([clear, tounicode] * 10, array.array('w', 'a'*10000))
-        check([clear, tofile] * 10, array.array('w', 'a'*10000))
-        check([clear] + [extend] * 10)
-        check([clear] + [inplace_concat] * 10)
-        check([clear] + [concat] * 10, array.array('w', 'a'*10000))
-        check([fromunicode] * 10, array.array('w', 'a'))
-        check([frombytes] * 10)
-        check([fromlist] * 10)
-        check([clear] + [richcmplhs] * 10, array.array('i', [1]*10000))
-        check([clear] + [richcmprhs] * 10, array.array('i', [1]*10000))
-        check([clear, ass0] * 10, array.array('i', [1]*10000))  # to test 
array_ass_item must disable Py_mp_ass_subscript
-        check([clear] + [new] * 10, array.array('w', 'a'*10000))
-        check([clear] + [repr_] * 10, array.array('B', b'0' * 0x40000))
-        check([clear] + [repr_] * 10, array.array('B', b'0' * 0x40000))
-        check([clear] + [irepeat] * 10, array.array('B', b'0' * 0x40000))
-        check([clear] + [iter_reduce] * 10, a := array.array('B', b'0' * 
0x400), iter(a))
-
-        # make sure we handle non-self objects correctly
-        check([clear] + [newi] * 10, [2] * random.randint(0, 100))
-        check([fromlistlclear] + [fromlistl] * 10, array.array('i', [1]), [2] 
* random.randint(0, 100))
-        check([clear2] + [concat2] * 10, array.array('w', 'a'*10000), 
array.array('w', 'a'*10000))
-        check([clear2] + [inplace_concat2] * 10, array.array('w', 'a'*10000), 
array.array('w', 'a'*10000))
-        check([clear2] + [extend2] * 10, array.array('w', 'a'*10000), 
array.array('w', 'a'*10000))
-        check([clear2] + [ass_subscr2] * 10, array.array('w', 'a'*10000), 
array.array('w', 'a'*10000))
-        check([clear2] + [frombytes2] * 10, array.array('w', 'a'*10000), 
array.array('B', b'a'*10000))
-
-        # iterator stuff
-        check([clear] + [iter_next] * 10, a := array.array('i', [1] * 10), 
iter(a))
-
-
 if __name__ == "__main__":
     unittest.main()
diff --git 
a/Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst 
b/Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
deleted file mode 100644
index 2b5eb581f1ffa1..00000000000000
--- a/Misc/NEWS.d/next/Library/2025-01-17-13-53-32.gh-issue-128942.DxzaIg.rst
+++ /dev/null
@@ -1 +0,0 @@
-Make the :mod:`array` module safe under :term:`free threading`.
diff --git a/Modules/arraymodule.c b/Modules/arraymodule.c
index 0775b26e1d68ed..5b86ec98393e48 100644
--- a/Modules/arraymodule.c
+++ b/Modules/arraymodule.c
@@ -13,7 +13,6 @@
 #include "pycore_ceval.h"         // _PyEval_GetBuiltin()
 #include "pycore_modsupport.h"    // _PyArg_NoKeywords()
 #include "pycore_moduleobject.h"  // _PyModule_GetState()
-#include "pycore_pyatomic_ft_wrappers.h"
 
 #include <stddef.h>               // offsetof()
 #include <stdbool.h>
@@ -69,19 +68,6 @@ typedef struct {
     PyObject *str_iter;
 } array_state;
 
-static inline Py_ssize_t Pyarrayobject_GET_SIZE(PyObject *op) {
-    arrayobject *ao = (arrayobject *)op;
-#ifdef Py_GIL_DISABLED
-    return _Py_atomic_load_ssize_relaxed(&(_PyVarObject_CAST(ao)->ob_size));
-#else
-    return Py_SIZE(ao);
-#endif
-}
-#define Pyarrayobject_GET_SIZE(op) Pyarrayobject_GET_SIZE(_PyObject_CAST(op))
-
-/* Forward declaration. */
-static PyObject *array_array_frombytes(PyObject *self, PyObject *bytes);
-
 static array_state *
 get_array_state(PyObject *module)
 {
@@ -147,7 +133,6 @@ enum machine_format_code {
 static int
 array_resize(arrayobject *self, Py_ssize_t newsize)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
     char *items;
     size_t _new_size;
 
@@ -173,7 +158,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
         PyMem_Free(self->ob_item);
         self->ob_item = NULL;
         Py_SET_SIZE(self, 0);
-        FT_ATOMIC_STORE_SSIZE_RELAXED(self->allocated, 0);
+        self->allocated = 0;
         return 0;
     }
 
@@ -203,7 +188,7 @@ array_resize(arrayobject *self, Py_ssize_t newsize)
     }
     self->ob_item = items;
     Py_SET_SIZE(self, newsize);
-    FT_ATOMIC_STORE_SSIZE_RELAXED(self->allocated, _new_size);
+    self->allocated = _new_size;
     return 0;
 }
 
@@ -687,7 +672,6 @@ newarrayobject(PyTypeObject *type, Py_ssize_t size, const 
struct arraydescr *des
 static PyObject *
 getarrayitem(PyObject *op, Py_ssize_t i)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
 #ifndef NDEBUG
     array_state *state = find_array_state_by_type(Py_TYPE(op));
     assert(array_Check(op, state));
@@ -701,7 +685,6 @@ getarrayitem(PyObject *op, Py_ssize_t i)
 static int
 ins1(arrayobject *self, Py_ssize_t where, PyObject *v)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
     char *items;
     Py_ssize_t n = Py_SIZE(self);
     if (v == NULL) {
@@ -745,11 +728,6 @@ array_dealloc(PyObject *op)
     PyObject_GC_UnTrack(op);
 
     arrayobject *self = arrayobject_CAST(op);
-    if (self->ob_exports > 0) {
-        PyErr_SetString(PyExc_SystemError,
-                        "deallocated array object has exported buffers");
-        PyErr_Print();
-    }
     if (self->weakreflist != NULL) {
         PyObject_ClearWeakRefs(op);
     }
@@ -761,10 +739,8 @@ array_dealloc(PyObject *op)
 }
 
 static PyObject *
-array_richcompare_lock_held(PyObject *v, PyObject *w, int op)
+array_richcompare(PyObject *v, PyObject *w, int op)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(v);
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(w);
     array_state *state = find_array_state_by_type(Py_TYPE(v));
     arrayobject *va, *wa;
     PyObject *vi = NULL;
@@ -872,27 +848,15 @@ array_richcompare_lock_held(PyObject *v, PyObject *w, int 
op)
     return res;
 }
 
-static PyObject *
-array_richcompare(PyObject *v, PyObject *w, int op)
-{
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION2(v, w);
-    ret = array_richcompare_lock_held(v, w, op);
-    Py_END_CRITICAL_SECTION2();
-    return ret;
-}
-
 static Py_ssize_t
 array_length(PyObject *op)
 {
-    arrayobject *self = arrayobject_CAST(op);
-    return Pyarrayobject_GET_SIZE(self);
+    return Py_SIZE(op);
 }
 
 static PyObject *
-array_item_lock_held(PyObject *op, Py_ssize_t i)
+array_item(PyObject *op, Py_ssize_t i)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     if (i < 0 || i >= Py_SIZE(op)) {
         PyErr_SetString(PyExc_IndexError, "array index out of range");
         return NULL;
@@ -900,20 +864,9 @@ array_item_lock_held(PyObject *op, Py_ssize_t i)
     return getarrayitem(op, i);
 }
 
-static PyObject *
-array_item(PyObject *op, Py_ssize_t i)
-{
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_item_lock_held(op, i);
-    Py_END_CRITICAL_SECTION();
-    return ret;
-}
-
 static PyObject *
 array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(a);
     array_state *state = find_array_state_by_type(Py_TYPE(a));
     arrayobject *np;
 
@@ -938,7 +891,6 @@ array_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t 
ihigh)
 }
 
 /*[clinic input]
-@critical_section
 array.array.clear
 
 Remove all items from the array.
@@ -946,7 +898,7 @@ Remove all items from the array.
 
 static PyObject *
 array_array_clear_impl(arrayobject *self)
-/*[clinic end generated code: output=5efe0417062210a9 input=1c9dfcc80f5b6731]*/
+/*[clinic end generated code: output=5efe0417062210a9 input=5dffa30e94e717a4]*/
 {
     if (array_resize(self, 0) == -1) {
         return NULL;
@@ -955,7 +907,6 @@ array_array_clear_impl(arrayobject *self)
 }
 
 /*[clinic input]
-@critical_section
 array.array.__copy__
 
 Return a copy of the array.
@@ -963,13 +914,12 @@ Return a copy of the array.
 
 static PyObject *
 array_array___copy___impl(arrayobject *self)
-/*[clinic end generated code: output=dec7c3f925d9619e input=7622f8f9489472d5]*/
+/*[clinic end generated code: output=dec7c3f925d9619e input=ad1ee5b086965f09]*/
 {
     return array_slice(self, 0, Py_SIZE(self));
 }
 
 /*[clinic input]
-@critical_section
 array.array.__deepcopy__
 
     unused: object
@@ -979,17 +929,15 @@ Return a copy of the array.
 [clinic start generated code]*/
 
 static PyObject *
-array_array___deepcopy___impl(arrayobject *self, PyObject *unused)
-/*[clinic end generated code: output=703b4c412feaaf31 input=1a29f718f5b8a1dc]*/
+array_array___deepcopy__(arrayobject *self, PyObject *unused)
+/*[clinic end generated code: output=1ec748d8e14a9faa input=2405ecb4933748c4]*/
 {
     return array_array___copy___impl(self);
 }
 
 static PyObject *
-array_concat_lock_held(PyObject *op, PyObject *bb)
+array_concat(PyObject *op, PyObject *bb)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(bb);
     arrayobject *a = arrayobject_CAST(op);
     array_state *state = find_array_state_by_type(Py_TYPE(a));
     Py_ssize_t size;
@@ -1025,19 +973,8 @@ array_concat_lock_held(PyObject *op, PyObject *bb)
 }
 
 static PyObject *
-array_concat(PyObject *op, PyObject *bb)
-{
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION2(op, bb);
-    ret = array_concat_lock_held(op, bb);
-    Py_END_CRITICAL_SECTION2();
-    return ret;
-}
-
-static PyObject *
-array_repeat_lock_held(PyObject *op, Py_ssize_t n)
+array_repeat(PyObject *op, Py_ssize_t n)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     arrayobject *a = arrayobject_CAST(op);
     array_state *state = find_array_state_by_type(Py_TYPE(a));
 
@@ -1061,20 +998,9 @@ array_repeat_lock_held(PyObject *op, Py_ssize_t n)
     return (PyObject *)np;
 }
 
-static PyObject *
-array_repeat(PyObject *op, Py_ssize_t n)
-{
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_repeat_lock_held(op, n);
-    Py_END_CRITICAL_SECTION();
-    return ret;
-}
-
 static int
 array_del_slice(arrayobject *a, Py_ssize_t ilow, Py_ssize_t ihigh)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(a);
     char *item;
     Py_ssize_t d; /* Change in size */
     if (ilow < 0)
@@ -1108,9 +1034,8 @@ array_del_slice(arrayobject *a, Py_ssize_t ilow, 
Py_ssize_t ihigh)
 }
 
 static int
-setarrayitem(PyObject *op, Py_ssize_t i, PyObject *v)
+array_ass_item(PyObject *op, Py_ssize_t i, PyObject *v)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     arrayobject *a = arrayobject_CAST(op);
     if (i < 0 || i >= Py_SIZE(a)) {
         PyErr_SetString(PyExc_IndexError,
@@ -1123,20 +1048,18 @@ setarrayitem(PyObject *op, Py_ssize_t i, PyObject *v)
 }
 
 static int
-array_ass_item(PyObject *op, Py_ssize_t i, PyObject *v)
+setarrayitem(PyObject *a, Py_ssize_t i, PyObject *v)
 {
-    int ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = setarrayitem(op, i, v);
-    Py_END_CRITICAL_SECTION();
-    return ret;
+#ifndef NDEBUG
+    array_state *state = find_array_state_by_type(Py_TYPE(a));
+    assert(array_Check(a, state));
+#endif
+    return array_ass_item(a, i, v);
 }
 
 static int
 array_iter_extend(arrayobject *self, PyObject *bb)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(bb);
     PyObject *it, *v;
 
     it = PyObject_GetIter(bb);
@@ -1158,10 +1081,8 @@ array_iter_extend(arrayobject *self, PyObject *bb)
 }
 
 static int
-array_do_extend_lock_held(array_state *state, arrayobject *self, PyObject *bb)
+array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(self);
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(bb);
     Py_ssize_t size, oldsize, bbsize;
 
     if (!array_Check(bb, state))
@@ -1192,16 +1113,6 @@ array_do_extend_lock_held(array_state *state, 
arrayobject *self, PyObject *bb)
 #undef b
 }
 
-static int
-array_do_extend(array_state *state, arrayobject *self, PyObject *bb)
-{
-    int ret;
-    Py_BEGIN_CRITICAL_SECTION2(self, bb);
-    ret = array_do_extend_lock_held(state, self, bb);
-    Py_END_CRITICAL_SECTION2();
-    return ret;
-}
-
 static PyObject *
 array_inplace_concat(PyObject *op, PyObject *bb)
 {
@@ -1220,9 +1131,8 @@ array_inplace_concat(PyObject *op, PyObject *bb)
 }
 
 static PyObject *
-array_inplace_repeat_lock_held(PyObject *op, Py_ssize_t n)
+array_inplace_repeat(PyObject *op, Py_ssize_t n)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     arrayobject *self = arrayobject_CAST(op);
     const Py_ssize_t array_size = Py_SIZE(self);
 
@@ -1245,19 +1155,16 @@ array_inplace_repeat_lock_held(PyObject *op, Py_ssize_t 
n)
     return Py_NewRef(self);
 }
 
+
 static PyObject *
-array_inplace_repeat(PyObject *op, Py_ssize_t n)
+ins(arrayobject *self, Py_ssize_t where, PyObject *v)
 {
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_inplace_repeat_lock_held(op, n);
-    Py_END_CRITICAL_SECTION();
-    return ret;
+    if (ins1(self, where, v) != 0)
+        return NULL;
+    Py_RETURN_NONE;
 }
 
-
 /*[clinic input]
-@critical_section
 array.array.count
 
     v: object
@@ -1267,8 +1174,8 @@ Return number of occurrences of v in the array.
 [clinic start generated code]*/
 
 static PyObject *
-array_array_count_impl(arrayobject *self, PyObject *v)
-/*[clinic end generated code: output=93ead26a2affb739 input=c12c0042c1d0e27e]*/
+array_array_count(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=3dd3624bf7135a3a input=d9bce9d65e39d1f5]*/
 {
     Py_ssize_t count = 0;
     Py_ssize_t i;
@@ -1292,7 +1199,6 @@ array_array_count_impl(arrayobject *self, PyObject *v)
 
 
 /*[clinic input]
-@critical_section
 array.array.index
 
     v: object
@@ -1308,7 +1214,7 @@ Raise ValueError if the value is not present.
 static PyObject *
 array_array_index_impl(arrayobject *self, PyObject *v, Py_ssize_t start,
                        Py_ssize_t stop)
-/*[clinic end generated code: output=c45e777880c99f52 input=fa32ac8ec22175d6]*/
+/*[clinic end generated code: output=c45e777880c99f52 input=089dff7baa7e5a7e]*/
 {
     if (start < 0) {
         start += Py_SIZE(self);
@@ -1341,34 +1247,22 @@ array_array_index_impl(arrayobject *self, PyObject *v, 
Py_ssize_t start,
 }
 
 static int
-array_contains_lock_held(PyObject *op, PyObject *v)
+array_contains(PyObject *self, PyObject *v)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     Py_ssize_t i;
     int cmp;
 
-    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(op); i++) {
-        PyObject *opi = getarrayitem(op, i);
-        if (opi == NULL)
+    for (i = 0, cmp = 0 ; cmp == 0 && i < Py_SIZE(self); i++) {
+        PyObject *selfi = getarrayitem(self, i);
+        if (selfi == NULL)
             return -1;
-        cmp = PyObject_RichCompareBool(opi, v, Py_EQ);
-        Py_DECREF(opi);
+        cmp = PyObject_RichCompareBool(selfi, v, Py_EQ);
+        Py_DECREF(selfi);
     }
     return cmp;
 }
 
-static int
-array_contains(PyObject *op, PyObject *v)
-{
-    int ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_contains_lock_held(op, v);
-    Py_END_CRITICAL_SECTION();
-    return ret;
-}
-
 /*[clinic input]
-@critical_section
 array.array.remove
 
     v: object
@@ -1378,8 +1272,8 @@ Remove the first occurrence of v in the array.
 [clinic start generated code]*/
 
 static PyObject *
-array_array_remove_impl(arrayobject *self, PyObject *v)
-/*[clinic end generated code: output=f2a24e288ecb2a35 input=78bef3fd40e62f7a]*/
+array_array_remove(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=bef06be9fdf9dceb input=0b1e5aed25590027]*/
 {
     Py_ssize_t i;
 
@@ -1405,7 +1299,6 @@ array_array_remove_impl(arrayobject *self, PyObject *v)
 }
 
 /*[clinic input]
-@critical_section
 array.array.pop
 
     i: Py_ssize_t = -1
@@ -1418,7 +1311,7 @@ i defaults to -1.
 
 static PyObject *
 array_array_pop_impl(arrayobject *self, Py_ssize_t i)
-/*[clinic end generated code: output=bc1f0c54fe5308e4 input=c69a7f1f8c570e2f]*/
+/*[clinic end generated code: output=bc1f0c54fe5308e4 input=8e5feb4c1a11cd44]*/
 {
     PyObject *v;
 
@@ -1465,7 +1358,6 @@ array_array_extend_impl(arrayobject *self, PyTypeObject 
*cls, PyObject *bb)
 }
 
 /*[clinic input]
-@critical_section
 array.array.insert
 
     i: Py_ssize_t
@@ -1477,15 +1369,12 @@ Insert a new item v into the array before position i.
 
 static PyObject *
 array_array_insert_impl(arrayobject *self, Py_ssize_t i, PyObject *v)
-/*[clinic end generated code: output=5a3648e278348564 input=3c922bbd81462978]*/
+/*[clinic end generated code: output=5a3648e278348564 input=5577d1b4383e9313]*/
 {
-    if (ins1(self, i, v) != 0)
-        return NULL;
-    Py_RETURN_NONE;
+    return ins(self, i, v);
 }
 
 /*[clinic input]
-@critical_section
 array.array.buffer_info
 
 Return a tuple (address, length) giving the current memory address and the 
length in items of the buffer used to hold array's contents.
@@ -1496,7 +1385,7 @@ the buffer length in bytes.
 
 static PyObject *
 array_array_buffer_info_impl(arrayobject *self)
-/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=9d0dc1ff0e6542e8]*/
+/*[clinic end generated code: output=9b2a4ec3ae7e98e7 input=a58bae5c6e1ac6a6]*/
 {
     PyObject *retval = NULL, *v;
 
@@ -1522,7 +1411,6 @@ array_array_buffer_info_impl(arrayobject *self)
 }
 
 /*[clinic input]
-@critical_section
 array.array.append
 
     v: object
@@ -1532,16 +1420,13 @@ Append new value v to the end of the array.
 [clinic start generated code]*/
 
 static PyObject *
-array_array_append_impl(arrayobject *self, PyObject *v)
-/*[clinic end generated code: output=2f1e8cbad70c2a8b input=9cdd897c66a40c3f]*/
+array_array_append(arrayobject *self, PyObject *v)
+/*[clinic end generated code: output=745a0669bf8db0e2 input=0b98d9d78e78f0fa]*/
 {
-    if (ins1(self, Py_SIZE(self), v) != 0)
-        return NULL;
-    Py_RETURN_NONE;
+    return ins(self, Py_SIZE(self), v);
 }
 
 /*[clinic input]
-@critical_section
 array.array.byteswap
 
 Byteswap all items of the array.
@@ -1552,7 +1437,7 @@ raised.
 
 static PyObject *
 array_array_byteswap_impl(arrayobject *self)
-/*[clinic end generated code: output=5f8236cbdf0d90b5 input=e691b6eff94d8b2e]*/
+/*[clinic end generated code: output=5f8236cbdf0d90b5 input=6a85591b950a0186]*/
 {
     char *p;
     Py_ssize_t i;
@@ -1602,7 +1487,6 @@ array_array_byteswap_impl(arrayobject *self)
 }
 
 /*[clinic input]
-@critical_section
 array.array.reverse
 
 Reverse the order of the items in the array.
@@ -1610,7 +1494,7 @@ Reverse the order of the items in the array.
 
 static PyObject *
 array_array_reverse_impl(arrayobject *self)
-/*[clinic end generated code: output=c04868b36f6f4089 input=e3947e98aed068ed]*/
+/*[clinic end generated code: output=c04868b36f6f4089 input=cd904f01b27d966a]*/
 {
     Py_ssize_t itemsize = self->ob_descr->itemsize;
     char *p, *q;
@@ -1700,7 +1584,6 @@ array_array_fromfile_impl(arrayobject *self, PyTypeObject 
*cls, PyObject *f,
 }
 
 /*[clinic input]
-@critical_section
 array.array.tofile
 
     cls: defining_class
@@ -1712,7 +1595,7 @@ Write all items (as machine values) to the file object f.
 
 static PyObject *
 array_array_tofile_impl(arrayobject *self, PyTypeObject *cls, PyObject *f)
-/*[clinic end generated code: output=4560c628d9c18bc2 input=a26bc66df57864dd]*/
+/*[clinic end generated code: output=4560c628d9c18bc2 input=5a24da7a7b407b52]*/
 {
     Py_ssize_t nbytes = Py_SIZE(self) * self->ob_descr->itemsize;
     /* Write 64K blocks at a time */
@@ -1745,12 +1628,11 @@ array_array_tofile_impl(arrayobject *self, PyTypeObject 
*cls, PyObject *f)
         Py_DECREF(res); /* drop write result */
     }
 
-done:
+  done:
     Py_RETURN_NONE;
 }
 
 /*[clinic input]
-@critical_section self list
 array.array.fromlist
 
     list: object
@@ -1760,8 +1642,8 @@ Append items to array from list.
 [clinic start generated code]*/
 
 static PyObject *
-array_array_fromlist_impl(arrayobject *self, PyObject *list)
-/*[clinic end generated code: output=6c23733a68dd68df input=c7c056aaf85d997a]*/
+array_array_fromlist(arrayobject *self, PyObject *list)
+/*[clinic end generated code: output=26411c2d228a3e3f input=be2605a96c49680f]*/
 {
     Py_ssize_t n;
 
@@ -1794,7 +1676,6 @@ array_array_fromlist_impl(arrayobject *self, PyObject 
*list)
 }
 
 /*[clinic input]
-@critical_section
 array.array.tolist
 
 Convert array to an ordinary list with the same items.
@@ -1802,7 +1683,7 @@ Convert array to an ordinary list with the same items.
 
 static PyObject *
 array_array_tolist_impl(arrayobject *self)
-/*[clinic end generated code: output=00b60cc9eab8ef89 input=4543fdbac475c52c]*/
+/*[clinic end generated code: output=00b60cc9eab8ef89 input=a8d7784a94f86b53]*/
 {
     PyObject *list = PyList_New(Py_SIZE(self));
     Py_ssize_t i;
@@ -1822,29 +1703,19 @@ array_array_tolist_impl(arrayobject *self)
     return NULL;
 }
 
-
-/*[clinic input]
-@critical_section
-array.array.frombytes
-
-    buffer: Py_buffer
-    /
-
-Appends items from the string, interpreting it as an array of machine values, 
as if it had been read from a file using the fromfile() method.
-[clinic start generated code]*/
-
 static PyObject *
-array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
-/*[clinic end generated code: output=d9842c8f7510a516 input=2245f9ea58579960]*/
+frombytes(arrayobject *self, Py_buffer *buffer)
 {
     int itemsize = self->ob_descr->itemsize;
     Py_ssize_t n;
     if (buffer->itemsize != 1) {
+        PyBuffer_Release(buffer);
         PyErr_SetString(PyExc_TypeError, "a bytes-like object is required");
         return NULL;
     }
     n = buffer->len;
     if (n % itemsize != 0) {
+        PyBuffer_Release(buffer);
         PyErr_SetString(PyExc_ValueError,
                    "bytes length not a multiple of item size");
         return NULL;
@@ -1854,19 +1725,37 @@ array_array_frombytes_impl(arrayobject *self, Py_buffer 
*buffer)
         Py_ssize_t old_size = Py_SIZE(self);
         if ((n > PY_SSIZE_T_MAX - old_size) ||
             ((old_size + n) > PY_SSIZE_T_MAX / itemsize)) {
+                PyBuffer_Release(buffer);
                 return PyErr_NoMemory();
         }
         if (array_resize(self, old_size + n) == -1) {
+            PyBuffer_Release(buffer);
             return NULL;
         }
         memcpy(self->ob_item + old_size * itemsize,
             buffer->buf, n * itemsize);
     }
+    PyBuffer_Release(buffer);
     Py_RETURN_NONE;
 }
 
 /*[clinic input]
-@critical_section
+array.array.frombytes
+
+    buffer: Py_buffer
+    /
+
+Appends items from the string, interpreting it as an array of machine values, 
as if it had been read from a file using the fromfile() method.
+[clinic start generated code]*/
+
+static PyObject *
+array_array_frombytes_impl(arrayobject *self, Py_buffer *buffer)
+/*[clinic end generated code: output=d9842c8f7510a516 input=378db226dfac949e]*/
+{
+    return frombytes(self, buffer);
+}
+
+/*[clinic input]
 array.array.tobytes
 
 Convert the array to an array of machine values and return the bytes 
representation.
@@ -1874,7 +1763,7 @@ Convert the array to an array of machine values and 
return the bytes representat
 
 static PyObject *
 array_array_tobytes_impl(arrayobject *self)
-/*[clinic end generated code: output=87318e4edcdc2bb6 input=c4d44d5499d2320f]*/
+/*[clinic end generated code: output=87318e4edcdc2bb6 input=90ee495f96de34f5]*/
 {
     if (Py_SIZE(self) <= PY_SSIZE_T_MAX / self->ob_descr->itemsize) {
         return PyBytes_FromStringAndSize(self->ob_item,
@@ -1885,7 +1774,6 @@ array_array_tobytes_impl(arrayobject *self)
 }
 
 /*[clinic input]
-@critical_section
 array.array.fromunicode
 
     ustr: unicode
@@ -1900,7 +1788,7 @@ some other type.
 
 static PyObject *
 array_array_fromunicode_impl(arrayobject *self, PyObject *ustr)
-/*[clinic end generated code: output=24359f5e001a7f2b input=01e2a776cee82011]*/
+/*[clinic end generated code: output=24359f5e001a7f2b input=025db1fdade7a4ce]*/
 {
     int typecode = self->ob_descr->typecode;
     if (typecode != 'u' && typecode != 'w') {
@@ -1948,7 +1836,6 @@ array_array_fromunicode_impl(arrayobject *self, PyObject 
*ustr)
 }
 
 /*[clinic input]
-@critical_section
 array.array.tounicode
 
 Extends this array with data from the unicode string ustr.
@@ -1960,7 +1847,7 @@ unicode string from an array of some other type.
 
 static PyObject *
 array_array_tounicode_impl(arrayobject *self)
-/*[clinic end generated code: output=08e442378336e1ef input=6c69dfe81a279b91]*/
+/*[clinic end generated code: output=08e442378336e1ef input=127242eebe70b66d]*/
 {
     int typecode = self->ob_descr->typecode;
     if (typecode != 'u' && typecode != 'w') {
@@ -1989,8 +1876,7 @@ array_array___sizeof___impl(arrayobject *self)
 /*[clinic end generated code: output=d8e1c61ebbe3eaed input=805586565bf2b3c6]*/
 {
     size_t res = _PyObject_SIZE(Py_TYPE(self));
-    res += (size_t)FT_ATOMIC_LOAD_SSIZE_RELAXED(self->allocated)
-        * (size_t)self->ob_descr->itemsize;
+    res += (size_t)self->allocated * (size_t)self->ob_descr->itemsize;
     return PyLong_FromSize_t(res);
 }
 
@@ -2385,7 +2271,6 @@ array__array_reconstructor_impl(PyObject *module, 
PyTypeObject *arraytype,
 }
 
 /*[clinic input]
-@critical_section
 array.array.__reduce_ex__
 
     cls: defining_class
@@ -2398,7 +2283,7 @@ Return state information for pickling.
 static PyObject *
 array_array___reduce_ex___impl(arrayobject *self, PyTypeObject *cls,
                                PyObject *value)
-/*[clinic end generated code: output=4958ee5d79452ad5 input=18c90a4cad7ac527]*/
+/*[clinic end generated code: output=4958ee5d79452ad5 input=19968cf0f91d3eea]*/
 {
     PyObject *dict;
     PyObject *result;
@@ -2526,9 +2411,8 @@ static PyMethodDef array_methods[] = {
 };
 
 static PyObject *
-array_repr_lock_held(PyObject *op)
+array_repr(PyObject *op)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     char typecode;
     PyObject *s, *v = NULL;
     Py_ssize_t len;
@@ -2554,20 +2438,9 @@ array_repr_lock_held(PyObject *op)
     return s;
 }
 
-static PyObject *
-array_repr(PyObject *op)
-{
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_repr_lock_held(op);
-    Py_END_CRITICAL_SECTION();
-    return ret;
-}
-
 static PyObject*
-array_subscr_lock_held(PyObject *op, PyObject *item)
+array_subscr(PyObject *op, PyObject *item)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
     arrayobject *self = arrayobject_CAST(op);
     array_state *state = find_array_state_by_type(Py_TYPE(self));
 
@@ -2629,28 +2502,12 @@ array_subscr_lock_held(PyObject *op, PyObject *item)
     }
 }
 
-static PyObject *
-array_subscr(PyObject *op, PyObject *item)
-{
-    PyObject *ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_subscr_lock_held(op, item);
-    Py_END_CRITICAL_SECTION();
-    return ret;
-}
-
 static int
-array_ass_subscr_lock_held(PyObject *op, PyObject* item, PyObject* value)
+array_ass_subscr(PyObject *op, PyObject *item, PyObject *value)
 {
-    array_state* state = find_array_state_by_type(Py_TYPE(op));
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
-#ifdef Py_DEBUG
-    if (value != NULL && array_Check(value, state)) {
-        _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(value);
-    }
-#endif
-    arrayobject *self = arrayobject_CAST(op);
     Py_ssize_t start, stop, step, slicelength, needed;
+    arrayobject *self = arrayobject_CAST(op);
+    array_state* state = find_array_state_by_type(Py_TYPE(self));
     arrayobject* other;
     int itemsize;
 
@@ -2701,7 +2558,7 @@ array_ass_subscr_lock_held(PyObject *op, PyObject* item, 
PyObject* value)
             value = array_slice(other, 0, needed);
             if (value == NULL)
                 return -1;
-            ret = array_ass_subscr_lock_held(op, item, value);
+            ret = array_ass_subscr(op, item, value);
             Py_DECREF(value);
             return ret;
         }
@@ -2804,38 +2661,19 @@ array_ass_subscr_lock_held(PyObject *op, PyObject* 
item, PyObject* value)
     }
 }
 
-static int
-array_ass_subscr(PyObject *op, PyObject* item, PyObject* value)
-{
-    int ret;
-    array_state* state = find_array_state_by_type(Py_TYPE(op));
-    if (value != NULL && array_Check(value, state)) {
-        Py_BEGIN_CRITICAL_SECTION2(op, value);
-        ret = array_ass_subscr_lock_held(op, item, value);
-        Py_END_CRITICAL_SECTION2();
-    }
-    else {
-        Py_BEGIN_CRITICAL_SECTION(op);
-        ret = array_ass_subscr_lock_held(op, item, value);
-        Py_END_CRITICAL_SECTION();
-    }
-    return ret;
-}
-
 static const void *emptybuf = "";
 
 
 static int
-array_buffer_getbuf_lock_held(PyObject *op, Py_buffer *view, int flags)
+array_buffer_getbuf(PyObject *op, Py_buffer *view, int flags)
 {
-    _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op);
-    arrayobject *self = arrayobject_CAST(op);
     if (view == NULL) {
         PyErr_SetString(PyExc_BufferError,
             "array_buffer_getbuf: view==NULL argument is obsolete");
         return -1;
     }
 
+    arrayobject *self = arrayobject_CAST(op);
     view->buf = (void *)self->ob_item;
     view->obj = Py_NewRef(self);
     if (view->buf == NULL)
@@ -2867,39 +2705,61 @@ array_buffer_getbuf_lock_held(PyObject *op, Py_buffer 
*view, int flags)
     return 0;
 }
 
-static int
-array_buffer_getbuf(PyObject *op, Py_buffer *view, int flags)
-{
-    int ret;
-    Py_BEGIN_CRITICAL_SECTION(op);
-    ret = array_buffer_getbuf_lock_held(op, view, flags);
-    Py_END_CRITICAL_SECTION();
-    return ret;
-}
-
 static void
 array_buffer_relbuf(PyObject *op, Py_buffer *Py_UNUSED(view))
 {
-    Py_BEGIN_CRITICAL_SECTION(op);
     arrayobject *self = arrayobject_CAST(op);
     self->ob_exports--;
-    assert(self->ob_exports >= 0);
-    Py_END_CRITICAL_SECTION();
 }
 
 static PyObject *
-array_new_internal_lock_held(PyTypeObject *type, PyObject *initial, int c)
+array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 {
-#ifdef Py_DEBUG
-    if (initial != NULL) {
-        _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(initial);
-    }
-#endif
     array_state *state = find_array_state_by_type(type);
-    PyObject *it = NULL;
+    int c;
+    PyObject *initial = NULL, *it = NULL;
     const struct arraydescr *descr;
+
+    if ((type == state->ArrayType ||
+         type->tp_init == state->ArrayType->tp_init) &&
+        !_PyArg_NoKeywords("array.array", kwds))
+        return NULL;
+
+    if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial))
+        return NULL;
+
+    if (PySys_Audit("array.__new__", "CO",
+                    c, initial ? initial : Py_None) < 0) {
+        return NULL;
+    }
+
+    if (c == 'u') {
+        if (PyErr_WarnEx(PyExc_DeprecationWarning,
+                         "The 'u' type code is deprecated and "
+                         "will be removed in Python 3.16",
+                         1)) {
+            return NULL;
+        }
+    }
+
     bool is_unicode = c == 'u' || c == 'w';
 
+    if (initial && !is_unicode) {
+        if (PyUnicode_Check(initial)) {
+            PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
+                         "an array with typecode '%c'", c);
+            return NULL;
+        }
+        else if (array_Check(initial, state)) {
+            int ic = ((arrayobject*)initial)->ob_descr->typecode;
+            if (ic == 'u' || ic == 'w') {
+                PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
+                            "initialize an array with typecode '%c'", c);
+                return NULL;
+            }
+        }
+    }
+
     if (!(initial == NULL || PyList_Check(initial)
           || PyByteArray_Check(initial)
           || PyBytes_Check(initial)
@@ -3017,69 +2877,6 @@ array_new_internal_lock_held(PyTypeObject *type, 
PyObject *initial, int c)
     return NULL;
 }
 
-static PyObject *
-array_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
-{
-    array_state *state = find_array_state_by_type(type);
-    int c;
-    PyObject *initial = NULL;
-
-    if ((type == state->ArrayType ||
-         type->tp_init == state->ArrayType->tp_init) &&
-        !_PyArg_NoKeywords("array.array", kwds)) {
-        return NULL;
-    }
-
-    if (!PyArg_ParseTuple(args, "C|O:array", &c, &initial)) {
-        return NULL;
-    }
-
-    if (PySys_Audit("array.__new__", "CO",
-                    c, initial ? initial : Py_None) < 0) {
-        return NULL;
-    }
-
-    if (c == 'u') {
-        if (PyErr_WarnEx(PyExc_DeprecationWarning,
-                         "The 'u' type code is deprecated and "
-                         "will be removed in Python 3.16",
-                         1)) {
-            return NULL;
-        }
-    }
-
-    bool is_unicode = c == 'u' || c == 'w';
-
-    if (initial && !is_unicode) {
-        if (PyUnicode_Check(initial)) {
-            PyErr_Format(PyExc_TypeError, "cannot use a str to initialize "
-                         "an array with typecode '%c'", c);
-            return NULL;
-        }
-        else if (array_Check(initial, state)) {
-            int ic = ((arrayobject*)initial)->ob_descr->typecode;
-            if (ic == 'u' || ic == 'w') {
-                PyErr_Format(PyExc_TypeError, "cannot use a unicode array to "
-                            "initialize an array with typecode '%c'", c);
-                return NULL;
-            }
-        }
-    }
-
-    PyObject *ret;
-
-    if (initial == NULL) {
-        ret = array_new_internal_lock_held(type, initial, c);
-    }
-    else {
-        Py_BEGIN_CRITICAL_SECTION(initial);
-        ret = array_new_internal_lock_held(type, initial, c);
-        Py_END_CRITICAL_SECTION();
-    }
-
-    return ret;
-}
-
 
 PyDoc_STRVAR(module_doc,
 "This module defines an object type which can efficiently represent\n\
@@ -3222,7 +3019,7 @@ array_iter(PyObject *op)
         return NULL;
 
     it->ao = (arrayobject*)Py_NewRef(ao);
-    it->index = 0;  // -1 indicates exhausted
+    it->index = 0;
     it->getitem = ao->ob_descr->getitem;
     PyObject_GC_Track(it);
     return (PyObject *)it;
@@ -3233,37 +3030,23 @@ arrayiter_next(PyObject *op)
 {
     arrayiterobject *it = arrayiterobject_CAST(op);
     assert(it != NULL);
-    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(it->index);
-    if (index < 0) {
-        return NULL;
-    }
-    PyObject *ret;
-    arrayobject *ao = it->ao;
 #ifndef NDEBUG
     array_state *state = find_array_state_by_type(Py_TYPE(it));
     assert(PyObject_TypeCheck(it, state->ArrayIterType));
-    assert(array_Check(ao, state));
 #endif
-
-    Py_BEGIN_CRITICAL_SECTION(ao);
-    if (index < Py_SIZE(ao)) {
-        ret = (*it->getitem)(ao, index);
-    }
-    else {
-        ret = NULL;
-    }
-    Py_END_CRITICAL_SECTION();
-
-    if (ret != NULL) {
-        FT_ATOMIC_STORE_SSIZE_RELAXED(it->index, index + 1);
+    arrayobject *ao = it->ao;
+    if (ao == NULL) {
+        return NULL;
     }
-    else {
-        FT_ATOMIC_STORE_SSIZE_RELAXED(it->index, -1);
-#ifndef Py_GIL_DISABLED
-        Py_CLEAR(it->ao);
+#ifndef NDEBUG
+    assert(array_Check(ao, state));
 #endif
+    if (it->index < Py_SIZE(ao)) {
+        return (*it->getitem)(ao, it->index++);
     }
-    return ret;
+    it->ao = NULL;
+    Py_DECREF(ao);
+    return NULL;
 }
 
 static void
@@ -3299,14 +3082,14 @@ static PyObject *
 array_arrayiterator___reduce___impl(arrayiterobject *self, PyTypeObject *cls)
 /*[clinic end generated code: output=4b032417a2c8f5e6 input=ac64e65a87ad452e]*/
 {
+
     array_state *state = get_array_state_by_class(cls);
     assert(state != NULL);
     PyObject *func = _PyEval_GetBuiltin(state->str_iter);
-    Py_ssize_t index = FT_ATOMIC_LOAD_SSIZE_RELAXED(self->index);
-    if (index >= 0) {
-        return Py_BuildValue("N(O)n", func, self->ao, index);
+    if (self->ao == NULL) {
+        return Py_BuildValue("N(())", func);
     }
-    return Py_BuildValue("N(())", func);
+    return Py_BuildValue("N(O)n", func, self->ao, self->index);
 }
 
 /*[clinic input]
@@ -3323,20 +3106,17 @@ array_arrayiterator___setstate__(arrayiterobject *self, 
PyObject *state)
 /*[clinic end generated code: output=397da9904e443cbe input=f47d5ceda19e787b]*/
 {
     Py_ssize_t index = PyLong_AsSsize_t(state);
-    if (index == -1 && PyErr_Occurred()) {
+    if (index == -1 && PyErr_Occurred())
         return NULL;
-    }
-    if (FT_ATOMIC_LOAD_SSIZE_RELAXED(self->index) >= 0) {
-        if (index < -1) {
-            index = -1;
+    arrayobject *ao = self->ao;
+    if (ao != NULL) {
+        if (index < 0) {
+            index = 0;
         }
-        else {
-            Py_ssize_t size = Pyarrayobject_GET_SIZE(self->ao);
-            if (index > size) {
-                index = size; /* iterator at end */
-            }
+        else if (index > Py_SIZE(ao)) {
+            index = Py_SIZE(ao); /* iterator exhausted */
         }
-        FT_ATOMIC_STORE_SSIZE_RELAXED(self->index, index);
+        self->index = index;
     }
     Py_RETURN_NONE;
 }
diff --git a/Modules/clinic/arraymodule.c.h b/Modules/clinic/arraymodule.c.h
index 3816bb7709658e..c5b62b16699d06 100644
--- a/Modules/clinic/arraymodule.c.h
+++ b/Modules/clinic/arraymodule.c.h
@@ -6,7 +6,6 @@ preserve
 #  include "pycore_runtime.h"     // _Py_SINGLETON()
 #endif
 #include "pycore_abstract.h"      // _PyNumber_Index()
-#include "pycore_critical_section.h"// Py_BEGIN_CRITICAL_SECTION()
 #include "pycore_modsupport.h"    // _PyArg_CheckPositional()
 
 PyDoc_STRVAR(array_array_clear__doc__,
@@ -24,13 +23,7 @@ array_array_clear_impl(arrayobject *self);
 static PyObject *
 array_array_clear(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_clear_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_clear_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array___copy____doc__,
@@ -48,13 +41,7 @@ array_array___copy___impl(arrayobject *self);
 static PyObject *
 array_array___copy__(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array___copy___impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array___copy___impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array___deepcopy____doc__,
@@ -66,21 +53,6 @@ PyDoc_STRVAR(array_array___deepcopy____doc__,
 #define ARRAY_ARRAY___DEEPCOPY___METHODDEF    \
     {"__deepcopy__", (PyCFunction)array_array___deepcopy__, METH_O, 
array_array___deepcopy____doc__},
 
-static PyObject *
-array_array___deepcopy___impl(arrayobject *self, PyObject *unused);
-
-static PyObject *
-array_array___deepcopy__(arrayobject *self, PyObject *unused)
-{
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array___deepcopy___impl((arrayobject *)self, unused);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
-}
-
 PyDoc_STRVAR(array_array_count__doc__,
 "count($self, v, /)\n"
 "--\n"
@@ -90,21 +62,6 @@ PyDoc_STRVAR(array_array_count__doc__,
 #define ARRAY_ARRAY_COUNT_METHODDEF    \
     {"count", (PyCFunction)array_array_count, METH_O, 
array_array_count__doc__},
 
-static PyObject *
-array_array_count_impl(arrayobject *self, PyObject *v);
-
-static PyObject *
-array_array_count(arrayobject *self, PyObject *v)
-{
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_count_impl((arrayobject *)self, v);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
-}
-
 PyDoc_STRVAR(array_array_index__doc__,
 "index($self, v, start=0, stop=sys.maxsize, /)\n"
 "--\n"
@@ -145,9 +102,7 @@ array_array_index(PyObject *self, PyObject *const *args, 
Py_ssize_t nargs)
         goto exit;
     }
 skip_optional:
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array_index_impl((arrayobject *)self, v, start, stop);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -162,21 +117,6 @@ PyDoc_STRVAR(array_array_remove__doc__,
 #define ARRAY_ARRAY_REMOVE_METHODDEF    \
     {"remove", (PyCFunction)array_array_remove, METH_O, 
array_array_remove__doc__},
 
-static PyObject *
-array_array_remove_impl(arrayobject *self, PyObject *v);
-
-static PyObject *
-array_array_remove(arrayobject *self, PyObject *v)
-{
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_remove_impl((arrayobject *)self, v);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
-}
-
 PyDoc_STRVAR(array_array_pop__doc__,
 "pop($self, i=-1, /)\n"
 "--\n"
@@ -216,9 +156,7 @@ array_array_pop(PyObject *self, PyObject *const *args, 
Py_ssize_t nargs)
         i = ival;
     }
 skip_optional:
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array_pop_impl((arrayobject *)self, i);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -303,9 +241,7 @@ array_array_insert(PyObject *self, PyObject *const *args, 
Py_ssize_t nargs)
         i = ival;
     }
     v = args[1];
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array_insert_impl((arrayobject *)self, i, v);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -329,13 +265,7 @@ array_array_buffer_info_impl(arrayobject *self);
 static PyObject *
 array_array_buffer_info(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_buffer_info_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_buffer_info_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array_append__doc__,
@@ -347,21 +277,6 @@ PyDoc_STRVAR(array_array_append__doc__,
 #define ARRAY_ARRAY_APPEND_METHODDEF    \
     {"append", (PyCFunction)array_array_append, METH_O, 
array_array_append__doc__},
 
-static PyObject *
-array_array_append_impl(arrayobject *self, PyObject *v);
-
-static PyObject *
-array_array_append(arrayobject *self, PyObject *v)
-{
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_append_impl((arrayobject *)self, v);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
-}
-
 PyDoc_STRVAR(array_array_byteswap__doc__,
 "byteswap($self, /)\n"
 "--\n"
@@ -380,13 +295,7 @@ array_array_byteswap_impl(arrayobject *self);
 static PyObject *
 array_array_byteswap(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_byteswap_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_byteswap_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array_reverse__doc__,
@@ -404,13 +313,7 @@ array_array_reverse_impl(arrayobject *self);
 static PyObject *
 array_array_reverse(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_reverse_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_reverse_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array_fromfile__doc__,
@@ -509,9 +412,7 @@ array_array_tofile(PyObject *self, PyTypeObject *cls, 
PyObject *const *args, Py_
         goto exit;
     }
     f = args[0];
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array_tofile_impl((arrayobject *)self, cls, f);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -526,21 +427,6 @@ PyDoc_STRVAR(array_array_fromlist__doc__,
 #define ARRAY_ARRAY_FROMLIST_METHODDEF    \
     {"fromlist", (PyCFunction)array_array_fromlist, METH_O, 
array_array_fromlist__doc__},
 
-static PyObject *
-array_array_fromlist_impl(arrayobject *self, PyObject *list);
-
-static PyObject *
-array_array_fromlist(arrayobject *self, PyObject *list)
-{
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION2(self, list);
-    return_value = array_array_fromlist_impl((arrayobject *)self, list);
-    Py_END_CRITICAL_SECTION2();
-
-    return return_value;
-}
-
 PyDoc_STRVAR(array_array_tolist__doc__,
 "tolist($self, /)\n"
 "--\n"
@@ -556,13 +442,7 @@ array_array_tolist_impl(arrayobject *self);
 static PyObject *
 array_array_tolist(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_tolist_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_tolist_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array_frombytes__doc__,
@@ -586,9 +466,7 @@ array_array_frombytes(PyObject *self, PyObject *arg)
     if (PyObject_GetBuffer(arg, &buffer, PyBUF_SIMPLE) != 0) {
         goto exit;
     }
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array_frombytes_impl((arrayobject *)self, &buffer);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     /* Cleanup for buffer */
@@ -614,13 +492,7 @@ array_array_tobytes_impl(arrayobject *self);
 static PyObject *
 array_array_tobytes(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_tobytes_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_tobytes_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array_fromunicode__doc__,
@@ -650,9 +522,7 @@ array_array_fromunicode(PyObject *self, PyObject *arg)
         goto exit;
     }
     ustr = arg;
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array_fromunicode_impl((arrayobject *)self, ustr);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -677,13 +547,7 @@ array_array_tounicode_impl(arrayobject *self);
 static PyObject *
 array_array_tounicode(PyObject *self, PyObject *Py_UNUSED(ignored))
 {
-    PyObject *return_value = NULL;
-
-    Py_BEGIN_CRITICAL_SECTION(self);
-    return_value = array_array_tounicode_impl((arrayobject *)self);
-    Py_END_CRITICAL_SECTION();
-
-    return return_value;
+    return array_array_tounicode_impl((arrayobject *)self);
 }
 
 PyDoc_STRVAR(array_array___sizeof____doc__,
@@ -795,9 +659,7 @@ array_array___reduce_ex__(PyObject *self, PyTypeObject 
*cls, PyObject *const *ar
         goto exit;
     }
     value = args[0];
-    Py_BEGIN_CRITICAL_SECTION(self);
     return_value = array_array___reduce_ex___impl((arrayobject *)self, cls, 
value);
-    Py_END_CRITICAL_SECTION();
 
 exit:
     return return_value;
@@ -833,4 +695,4 @@ PyDoc_STRVAR(array_arrayiterator___setstate____doc__,
 
 #define ARRAY_ARRAYITERATOR___SETSTATE___METHODDEF    \
     {"__setstate__", (PyCFunction)array_arrayiterator___setstate__, METH_O, 
array_arrayiterator___setstate____doc__},
-/*[clinic end generated code: output=c9219e074c62e0c8 input=a9049054013a1b77]*/
+/*[clinic end generated code: output=8120dc5c4fa414b9 input=a9049054013a1b77]*/

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to