Skip to content

Commit 2ba1aed

Browse files
authored
gh-117657: TSAN fix race on gstate->young.count (#118313)
1 parent 79688b5 commit 2ba1aed

File tree

2 files changed

+13
-13
lines changed

2 files changed

+13
-13
lines changed

Python/gc_free_threading.c

+13-12
Original file line numberDiff line numberDiff line change
@@ -1044,9 +1044,20 @@ record_deallocation(PyThreadState *tstate)
10441044
}
10451045

10461046
static void
1047-
gc_collect_internal(PyInterpreterState *interp, struct collection_state *state)
1047+
gc_collect_internal(PyInterpreterState *interp, struct collection_state *state, int generation)
10481048
{
10491049
_PyEval_StopTheWorld(interp);
1050+
1051+
// update collection and allocation counters
1052+
if (generation+1 < NUM_GENERATIONS) {
1053+
state->gcstate->old[generation].count += 1;
1054+
}
1055+
1056+
state->gcstate->young.count = 0;
1057+
for (int i = 1; i <= generation; ++i) {
1058+
state->gcstate->old[i-1].count = 0;
1059+
}
1060+
10501061
// merge refcounts for all queued objects
10511062
merge_all_queued_objects(interp, state);
10521063
process_delayed_frees(interp);
@@ -1115,7 +1126,6 @@ gc_collect_internal(PyInterpreterState *interp, struct collection_state *state)
11151126
static Py_ssize_t
11161127
gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
11171128
{
1118-
int i;
11191129
Py_ssize_t m = 0; /* # objects collected */
11201130
Py_ssize_t n = 0; /* # unreachable objects that couldn't be collected */
11211131
PyTime_t t1 = 0; /* initialize to prevent a compiler warning */
@@ -1161,23 +1171,14 @@ gc_collect_main(PyThreadState *tstate, int generation, _PyGC_Reason reason)
11611171
PyDTrace_GC_START(generation);
11621172
}
11631173

1164-
/* update collection and allocation counters */
1165-
if (generation+1 < NUM_GENERATIONS) {
1166-
gcstate->old[generation].count += 1;
1167-
}
1168-
gcstate->young.count = 0;
1169-
for (i = 1; i <= generation; i++) {
1170-
gcstate->old[i-1].count = 0;
1171-
}
1172-
11731174
PyInterpreterState *interp = tstate->interp;
11741175

11751176
struct collection_state state = {
11761177
.interp = interp,
11771178
.gcstate = gcstate,
11781179
};
11791180

1180-
gc_collect_internal(interp, &state);
1181+
gc_collect_internal(interp, &state, generation);
11811182

11821183
m = state.collected;
11831184
n = state.uncollectable;

Tools/tsan/suppressions_free_threading.txt

-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ race:_PyObject_GC_TRACK
2727
race:_PyParkingLot_Park
2828
race:_PyType_HasFeature
2929
race:assign_version_tag
30-
race:gc_collect_main
3130
race:gc_restore_tid
3231
race:initialize_new_array
3332
race:insertdict

0 commit comments

Comments
 (0)