Skip to content

Commit 6b3a124

Browse files
authored
Merge pull request #1225 from ldorau/Use_atomics_to_fix_hopefully_all_ASAN_data_races_in_critnib
Use atomics to fix ASAN data races in critnib
2 parents ebcbc07 + 44a0afd commit 6b3a124

File tree

1 file changed

+20
-15
lines changed

1 file changed

+20
-15
lines changed

src/critnib/critnib.c

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,8 @@ static void free_node(struct critnib *__restrict c,
246246
}
247247

248248
ASSERT(!is_leaf(n));
249-
n->child[0] = c->deleted_node;
250-
c->deleted_node = n;
249+
utils_atomic_store_release_ptr((void **)&n->child[0], c->deleted_node);
250+
utils_atomic_store_release_ptr((void **)&c->deleted_node, n);
251251
}
252252

253253
/*
@@ -277,8 +277,8 @@ static void free_leaf(struct critnib *__restrict c,
277277
return;
278278
}
279279

280-
k->value = c->deleted_leaf;
281-
c->deleted_leaf = k;
280+
utils_atomic_store_release_ptr((void **)&k->value, c->deleted_leaf);
281+
utils_atomic_store_release_ptr((void **)&c->deleted_leaf, k);
282282
}
283283

284284
/*
@@ -319,8 +319,8 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
319319

320320
utils_annotate_memory_no_check(k, sizeof(struct critnib_leaf));
321321

322-
k->key = key;
323-
k->value = value;
322+
utils_atomic_store_release_ptr((void **)&k->key, (void *)key);
323+
utils_atomic_store_release_ptr((void **)&k->value, value);
324324

325325
struct critnib_node *kn = (void *)((word)k | 1);
326326

@@ -358,7 +358,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
358358
free_leaf(c, to_leaf(kn));
359359

360360
if (update) {
361-
to_leaf(n)->value = value;
361+
utils_atomic_store_release_ptr(&to_leaf(n)->value, value);
362362
utils_mutex_unlock(&c->mutex);
363363
return 0;
364364
} else {
@@ -381,13 +381,14 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
381381
utils_annotate_memory_no_check(m, sizeof(struct critnib_node));
382382

383383
for (int i = 0; i < SLNODES; i++) {
384-
m->child[i] = NULL;
384+
utils_atomic_store_release_ptr((void *)&m->child[i], NULL);
385385
}
386386

387-
m->child[slice_index(key, sh)] = kn;
388-
m->child[slice_index(path, sh)] = n;
387+
utils_atomic_store_release_ptr((void *)&m->child[slice_index(key, sh)], kn);
388+
utils_atomic_store_release_ptr((void *)&m->child[slice_index(path, sh)], n);
389389
m->shift = sh;
390-
m->path = key & path_mask(sh);
390+
utils_atomic_store_release_u64((void *)&m->path, key & path_mask(sh));
391+
391392
utils_atomic_store_release_ptr((void **)parent, m);
392393

393394
utils_mutex_unlock(&c->mutex);
@@ -569,12 +570,15 @@ static struct critnib_leaf *find_le(struct critnib_node *__restrict n,
569570
* that shift points at the nib's lower rather than upper edge, so it
570571
* needs to be masked away as well.
571572
*/
572-
if ((key ^ n->path) >> (n->shift) & ~NIB) {
573+
word path;
574+
sh_t shift = n->shift;
575+
utils_atomic_load_acquire_u64((uint64_t *)&n->path, (uint64_t *)&path);
576+
if ((key ^ path) >> (shift) & ~NIB) {
573577
/*
574578
* subtree is too far to the left?
575579
* -> its rightmost value is good
576580
*/
577-
if (n->path < key) {
581+
if (path < key) {
578582
return find_predecessor(n);
579583
}
580584

@@ -759,8 +763,9 @@ int critnib_find(struct critnib *c, uintptr_t key, enum find_dir_t dir,
759763
k = (n && kk->key == key) ? kk : NULL;
760764
}
761765
if (k) {
762-
_rkey = k->key;
763-
_rvalue = k->value;
766+
utils_atomic_load_acquire_u64((uint64_t *)&k->key,
767+
(uint64_t *)&_rkey);
768+
utils_atomic_load_acquire_ptr(&k->value, (void **)&_rvalue);
764769
}
765770
utils_atomic_load_acquire_u64(&c->remove_count, &wrs2);
766771
} while (wrs1 + DELETED_LIFE <= wrs2);

0 commit comments

Comments
 (0)