diff options
| author | Luke Gruber <luke.gruber@shopify.com> | 2026-04-09 14:35:57 -0400 |
|---|---|---|
| committer | Luke Gruber <luke.gru@gmail.com> | 2026-04-13 19:49:27 -0400 |
| commit | ee90e8e380190468a87ab5df3597dafd4f5def53 (patch) | |
| tree | 9608e19c92e484c732aebaefffeebf091f108fe5 | |
| parent | ab324956d7823fb7a20123c1846075e3a04dfe0e (diff) | |
Concurrent set fix when encountering garbage obj in find_or_insert
When CASing the garbage key to EMPTY, if we succeed we should decrease
set->size because we're trying to re-insert into the same slot right after.
The insertion increases set->size if it succeeds. This issue can lead to
set->size being overcounted, which can lead to more table resizes.
| -rw-r--r-- | concurrent_set.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/concurrent_set.c b/concurrent_set.c index c8b0c73881..42a5bfe8da 100644 --- a/concurrent_set.c +++ b/concurrent_set.c @@ -399,7 +399,12 @@ start_search: if (continuation) { goto probe_next; } - rbimpl_atomic_value_cas(&entry->key, curr_key, CONCURRENT_SET_EMPTY, RBIMPL_ATOMIC_RELEASE, RBIMPL_ATOMIC_RELAXED); + { + VALUE prev = rbimpl_atomic_value_cas(&entry->key, curr_key, CONCURRENT_SET_EMPTY, RBIMPL_ATOMIC_RELEASE, RBIMPL_ATOMIC_RELAXED); + if (prev == curr_key) { + rbimpl_atomic_sub(&set->size, 1, RBIMPL_ATOMIC_RELAXED); + } + } continue; } |
