Only call `gc_restore_tid()` from stop-the-world contexts.
`worklist_pop()` can be called while other threads are running, so use a
relaxed atomic to modify `ob_tid`.
PyObject *op = (PyObject *)worklist->head;
if (op != NULL) {
worklist->head = op->ob_tid;
- op->ob_tid = 0;
+ _Py_atomic_store_uintptr_relaxed(&op->ob_tid, 0);
}
return op;
}
static void
gc_restore_tid(PyObject *op)
{
+ assert(_PyInterpreterState_GET()->stoptheworld.world_stopped);
mi_segment_t *segment = _mi_ptr_segment(op);
if (_Py_REF_IS_MERGED(op->ob_ref_shared)) {
op->ob_tid = 0;
Py_DECREF(temp);
}
- gc_restore_tid(op);
Py_DECREF(op); // drop worklist reference
}
}
{
PyObject *op;
while ((op = worklist_pop(worklist)) != NULL) {
- gc_restore_tid(op);
gc_clear_unreachable(op);
Py_DECREF(op);
}
race_top:_PyParkingLot_Park
race_top:_PyType_HasFeature
race_top:assign_version_tag
-race_top:gc_restore_tid
race_top:insertdict
race_top:lookup_tp_dict
race_top:mi_heap_visit_pages
race_top:make_pending_calls
race_top:set_add_entry
race_top:should_intern_string
-race_top:worklist_pop
race_top:_PyEval_IsGILEnabled
race_top:llist_insert_tail
race_top:_Py_slot_tp_getattr_hook
race_top:tstate_delete_common
race_top:tstate_is_freed
race_top:type_modified_unlocked
-race_top:update_refs
race_top:write_thread_id
race_top:PyThreadState_Clear