Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit fb5e034

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

File tree

Expand file treeCollapse file tree

1 file changed

+29
-6
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+29
-6
lines changed

‎Objects/listobject.c

Copy file name to clipboardExpand all lines: Objects/listobject.c
+29-6Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.