[3.13] gh-129533: Update PyGC_Enable/Disable/IsEnabled to use atomic operat… (gh-129756)

gh-129533: Update PyGC_Enable/Disable/IsEnabled to use atomic operation  (gh-129563)

(cherry picked from commit b184abf074)
This commit is contained in:
Donghee Na 2025-02-07 08:11:17 +09:00 committed by GitHub
parent f7cc862345
commit f7af8bc58a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 10 additions and 11 deletions

View File

@ -0,0 +1,3 @@
Update :c:func:`PyGC_Enable()`, :c:func:`PyGC_Disable()`,
:c:func:`PyGC_IsEnabled()` to use atomic operation for thread-safety
at free-threading build. Patch by Donghee Na.

View File

@ -1059,7 +1059,8 @@ gc_should_collect(GCState *gcstate)
{ {
int count = _Py_atomic_load_int_relaxed(&gcstate->generations[0].count); int count = _Py_atomic_load_int_relaxed(&gcstate->generations[0].count);
int threshold = gcstate->generations[0].threshold; int threshold = gcstate->generations[0].threshold;
if (count <= threshold || threshold == 0 || !gcstate->enabled) { int gc_enabled = _Py_atomic_load_int_relaxed(&gcstate->enabled);
if (count <= threshold || threshold == 0 || !gc_enabled) {
return false; return false;
} }
// Avoid quadratic behavior by scaling threshold to the number of live // Avoid quadratic behavior by scaling threshold to the number of live
@ -1495,25 +1496,21 @@ int
PyGC_Enable(void) PyGC_Enable(void)
{ {
GCState *gcstate = get_gc_state(); GCState *gcstate = get_gc_state();
int old_state = gcstate->enabled; return _Py_atomic_exchange_int(&gcstate->enabled, 1);
gcstate->enabled = 1;
return old_state;
} }
int int
PyGC_Disable(void) PyGC_Disable(void)
{ {
GCState *gcstate = get_gc_state(); GCState *gcstate = get_gc_state();
int old_state = gcstate->enabled; return _Py_atomic_exchange_int(&gcstate->enabled, 0);
gcstate->enabled = 0;
return old_state;
} }
int int
PyGC_IsEnabled(void) PyGC_IsEnabled(void)
{ {
GCState *gcstate = get_gc_state(); GCState *gcstate = get_gc_state();
return gcstate->enabled; return _Py_atomic_load_int_relaxed(&gcstate->enabled);
} }
/* Public API to invoke gc.collect() from C */ /* Public API to invoke gc.collect() from C */
@ -1523,7 +1520,7 @@ PyGC_Collect(void)
PyThreadState *tstate = _PyThreadState_GET(); PyThreadState *tstate = _PyThreadState_GET();
GCState *gcstate = &tstate->interp->gc; GCState *gcstate = &tstate->interp->gc;
if (!gcstate->enabled) { if (!_Py_atomic_load_int_relaxed(&gcstate->enabled)) {
return 0; return 0;
} }
@ -1681,8 +1678,7 @@ _PyObject_GC_Link(PyObject *op)
void void
_Py_RunGC(PyThreadState *tstate) _Py_RunGC(PyThreadState *tstate)
{ {
GCState *gcstate = get_gc_state(); if (!PyGC_IsEnabled()) {
if (!gcstate->enabled) {
return; return;
} }
gc_collect_main(tstate, 0, _Py_GC_REASON_HEAP); gc_collect_main(tstate, 0, _Py_GC_REASON_HEAP);