summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Gruber <luke.gruber@shopify.com>2026-04-09 14:35:57 -0400
committerLuke Gruber <luke.gru@gmail.com>2026-04-13 19:49:27 -0400
commitee90e8e380190468a87ab5df3597dafd4f5def53 (patch)
tree9608e19c92e484c732aebaefffeebf091f108fe5
parentab324956d7823fb7a20123c1846075e3a04dfe0e (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.c7
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;
}