mirror of
https://github.com/python/cpython.git
synced 2025-08-02 08:02:56 +00:00
gh-97922: Run the GC only on eval breaker (#97920)
This commit is contained in:
parent
c66dbddfba
commit
83eb827247
8 changed files with 74 additions and 14 deletions
|
@ -2252,6 +2252,20 @@ PyObject_IS_GC(PyObject *obj)
|
|||
return _PyObject_IS_GC(obj);
|
||||
}
|
||||
|
||||
void
|
||||
_Py_ScheduleGC(PyInterpreterState *interp)
|
||||
{
|
||||
GCState *gcstate = &interp->gc;
|
||||
if (gcstate->collecting == 1) {
|
||||
return;
|
||||
}
|
||||
struct _ceval_state *ceval = &interp->ceval;
|
||||
if (!_Py_atomic_load_relaxed(&ceval->gc_scheduled)) {
|
||||
_Py_atomic_store_relaxed(&ceval->gc_scheduled, 1);
|
||||
_Py_atomic_store_relaxed(&ceval->eval_breaker, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_PyObject_GC_Link(PyObject *op)
|
||||
{
|
||||
|
@ -2269,12 +2283,19 @@ _PyObject_GC_Link(PyObject *op)
|
|||
!gcstate->collecting &&
|
||||
!_PyErr_Occurred(tstate))
|
||||
{
|
||||
gcstate->collecting = 1;
|
||||
gc_collect_generations(tstate);
|
||||
gcstate->collecting = 0;
|
||||
_Py_ScheduleGC(tstate->interp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
_Py_RunGC(PyThreadState *tstate)
|
||||
{
|
||||
GCState *gcstate = &tstate->interp->gc;
|
||||
gcstate->collecting = 1;
|
||||
gc_collect_generations(tstate);
|
||||
gcstate->collecting = 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
gc_alloc(size_t basicsize, size_t presize)
|
||||
{
|
||||
|
|
|
@ -1798,6 +1798,19 @@ int
|
|||
PyErr_CheckSignals(void)
|
||||
{
|
||||
PyThreadState *tstate = _PyThreadState_GET();
|
||||
|
||||
/* Opportunistically check if the GC is scheduled to run and run it
|
||||
if we have a request. This is done here because native code needs
|
||||
to call this API if is going to run for some time without executing
|
||||
Python code to ensure signals are handled. Checking for the GC here
|
||||
allows long running native code to clean cycles created using the C-API
|
||||
even if it doesn't run the evaluation loop */
|
||||
struct _ceval_state *interp_ceval_state = &tstate->interp->ceval;
|
||||
if (_Py_atomic_load_relaxed(&interp_ceval_state->gc_scheduled)) {
|
||||
_Py_atomic_store_relaxed(&interp_ceval_state->gc_scheduled, 0);
|
||||
_Py_RunGC(tstate);
|
||||
}
|
||||
|
||||
if (!_Py_ThreadCanHandleSignals(tstate->interp)) {
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue