gh-115103: Implement delayed free mechanism for free-threaded builds (#115367)
This adds `_PyMem_FreeDelayed()` and supporting functions. The `_PyMem_FreeDelayed()` function frees memory with the same allocator as `PyMem_Free()`, but after some delay to ensure that concurrent lock-free readers have finished.
This commit is contained in:
@@ -1837,6 +1837,9 @@ finalize_interp_clear(PyThreadState *tstate)
|
||||
|
||||
finalize_interp_types(tstate->interp);
|
||||
|
||||
/* Free any delayed free requests immediately */
|
||||
_PyMem_FiniDelayed(tstate->interp);
|
||||
|
||||
/* finalize_interp_types may allocate Python objects so we may need to
|
||||
abandon mimalloc segments again */
|
||||
_PyThreadState_ClearMimallocHeaps(tstate);
|
||||
|
||||
@@ -617,6 +617,7 @@ init_interpreter(PyInterpreterState *interp,
|
||||
#ifdef Py_GIL_DISABLED
|
||||
_Py_brc_init_state(interp);
|
||||
#endif
|
||||
llist_init(&interp->mem_free_queue.head);
|
||||
for (int i = 0; i < _PY_MONITORING_UNGROUPED_EVENTS; i++) {
|
||||
interp->monitors.tools[i] = 0;
|
||||
}
|
||||
@@ -1353,6 +1354,7 @@ init_threadstate(_PyThreadStateImpl *_tstate,
|
||||
// Initialize biased reference counting inter-thread queue
|
||||
_Py_brc_init_thread(tstate);
|
||||
#endif
|
||||
llist_init(&_tstate->mem_free_queue);
|
||||
|
||||
if (interp->stoptheworld.requested || _PyRuntime.stoptheworld.requested) {
|
||||
// Start in the suspended state if there is an ongoing stop-the-world.
|
||||
@@ -1574,6 +1576,7 @@ PyThreadState_Clear(PyThreadState *tstate)
|
||||
// don't call _PyInterpreterState_SetNotRunningMain() yet.
|
||||
tstate->on_delete(tstate->on_delete_data);
|
||||
}
|
||||
|
||||
#ifdef Py_GIL_DISABLED
|
||||
// Each thread should clear own freelists in free-threading builds.
|
||||
struct _Py_object_freelists *freelists = _Py_object_freelists_GET();
|
||||
@@ -1583,6 +1586,9 @@ PyThreadState_Clear(PyThreadState *tstate)
|
||||
_Py_brc_remove_thread(tstate);
|
||||
#endif
|
||||
|
||||
// Merge our queue of pointers to be freed into the interpreter queue.
|
||||
_PyMem_AbandonDelayed(tstate);
|
||||
|
||||
_PyThreadState_ClearMimallocHeaps(tstate);
|
||||
|
||||
tstate->_status.cleared = 1;
|
||||
|
||||
Reference in New Issue
Block a user