11/*
22 *
3- * Copyright (C) 2023-2024 Intel Corporation
3+ * Copyright (C) 2023-2025 Intel Corporation
44 *
55 * Under the Apache License v2.0 with LLVM Exceptions. See LICENSE.TXT.
66 * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -133,24 +133,6 @@ struct critnib {
133133 struct utils_mutex_t mutex ; /* writes/removes */
134134};
135135
136- /*
137- * atomic load
138- */
139- static void load (void * src , void * dst ) {
140- utils_atomic_load_acquire ((word * )src , (word * )dst );
141- }
142-
143- static void load64 (uint64_t * src , uint64_t * dst ) {
144- utils_atomic_load_acquire (src , dst );
145- }
146-
147- /*
148- * atomic store
149- */
150- static void store (void * dst , void * src ) {
151- utils_atomic_store_release ((word * )dst , (word )src );
152- }
153-
154136/*
155137 * internal: is_leaf -- check tagged pointer for leafness
156138 */
@@ -180,7 +162,7 @@ static inline unsigned slice_index(word key, sh_t shift) {
180162 * critnib_new -- allocates a new critnib structure
181163 */
182164struct critnib * critnib_new (void ) {
183- struct critnib * c = umf_ba_global_alloc (sizeof (struct critnib ));
165+ struct critnib * c = umf_ba_global_aligned_alloc (sizeof (struct critnib ), 8 );
184166 if (!c ) {
185167 return NULL ;
186168 }
@@ -192,8 +174,8 @@ struct critnib *critnib_new(void) {
192174 goto err_free_critnib ;
193175 }
194176
195- VALGRIND_HG_DRD_DISABLE_CHECKING (& c -> root , sizeof (c -> root ));
196- VALGRIND_HG_DRD_DISABLE_CHECKING (& c -> remove_count , sizeof (c -> remove_count ));
177+ utils_annotate_memory_no_check (& c -> root , sizeof (c -> root ));
178+ utils_annotate_memory_no_check (& c -> remove_count , sizeof (c -> remove_count ));
197179
198180 return c ;
199181err_free_critnib :
@@ -272,13 +254,13 @@ static void free_node(struct critnib *__restrict c,
272254 */
273255static struct critnib_node * alloc_node (struct critnib * __restrict c ) {
274256 if (!c -> deleted_node ) {
275- return umf_ba_global_alloc (sizeof (struct critnib_node ));
257+ return umf_ba_global_aligned_alloc (sizeof (struct critnib_node ), 8 );
276258 }
277259
278260 struct critnib_node * n = c -> deleted_node ;
279261
280262 c -> deleted_node = n -> child [0 ];
281- VALGRIND_ANNOTATE_NEW_MEMORY (n , sizeof (* n ));
263+ utils_annotate_memory_new (n , sizeof (* n ));
282264
283265 return n ;
284266}
@@ -303,13 +285,13 @@ static void free_leaf(struct critnib *__restrict c,
303285 */
304286static struct critnib_leaf * alloc_leaf (struct critnib * __restrict c ) {
305287 if (!c -> deleted_leaf ) {
306- return umf_ba_global_alloc (sizeof (struct critnib_leaf ));
288+ return umf_ba_global_aligned_alloc (sizeof (struct critnib_leaf ), 8 );
307289 }
308290
309291 struct critnib_leaf * k = c -> deleted_leaf ;
310292
311293 c -> deleted_leaf = k -> value ;
312- VALGRIND_ANNOTATE_NEW_MEMORY (k , sizeof (* k ));
294+ utils_annotate_memory_new (k , sizeof (* k ));
313295
314296 return k ;
315297}
@@ -334,7 +316,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
334316 return ENOMEM ;
335317 }
336318
337- VALGRIND_HG_DRD_DISABLE_CHECKING (k , sizeof (struct critnib_leaf ));
319+ utils_annotate_memory_no_check (k , sizeof (struct critnib_leaf ));
338320
339321 k -> key = key ;
340322 k -> value = value ;
@@ -343,10 +325,8 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
343325
344326 struct critnib_node * n = c -> root ;
345327 if (!n ) {
346- store (& c -> root , kn );
347-
328+ utils_atomic_store_release_ptr ((void * * )& c -> root , kn );
348329 utils_mutex_unlock (& c -> mutex );
349-
350330 return 0 ;
351331 }
352332
@@ -361,7 +341,8 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
361341
362342 if (!n ) {
363343 n = prev ;
364- store (& n -> child [slice_index (key , n -> shift )], kn );
344+ utils_atomic_store_release_ptr (
345+ (void * * )& n -> child [slice_index (key , n -> shift )], kn );
365346
366347 utils_mutex_unlock (& c -> mutex );
367348
@@ -396,7 +377,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
396377
397378 return ENOMEM ;
398379 }
399- VALGRIND_HG_DRD_DISABLE_CHECKING (m , sizeof (struct critnib_node ));
380+ utils_annotate_memory_no_check (m , sizeof (struct critnib_node ));
400381
401382 for (int i = 0 ; i < SLNODES ; i ++ ) {
402383 m -> child [i ] = NULL ;
@@ -406,7 +387,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
406387 m -> child [slice_index (path , sh )] = n ;
407388 m -> shift = sh ;
408389 m -> path = key & path_mask (sh );
409- store ( parent , m );
390+ utils_atomic_store_release_ptr (( void * * ) parent , m );
410391
411392 utils_mutex_unlock (& c -> mutex );
412393
@@ -427,7 +408,8 @@ void *critnib_remove(struct critnib *c, word key) {
427408 goto not_found ;
428409 }
429410
430- word del = (utils_atomic_increment (& c -> remove_count ) - 1 ) % DELETED_LIFE ;
411+ word del =
412+ (utils_atomic_increment_u64 (& c -> remove_count ) - 1 ) % DELETED_LIFE ;
431413 free_node (c , c -> pending_del_nodes [del ]);
432414 free_leaf (c , c -> pending_del_leaves [del ]);
433415 c -> pending_del_nodes [del ] = NULL ;
@@ -436,7 +418,7 @@ void *critnib_remove(struct critnib *c, word key) {
436418 if (is_leaf (n )) {
437419 k = to_leaf (n );
438420 if (k -> key == key ) {
439- store ( & c -> root , NULL );
421+ utils_atomic_store_release_ptr (( void * * ) & c -> root , NULL );
440422 goto del_leaf ;
441423 }
442424
@@ -466,7 +448,8 @@ void *critnib_remove(struct critnib *c, word key) {
466448 goto not_found ;
467449 }
468450
469- store (& n -> child [slice_index (key , n -> shift )], NULL );
451+ utils_atomic_store_release_ptr (
452+ (void * * )& n -> child [slice_index (key , n -> shift )], NULL );
470453
471454 /* Remove the node if there's only one remaining child. */
472455 int ochild = -1 ;
@@ -482,7 +465,7 @@ void *critnib_remove(struct critnib *c, word key) {
482465
483466 ASSERTne (ochild , -1 );
484467
485- store ( n_parent , n -> child [ochild ]);
468+ utils_atomic_store_release_ptr (( void * * ) n_parent , n -> child [ochild ]);
486469 c -> pending_del_nodes [del ] = n ;
487470
488471del_leaf :
@@ -511,22 +494,23 @@ void *critnib_get(struct critnib *c, word key) {
511494 do {
512495 struct critnib_node * n ;
513496
514- load64 (& c -> remove_count , & wrs1 );
515- load ( & c -> root , & n );
497+ utils_atomic_load_acquire_u64 (& c -> remove_count , & wrs1 );
498+ utils_atomic_load_acquire_ptr (( void * * ) & c -> root , ( void * * ) & n );
516499
517500 /*
518501 * critbit algorithm: dive into the tree, looking at nothing but
519502 * each node's critical bit^H^H^Hnibble. This means we risk
520503 * going wrong way if our path is missing, but that's ok...
521504 */
522505 while (n && !is_leaf (n )) {
523- load (& n -> child [slice_index (key , n -> shift )], & n );
506+ utils_atomic_load_acquire_ptr (
507+ (void * * )& n -> child [slice_index (key , n -> shift )], (void * * )& n );
524508 }
525509
526510 /* ... as we check it at the end. */
527511 struct critnib_leaf * k = to_leaf (n );
528512 res = (n && k -> key == key ) ? k -> value : NULL ;
529- load64 (& c -> remove_count , & wrs2 );
513+ utils_atomic_load_acquire_u64 (& c -> remove_count , & wrs2 );
530514 } while (wrs1 + DELETED_LIFE <= wrs2 );
531515
532516 return res ;
@@ -597,7 +581,7 @@ static struct critnib_leaf *find_le(struct critnib_node *__restrict n,
597581 /* recursive call: follow the path */
598582 {
599583 struct critnib_node * m ;
600- load ( & n -> child [nib ], & m );
584+ utils_atomic_load_acquire_ptr (( void * * ) & n -> child [nib ], ( void * * ) & m );
601585 struct critnib_leaf * k = find_le (m , key );
602586 if (k ) {
603587 return k ;
@@ -611,7 +595,7 @@ static struct critnib_leaf *find_le(struct critnib_node *__restrict n,
611595 */
612596 for (; nib > 0 ; nib -- ) {
613597 struct critnib_node * m ;
614- load ( & n -> child [nib - 1 ], & m );
598+ utils_atomic_load_acquire_ptr (( void * * ) & n -> child [nib - 1 ], ( void * * ) & m );
615599 if (m ) {
616600 n = m ;
617601 if (is_leaf (n )) {
@@ -635,12 +619,12 @@ void *critnib_find_le(struct critnib *c, word key) {
635619 void * res ;
636620
637621 do {
638- load64 (& c -> remove_count , & wrs1 );
622+ utils_atomic_load_acquire_u64 (& c -> remove_count , & wrs1 );
639623 struct critnib_node * n ; /* avoid a subtle TOCTOU */
640- load ( & c -> root , & n );
624+ utils_atomic_load_acquire_ptr (( void * * ) & c -> root , ( void * * ) & n );
641625 struct critnib_leaf * k = n ? find_le (n , key ) : NULL ;
642626 res = k ? k -> value : NULL ;
643- load64 (& c -> remove_count , & wrs2 );
627+ utils_atomic_load_acquire_u64 (& c -> remove_count , & wrs2 );
644628 } while (wrs1 + DELETED_LIFE <= wrs2 );
645629
646630 return res ;
@@ -653,7 +637,9 @@ static struct critnib_leaf *find_successor(struct critnib_node *__restrict n) {
653637 while (1 ) {
654638 unsigned nib ;
655639 for (nib = 0 ; nib <= NIB ; nib ++ ) {
656- if (n -> child [nib ]) {
640+ struct critnib_node * m ;
641+ utils_atomic_load_acquire_ptr ((void * * )& n -> child [nib ], (void * * )& m );
642+ if (m ) {
657643 break ;
658644 }
659645 }
@@ -662,7 +648,7 @@ static struct critnib_leaf *find_successor(struct critnib_node *__restrict n) {
662648 return NULL ;
663649 }
664650
665- n = n -> child [nib ];
651+ utils_atomic_load_acquire_ptr (( void * * ) & n -> child [nib ], ( void * * ) & n ) ;
666652 if (is_leaf (n )) {
667653 return to_leaf (n );
668654 }
@@ -694,7 +680,7 @@ static struct critnib_leaf *find_ge(struct critnib_node *__restrict n,
694680 unsigned nib = slice_index (key , n -> shift );
695681 {
696682 struct critnib_node * m ;
697- load ( & n -> child [nib ], & m );
683+ utils_atomic_load_acquire_ptr (( void * * ) & n -> child [nib ], ( void * * ) & m );
698684 struct critnib_leaf * k = find_ge (m , key );
699685 if (k ) {
700686 return k ;
@@ -703,7 +689,7 @@ static struct critnib_leaf *find_ge(struct critnib_node *__restrict n,
703689
704690 for (; nib < NIB ; nib ++ ) {
705691 struct critnib_node * m ;
706- load ( & n -> child [nib + 1 ], & m );
692+ utils_atomic_load_acquire_ptr (( void * * ) & n -> child [nib + 1 ], ( void * * ) & m );
707693 if (m ) {
708694 n = m ;
709695 if (is_leaf (n )) {
@@ -741,17 +727,19 @@ int critnib_find(struct critnib *c, uintptr_t key, enum find_dir_t dir,
741727 }
742728
743729 do {
744- load64 (& c -> remove_count , & wrs1 );
730+ utils_atomic_load_acquire_u64 (& c -> remove_count , & wrs1 );
745731 struct critnib_node * n ;
746- load ( & c -> root , & n );
732+ utils_atomic_load_acquire_ptr (( void * * ) & c -> root , ( void * * ) & n );
747733
748734 if (dir < 0 ) {
749735 k = find_le (n , key );
750736 } else if (dir > 0 ) {
751737 k = find_ge (n , key );
752738 } else {
753739 while (n && !is_leaf (n )) {
754- load (& n -> child [slice_index (key , n -> shift )], & n );
740+ utils_atomic_load_acquire_ptr (
741+ (void * * )& n -> child [slice_index (key , n -> shift )],
742+ (void * * )& n );
755743 }
756744
757745 struct critnib_leaf * kk = to_leaf (n );
@@ -761,7 +749,7 @@ int critnib_find(struct critnib *c, uintptr_t key, enum find_dir_t dir,
761749 _rkey = k -> key ;
762750 _rvalue = k -> value ;
763751 }
764- load64 (& c -> remove_count , & wrs2 );
752+ utils_atomic_load_acquire_u64 (& c -> remove_count , & wrs2 );
765753 } while (wrs1 + DELETED_LIFE <= wrs2 );
766754
767755 if (k ) {
0 commit comments