Skip to content

Commit f7af8bc

Browse files
authored
[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 b184abf)
1 parent f7cc862 commit f7af8bc

File tree

2 files changed

+10
-11
lines changed

2 files changed

+10
-11
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Update :c:func:`PyGC_Enable()`, :c:func:`PyGC_Disable()`,
2+
:c:func:`PyGC_IsEnabled()` to use atomic operation for thread-safety
3+
at free-threading build. Patch by Donghee Na.

Python/gc_free_threading.c

+7-11
Original file line numberDiff line numberDiff line change
@@ -1059,7 +1059,8 @@ gc_should_collect(GCState *gcstate)
10591059
{
10601060
int count = _Py_atomic_load_int_relaxed(&gcstate->generations[0].count);
10611061
int threshold = gcstate->generations[0].threshold;
1062-
if (count <= threshold || threshold == 0 || !gcstate->enabled) {
1062+
int gc_enabled = _Py_atomic_load_int_relaxed(&gcstate->enabled);
1063+
if (count <= threshold || threshold == 0 || !gc_enabled) {
10631064
return false;
10641065
}
10651066
// Avoid quadratic behavior by scaling threshold to the number of live
@@ -1495,25 +1496,21 @@ int
14951496
PyGC_Enable(void)
14961497
{
14971498
GCState *gcstate = get_gc_state();
1498-
int old_state = gcstate->enabled;
1499-
gcstate->enabled = 1;
1500-
return old_state;
1499+
return _Py_atomic_exchange_int(&gcstate->enabled, 1);
15011500
}
15021501

15031502
int
15041503
PyGC_Disable(void)
15051504
{
15061505
GCState *gcstate = get_gc_state();
1507-
int old_state = gcstate->enabled;
1508-
gcstate->enabled = 0;
1509-
return old_state;
1506+
return _Py_atomic_exchange_int(&gcstate->enabled, 0);
15101507
}
15111508

15121509
int
15131510
PyGC_IsEnabled(void)
15141511
{
15151512
GCState *gcstate = get_gc_state();
1516-
return gcstate->enabled;
1513+
return _Py_atomic_load_int_relaxed(&gcstate->enabled);
15171514
}
15181515

15191516
/* Public API to invoke gc.collect() from C */
@@ -1523,7 +1520,7 @@ PyGC_Collect(void)
15231520
PyThreadState *tstate = _PyThreadState_GET();
15241521
GCState *gcstate = &tstate->interp->gc;
15251522

1526-
if (!gcstate->enabled) {
1523+
if (!_Py_atomic_load_int_relaxed(&gcstate->enabled)) {
15271524
return 0;
15281525
}
15291526

@@ -1681,8 +1678,7 @@ _PyObject_GC_Link(PyObject *op)
16811678
void
16821679
_Py_RunGC(PyThreadState *tstate)
16831680
{
1684-
GCState *gcstate = get_gc_state();
1685-
if (!gcstate->enabled) {
1681+
if (!PyGC_IsEnabled()) {
16861682
return;
16871683
}
16881684
gc_collect_main(tstate, 0, _Py_GC_REASON_HEAP);

0 commit comments

Comments
 (0)