Skip to content

Commit fb5e034

Browse files
authored
gh-112087: Use QSBR technique for list_new/clear for free-thread build (gh-115875)
1 parent 90a1e98 commit fb5e034

File tree

1 file changed

+29
-6
lines changed

1 file changed

+29
-6
lines changed

Objects/listobject.c

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,16 @@ list_item(PyObject *aa, Py_ssize_t i)
502502
PyErr_SetObject(PyExc_IndexError, &_Py_STR(list_err));
503503
return NULL;
504504
}
505-
return Py_NewRef(a->ob_item[i]);
505+
PyObject *item;
506+
Py_BEGIN_CRITICAL_SECTION(a);
507+
#ifdef Py_GIL_DISABLED
508+
if (!_Py_IsOwnedByCurrentThread((PyObject *)a) && !_PyObject_GC_IS_SHARED(a)) {
509+
_PyObject_GC_SET_SHARED(a);
510+
}
511+
#endif
512+
item = Py_NewRef(a->ob_item[i]);
513+
Py_END_CRITICAL_SECTION();
514+
return item;
506515
}
507516

508517
static PyObject *
@@ -658,7 +667,7 @@ list_repeat(PyObject *aa, Py_ssize_t n)
658667
}
659668

660669
static void
661-
list_clear(PyListObject *a)
670+
list_clear_impl(PyListObject *a, bool is_resize)
662671
{
663672
PyObject **items = a->ob_item;
664673
if (items == NULL) {
@@ -674,17 +683,31 @@ list_clear(PyListObject *a)
674683
while (--i >= 0) {
675684
Py_XDECREF(items[i]);
676685
}
677-
// TODO: Use QSBR technique, if the list is shared between threads,
678-
PyMem_Free(items);
679-
686+
#ifdef Py_GIL_DISABLED
687+
bool use_qsbr = is_resize && _PyObject_GC_IS_SHARED(a);
688+
#else
689+
bool use_qsbr = false;
690+
#endif
691+
if (use_qsbr) {
692+
_PyMem_FreeDelayed(items);
693+
}
694+
else {
695+
PyMem_Free(items);
696+
}
680697
// Note that there is no guarantee that the list is actually empty
681698
// at this point, because XDECREF may have populated it indirectly again!
682699
}
683700

701+
static void
702+
list_clear(PyListObject *a)
703+
{
704+
list_clear_impl(a, true);
705+
}
706+
684707
static int
685708
list_clear_slot(PyObject *self)
686709
{
687-
list_clear((PyListObject *)self);
710+
list_clear_impl((PyListObject *)self, false);
688711
return 0;
689712
}
690713

0 commit comments

Comments
 (0)