Skip to content

Commit 8df34e9

Browse files
corona10cmaloney
authored andcommitted
pythongh-129533: Update PyGC_Enable/Disable/IsEnabled to use atomic operation (pythongh-129563)
1 parent 5d33246 commit 8df34e9

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
@@ -1864,7 +1864,8 @@ gc_should_collect(GCState *gcstate)
18641864
{
18651865
int count = _Py_atomic_load_int_relaxed(&gcstate->young.count);
18661866
int threshold = gcstate->young.threshold;
1867-
if (count <= threshold || threshold == 0 || !gcstate->enabled) {
1867+
int gc_enabled = _Py_atomic_load_int_relaxed(&gcstate->enabled);
1868+
if (count <= threshold || threshold == 0 || !gc_enabled) {
18681869
return false;
18691870
}
18701871
// Avoid quadratic behavior by scaling threshold to the number of live
@@ -2340,25 +2341,21 @@ int
23402341
PyGC_Enable(void)
23412342
{
23422343
GCState *gcstate = get_gc_state();
2343-
int old_state = gcstate->enabled;
2344-
gcstate->enabled = 1;
2345-
return old_state;
2344+
return _Py_atomic_exchange_int(&gcstate->enabled, 1);
23462345
}
23472346

23482347
int
23492348
PyGC_Disable(void)
23502349
{
23512350
GCState *gcstate = get_gc_state();
2352-
int old_state = gcstate->enabled;
2353-
gcstate->enabled = 0;
2354-
return old_state;
2351+
return _Py_atomic_exchange_int(&gcstate->enabled, 0);
23552352
}
23562353

23572354
int
23582355
PyGC_IsEnabled(void)
23592356
{
23602357
GCState *gcstate = get_gc_state();
2361-
return gcstate->enabled;
2358+
return _Py_atomic_load_int_relaxed(&gcstate->enabled);
23622359
}
23632360

23642361
/* Public API to invoke gc.collect() from C */
@@ -2368,7 +2365,7 @@ PyGC_Collect(void)
23682365
PyThreadState *tstate = _PyThreadState_GET();
23692366
GCState *gcstate = &tstate->interp->gc;
23702367

2371-
if (!gcstate->enabled) {
2368+
if (!_Py_atomic_load_int_relaxed(&gcstate->enabled)) {
23722369
return 0;
23732370
}
23742371

@@ -2527,8 +2524,7 @@ _PyObject_GC_Link(PyObject *op)
25272524
void
25282525
_Py_RunGC(PyThreadState *tstate)
25292526
{
2530-
GCState *gcstate = get_gc_state();
2531-
if (!gcstate->enabled) {
2527+
if (!PyGC_IsEnabled()) {
25322528
return;
25332529
}
25342530
gc_collect_main(tstate, 0, _Py_GC_REASON_HEAP);

0 commit comments

Comments
 (0)