Skip to content

Commit e22a413

Browse files
committed
Use atomics to fix (hopefully) all ASAN data races in critnib
Signed-off-by: Lukasz Dorau <[email protected]>
1 parent d694cc8 commit e22a413

File tree

1 file changed

+30
-14
lines changed

1 file changed

+30
-14
lines changed

src/critnib/critnib.c

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -246,8 +246,10 @@ 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+
// n->child[0] = c->deleted_node;
250+
utils_atomic_store_release_ptr((void **)&n->child[0], c->deleted_node);
251+
// c->deleted_node = n;
252+
utils_atomic_store_release_ptr((void **)&c->deleted_node, n);
251253
}
252254

253255
/*
@@ -277,8 +279,10 @@ static void free_leaf(struct critnib *__restrict c,
277279
return;
278280
}
279281

280-
k->value = c->deleted_leaf;
281-
c->deleted_leaf = k;
282+
// k->value = c->deleted_leaf;
283+
utils_atomic_store_release_ptr((void **)&k->value, c->deleted_leaf);
284+
// c->deleted_leaf = k;
285+
utils_atomic_store_release_ptr((void **)&c->deleted_leaf, k);
282286
}
283287

284288
/*
@@ -319,8 +323,10 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
319323

320324
utils_annotate_memory_no_check(k, sizeof(struct critnib_leaf));
321325

322-
k->key = key;
323-
k->value = value;
326+
// k->key = key;
327+
utils_atomic_store_release_ptr((void **)&k->key, (void *)key);
328+
// k->value = value;
329+
utils_atomic_store_release_ptr((void **)&k->value, value);
324330

325331
struct critnib_node *kn = (void *)((word)k | 1);
326332

@@ -381,13 +387,18 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
381387
utils_annotate_memory_no_check(m, sizeof(struct critnib_node));
382388

383389
for (int i = 0; i < SLNODES; i++) {
384-
m->child[i] = NULL;
390+
// m->child[i] = NULL;
391+
utils_atomic_store_release_ptr((void *)&m->child[i], NULL);
385392
}
386393

387-
m->child[slice_index(key, sh)] = kn;
388-
m->child[slice_index(path, sh)] = n;
394+
// m->child[slice_index(key, sh)] = kn;
395+
utils_atomic_store_release_ptr((void *)&m->child[slice_index(key, sh)], kn);
396+
// m->child[slice_index(path, sh)] = n;
397+
utils_atomic_store_release_ptr((void *)&m->child[slice_index(path, sh)], n);
389398
m->shift = sh;
390-
m->path = key & path_mask(sh);
399+
// m->path = key & path_mask(sh);
400+
utils_atomic_store_release_u64((void *)&m->path, key & path_mask(sh));
401+
391402
utils_atomic_store_release_ptr((void **)parent, m);
392403

393404
utils_mutex_unlock(&c->mutex);
@@ -569,12 +580,15 @@ static struct critnib_leaf *find_le(struct critnib_node *__restrict n,
569580
* that shift points at the nib's lower rather than upper edge, so it
570581
* needs to be masked away as well.
571582
*/
572-
if ((key ^ n->path) >> (n->shift) & ~NIB) {
583+
word path;
584+
sh_t shift = n->shift;
585+
utils_atomic_load_acquire_u64(&n->path, &path);
586+
if ((key ^ path) >> (shift) & ~NIB) {
573587
/*
574588
* subtree is too far to the left?
575589
* -> its rightmost value is good
576590
*/
577-
if (n->path < key) {
591+
if (path < key) {
578592
return find_predecessor(n);
579593
}
580594

@@ -759,8 +773,10 @@ int critnib_find(struct critnib *c, uintptr_t key, enum find_dir_t dir,
759773
k = (n && kk->key == key) ? kk : NULL;
760774
}
761775
if (k) {
762-
_rkey = k->key;
763-
_rvalue = k->value;
776+
// _rkey = k->key;
777+
utils_atomic_load_acquire_u64(&k->key, &_rkey);
778+
// _rvalue = k->value;
779+
utils_atomic_load_acquire_ptr(&k->value, (void **)&_rvalue);
764780
}
765781
utils_atomic_load_acquire_u64(&c->remove_count, &wrs2);
766782
} while (wrs1 + DELETED_LIFE <= wrs2);

0 commit comments

Comments
 (0)