aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Python/gc_free_threading.c
diff options
context:
space:
mode:
Diffstat (limited to 'Python/gc_free_threading.c')
-rw-r--r--Python/gc_free_threading.c25
1 files changed, 10 insertions, 15 deletions
diff --git a/Python/gc_free_threading.c b/Python/gc_free_threading.c
index 0920c616c3c..f7f44407494 100644
--- a/Python/gc_free_threading.c
+++ b/Python/gc_free_threading.c
@@ -304,7 +304,7 @@ gc_visit_heaps_lock_held(PyInterpreterState *interp, mi_block_visit_fun *visitor
Py_ssize_t offset_pre = offset_base + 2 * sizeof(PyObject*);
// visit each thread's heaps for GC objects
- for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
+ _Py_FOR_EACH_TSTATE_UNLOCKED(interp, p) {
struct _mimalloc_thread_state *m = &((_PyThreadStateImpl *)p)->mimalloc;
if (!_Py_atomic_load_int(&m->initialized)) {
// The thread may not have called tstate_mimalloc_bind() yet.
@@ -374,8 +374,7 @@ gc_visit_stackref(_PyStackRef stackref)
static void
gc_visit_thread_stacks(PyInterpreterState *interp)
{
- HEAD_LOCK(&_PyRuntime);
- for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
+ _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
for (_PyInterpreterFrame *f = p->current_frame; f != NULL; f = f->previous) {
PyObject *executable = PyStackRef_AsPyObjectBorrow(f->f_executable);
if (executable == NULL || !PyCode_Check(executable)) {
@@ -390,7 +389,7 @@ gc_visit_thread_stacks(PyInterpreterState *interp)
}
}
}
- HEAD_UNLOCK(&_PyRuntime);
+ _Py_FOR_EACH_TSTATE_END(interp);
}
static void
@@ -444,14 +443,13 @@ process_delayed_frees(PyInterpreterState *interp, struct collection_state *state
// Merge the queues from other threads into our own queue so that we can
// process all of the pending delayed free requests at once.
- HEAD_LOCK(&_PyRuntime);
- for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
+ _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
_PyThreadStateImpl *other = (_PyThreadStateImpl *)p;
if (other != current_tstate) {
llist_concat(&current_tstate->mem_free_queue, &other->mem_free_queue);
}
}
- HEAD_UNLOCK(&_PyRuntime);
+ _Py_FOR_EACH_TSTATE_END(interp);
_PyMem_ProcessDelayedNoDealloc((PyThreadState *)current_tstate, queue_freed_object, state);
}
@@ -1234,8 +1232,7 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
state->gcstate->old[i-1].count = 0;
}
- HEAD_LOCK(&_PyRuntime);
- for (PyThreadState *p = interp->threads.head; p != NULL; p = p->next) {
+ _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
_PyThreadStateImpl *tstate = (_PyThreadStateImpl *)p;
// merge per-thread refcount for types into the type's actual refcount
@@ -1244,7 +1241,7 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state,
// merge refcounts for all queued objects
merge_queued_objects(tstate, state);
}
- HEAD_UNLOCK(&_PyRuntime);
+ _Py_FOR_EACH_TSTATE_END(interp);
process_delayed_frees(interp, state);
@@ -1993,13 +1990,11 @@ PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void *arg)
void
_PyGC_ClearAllFreeLists(PyInterpreterState *interp)
{
- HEAD_LOCK(&_PyRuntime);
- _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)interp->threads.head;
- while (tstate != NULL) {
+ _Py_FOR_EACH_TSTATE_BEGIN(interp, p) {
+ _PyThreadStateImpl *tstate = (_PyThreadStateImpl *)p;
_PyObject_ClearFreeLists(&tstate->freelists, 0);
- tstate = (_PyThreadStateImpl *)tstate->base.next;
}
- HEAD_UNLOCK(&_PyRuntime);
+ _Py_FOR_EACH_TSTATE_END(interp);
}
#endif // Py_GIL_DISABLED