Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 9c08f40

Browse filesBrowse files
authored
gh-117657: Fix TSAN races in setobject.c (#121511)
The `used` field must be written using atomic stores because `set_len` and iterators may access the field concurrently without holding the per-object lock.
1 parent 649d5b6 commit 9c08f40
Copy full SHA for 9c08f40

File tree

Expand file treeCollapse file tree

2 files changed

+10
-11
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+10
-11
lines changed

‎Objects/setobject.c

Copy file name to clipboardExpand all lines: Objects/setobject.c
+10-8Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -184,14 +184,14 @@ set_add_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
184184
found_unused_or_dummy:
185185
if (freeslot == NULL)
186186
goto found_unused;
187-
so->used++;
187+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
188188
freeslot->key = key;
189189
freeslot->hash = hash;
190190
return 0;
191191

192192
found_unused:
193193
so->fill++;
194-
so->used++;
194+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used + 1);
195195
entry->key = key;
196196
entry->hash = hash;
197197
if ((size_t)so->fill*5 < mask*3)
@@ -357,7 +357,7 @@ set_discard_entry(PySetObject *so, PyObject *key, Py_hash_t hash)
357357
old_key = entry->key;
358358
entry->key = dummy;
359359
entry->hash = -1;
360-
so->used--;
360+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used - 1);
361361
Py_DECREF(old_key);
362362
return DISCARD_FOUND;
363363
}
@@ -397,7 +397,7 @@ set_empty_to_minsize(PySetObject *so)
397397
{
398398
memset(so->smalltable, 0, sizeof(so->smalltable));
399399
so->fill = 0;
400-
so->used = 0;
400+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, 0);
401401
so->mask = PySet_MINSIZE - 1;
402402
so->table = so->smalltable;
403403
so->hash = -1;
@@ -615,7 +615,7 @@ set_merge_lock_held(PySetObject *so, PyObject *otherset)
615615
}
616616
}
617617
so->fill = other->fill;
618-
so->used = other->used;
618+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, other->used);
619619
return 0;
620620
}
621621

@@ -624,7 +624,7 @@ set_merge_lock_held(PySetObject *so, PyObject *otherset)
624624
setentry *newtable = so->table;
625625
size_t newmask = (size_t)so->mask;
626626
so->fill = other->used;
627-
so->used = other->used;
627+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, other->used);
628628
for (i = other->mask + 1; i > 0 ; i--, other_entry++) {
629629
key = other_entry->key;
630630
if (key != NULL && key != dummy) {
@@ -678,7 +678,7 @@ set_pop_impl(PySetObject *so)
678678
key = entry->key;
679679
entry->key = dummy;
680680
entry->hash = -1;
681-
so->used--;
681+
FT_ATOMIC_STORE_SSIZE_RELAXED(so->used, so->used - 1);
682682
so->finger = entry - so->table + 1; /* next place to start */
683683
return key;
684684
}
@@ -1173,7 +1173,9 @@ set_swap_bodies(PySetObject *a, PySetObject *b)
11731173
Py_hash_t h;
11741174

11751175
t = a->fill; a->fill = b->fill; b->fill = t;
1176-
t = a->used; a->used = b->used; b->used = t;
1176+
t = a->used;
1177+
FT_ATOMIC_STORE_SSIZE_RELAXED(a->used, b->used);
1178+
FT_ATOMIC_STORE_SSIZE_RELAXED(b->used, t);
11771179
t = a->mask; a->mask = b->mask; b->mask = t;
11781180

11791181
u = a->table;

‎Tools/tsan/suppressions_free_threading.txt

Copy file name to clipboardExpand all lines: Tools/tsan/suppressions_free_threading.txt
-3Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ race_top:assign_version_tag
3030
race_top:insertdict
3131
race_top:lookup_tp_dict
3232
race_top:new_reference
33-
# https://gist.github.com/colesbury/d13d033f413b4ad07929d044bed86c35
34-
race_top:set_discard_entry
3533
race_top:_PyDict_CheckConsistency
3634
race_top:_Py_dict_lookup_threadsafe
3735
race_top:_multiprocessing_SemLock_acquire_impl
@@ -41,7 +39,6 @@ race_top:insert_to_emptydict
4139
race_top:insertdict
4240
race_top:list_get_item_ref
4341
race_top:make_pending_calls
44-
race_top:set_add_entry
4542
race_top:_Py_slot_tp_getattr_hook
4643
race_top:add_threadstate
4744
race_top:dump_traceback

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.