Skip to content

Commit b294cc6

Browse files
committed
a
1 parent c93cba5 commit b294cc6

21 files changed

+260
-174
lines changed

.github/workflows/pr_push.yml

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,9 @@ permissions:
1616
contents: read
1717

1818
jobs:
19-
CodeChecks:
20-
uses: ./.github/workflows/reusable_checks.yml
21-
DocsBuild:
22-
uses: ./.github/workflows/reusable_docs_build.yml
23-
FastBuild:
24-
name: Fast builds
25-
needs: [CodeChecks, DocsBuild]
26-
uses: ./.github/workflows/reusable_fast.yml
2719
Build:
2820
name: Basic builds
29-
needs: [FastBuild]
3021
uses: ./.github/workflows/reusable_basic.yml
31-
DevDax:
32-
needs: [FastBuild]
33-
uses: ./.github/workflows/reusable_dax.yml
34-
MultiNuma:
35-
needs: [FastBuild]
36-
uses: ./.github/workflows/reusable_multi_numa.yml
3722
L0:
3823
needs: [Build]
3924
uses: ./.github/workflows/reusable_gpu.yml
@@ -47,13 +32,8 @@ jobs:
4732
name: "CUDA"
4833
shared_lib: "['ON']"
4934
Sanitizers:
50-
needs: [FastBuild]
35+
needs: [Build]
5136
uses: ./.github/workflows/reusable_sanitizers.yml
52-
QEMU:
53-
needs: [FastBuild]
54-
uses: ./.github/workflows/reusable_qemu.yml
55-
with:
56-
short_run: true
5737
ProxyLib:
5838
needs: [Build]
5939
uses: ./.github/workflows/reusable_proxy_lib.yml
@@ -63,15 +43,15 @@ jobs:
6343
Coverage:
6444
# total coverage (on upstream only)
6545
if: github.repository == 'oneapi-src/unified-memory-framework'
66-
needs: [Build, DevDax, L0, CUDA, MultiNuma, QEMU, ProxyLib]
46+
needs: [Build, L0, CUDA, ProxyLib]
6747
uses: ./.github/workflows/reusable_coverage.yml
6848
secrets: inherit
6949
with:
7050
trigger: "${{github.event_name}}"
7151
Coverage_partial:
7252
# partial coverage (on forks)
7353
if: github.repository != 'oneapi-src/unified-memory-framework'
74-
needs: [Build, QEMU, ProxyLib]
54+
needs: [Build, ProxyLib]
7555
uses: ./.github/workflows/reusable_coverage.yml
7656
CodeQL:
7757
needs: [Build]

cmake/helpers.cmake

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,14 @@ function(add_umf_target_compile_options name)
273273
# disable warning 6326: Potential comparison of a constant
274274
# with another constant
275275
/wd6326
276-
# disable 4200 warning: nonstandard extension used:
276+
# disable warning 28112: a variable (ptr) which is accessed
277+
# via an Interlocked function must always be accessed via an
278+
# Interlocked function
279+
/wd28112
280+
# disable warning 4324: structure was padded due to
281+
# alignment specifier
282+
/wd4324
283+
# disable warning 4200: nonstandard extension used:
277284
# zero-sized array in struct/union
278285
/wd4200)
279286
if(UMF_DEVELOPER_MODE)

src/critnib/critnib.c

Lines changed: 34 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
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
@@ -118,7 +118,8 @@ struct critnib_leaf {
118118
};
119119

120120
struct critnib {
121-
struct critnib_node *root;
121+
CACHE_ALIGNED struct critnib_node *root;
122+
CACHE_ALIGNED uint64_t remove_count;
122123

123124
/* pool of freed nodes: singly linked list, next at child[0] */
124125
struct critnib_node *deleted_node;
@@ -128,29 +129,9 @@ struct critnib {
128129
struct critnib_node *pending_del_nodes[DELETED_LIFE];
129130
struct critnib_leaf *pending_del_leaves[DELETED_LIFE];
130131

131-
uint64_t remove_count;
132-
133132
struct utils_mutex_t mutex; /* writes/removes */
134133
};
135134

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-
154135
/*
155136
* internal: is_leaf -- check tagged pointer for leafness
156137
*/
@@ -180,7 +161,7 @@ static inline unsigned slice_index(word key, sh_t shift) {
180161
* critnib_new -- allocates a new critnib structure
181162
*/
182163
struct critnib *critnib_new(void) {
183-
struct critnib *c = umf_ba_global_alloc(sizeof(struct critnib));
164+
struct critnib *c = umf_ba_global_aligned_alloc(sizeof(struct critnib), 64);
184165
if (!c) {
185166
return NULL;
186167
}
@@ -272,7 +253,7 @@ static void free_node(struct critnib *__restrict c,
272253
*/
273254
static struct critnib_node *alloc_node(struct critnib *__restrict c) {
274255
if (!c->deleted_node) {
275-
return umf_ba_global_alloc(sizeof(struct critnib_node));
256+
return umf_ba_global_aligned_alloc(sizeof(struct critnib_node), 64);
276257
}
277258

278259
struct critnib_node *n = c->deleted_node;
@@ -303,7 +284,7 @@ static void free_leaf(struct critnib *__restrict c,
303284
*/
304285
static struct critnib_leaf *alloc_leaf(struct critnib *__restrict c) {
305286
if (!c->deleted_leaf) {
306-
return umf_ba_global_alloc(sizeof(struct critnib_leaf));
287+
return umf_ba_global_aligned_alloc(sizeof(struct critnib_leaf), 64);
307288
}
308289

309290
struct critnib_leaf *k = c->deleted_leaf;
@@ -343,10 +324,8 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
343324

344325
struct critnib_node *n = c->root;
345326
if (!n) {
346-
store(&c->root, kn);
347-
327+
utils_atomic_store_release_ptr((void **)&c->root, kn);
348328
utils_mutex_unlock(&c->mutex);
349-
350329
return 0;
351330
}
352331

@@ -361,7 +340,8 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
361340

362341
if (!n) {
363342
n = prev;
364-
store(&n->child[slice_index(key, n->shift)], kn);
343+
utils_atomic_store_release_ptr(
344+
(void **)&n->child[slice_index(key, n->shift)], kn);
365345

366346
utils_mutex_unlock(&c->mutex);
367347

@@ -406,7 +386,7 @@ int critnib_insert(struct critnib *c, word key, void *value, int update) {
406386
m->child[slice_index(path, sh)] = n;
407387
m->shift = sh;
408388
m->path = key & path_mask(sh);
409-
store(parent, m);
389+
utils_atomic_store_release_ptr((void **)parent, m);
410390

411391
utils_mutex_unlock(&c->mutex);
412392

@@ -427,7 +407,8 @@ void *critnib_remove(struct critnib *c, word key) {
427407
goto not_found;
428408
}
429409

430-
word del = (utils_atomic_increment(&c->remove_count) - 1) % DELETED_LIFE;
410+
word del =
411+
(utils_atomic_increment_u64(&c->remove_count) - 1) % DELETED_LIFE;
431412
free_node(c, c->pending_del_nodes[del]);
432413
free_leaf(c, c->pending_del_leaves[del]);
433414
c->pending_del_nodes[del] = NULL;
@@ -436,7 +417,7 @@ void *critnib_remove(struct critnib *c, word key) {
436417
if (is_leaf(n)) {
437418
k = to_leaf(n);
438419
if (k->key == key) {
439-
store(&c->root, NULL);
420+
utils_atomic_store_release_ptr((void **)&c->root, NULL);
440421
goto del_leaf;
441422
}
442423

@@ -466,7 +447,8 @@ void *critnib_remove(struct critnib *c, word key) {
466447
goto not_found;
467448
}
468449

469-
store(&n->child[slice_index(key, n->shift)], NULL);
450+
utils_atomic_store_release_ptr(
451+
(void **)&n->child[slice_index(key, n->shift)], NULL);
470452

471453
/* Remove the node if there's only one remaining child. */
472454
int ochild = -1;
@@ -482,7 +464,7 @@ void *critnib_remove(struct critnib *c, word key) {
482464

483465
ASSERTne(ochild, -1);
484466

485-
store(n_parent, n->child[ochild]);
467+
utils_atomic_store_release_ptr((void **)n_parent, n->child[ochild]);
486468
c->pending_del_nodes[del] = n;
487469

488470
del_leaf:
@@ -511,22 +493,23 @@ void *critnib_get(struct critnib *c, word key) {
511493
do {
512494
struct critnib_node *n;
513495

514-
load64(&c->remove_count, &wrs1);
515-
load(&c->root, &n);
496+
utils_atomic_load_acquire_u64(&c->remove_count, &wrs1);
497+
utils_atomic_load_acquire_ptr((void **)&c->root, (void **)&n);
516498

517499
/*
518500
* critbit algorithm: dive into the tree, looking at nothing but
519501
* each node's critical bit^H^H^Hnibble. This means we risk
520502
* going wrong way if our path is missing, but that's ok...
521503
*/
522504
while (n && !is_leaf(n)) {
523-
load(&n->child[slice_index(key, n->shift)], &n);
505+
utils_atomic_load_acquire_ptr(
506+
(void **)&n->child[slice_index(key, n->shift)], (void **)&n);
524507
}
525508

526509
/* ... as we check it at the end. */
527510
struct critnib_leaf *k = to_leaf(n);
528511
res = (n && k->key == key) ? k->value : NULL;
529-
load64(&c->remove_count, &wrs2);
512+
utils_atomic_load_acquire_u64(&c->remove_count, &wrs2);
530513
} while (wrs1 + DELETED_LIFE <= wrs2);
531514

532515
return res;
@@ -597,7 +580,7 @@ static struct critnib_leaf *find_le(struct critnib_node *__restrict n,
597580
/* recursive call: follow the path */
598581
{
599582
struct critnib_node *m;
600-
load(&n->child[nib], &m);
583+
utils_atomic_load_acquire_ptr((void **)&n->child[nib], (void **)&m);
601584
struct critnib_leaf *k = find_le(m, key);
602585
if (k) {
603586
return k;
@@ -611,7 +594,7 @@ static struct critnib_leaf *find_le(struct critnib_node *__restrict n,
611594
*/
612595
for (; nib > 0; nib--) {
613596
struct critnib_node *m;
614-
load(&n->child[nib - 1], &m);
597+
utils_atomic_load_acquire_ptr((void **)&n->child[nib - 1], (void **)&m);
615598
if (m) {
616599
n = m;
617600
if (is_leaf(n)) {
@@ -635,12 +618,12 @@ void *critnib_find_le(struct critnib *c, word key) {
635618
void *res;
636619

637620
do {
638-
load64(&c->remove_count, &wrs1);
621+
utils_atomic_load_acquire_u64(&c->remove_count, &wrs1);
639622
struct critnib_node *n; /* avoid a subtle TOCTOU */
640-
load(&c->root, &n);
623+
utils_atomic_load_acquire_ptr((void **)&c->root, (void **)&n);
641624
struct critnib_leaf *k = n ? find_le(n, key) : NULL;
642625
res = k ? k->value : NULL;
643-
load64(&c->remove_count, &wrs2);
626+
utils_atomic_load_acquire_u64(&c->remove_count, &wrs2);
644627
} while (wrs1 + DELETED_LIFE <= wrs2);
645628

646629
return res;
@@ -694,7 +677,7 @@ static struct critnib_leaf *find_ge(struct critnib_node *__restrict n,
694677
unsigned nib = slice_index(key, n->shift);
695678
{
696679
struct critnib_node *m;
697-
load(&n->child[nib], &m);
680+
utils_atomic_load_acquire_ptr((void **)&n->child[nib], (void **)&m);
698681
struct critnib_leaf *k = find_ge(m, key);
699682
if (k) {
700683
return k;
@@ -703,7 +686,7 @@ static struct critnib_leaf *find_ge(struct critnib_node *__restrict n,
703686

704687
for (; nib < NIB; nib++) {
705688
struct critnib_node *m;
706-
load(&n->child[nib + 1], &m);
689+
utils_atomic_load_acquire_ptr((void **)&n->child[nib + 1], (void **)&m);
707690
if (m) {
708691
n = m;
709692
if (is_leaf(n)) {
@@ -741,17 +724,19 @@ int critnib_find(struct critnib *c, uintptr_t key, enum find_dir_t dir,
741724
}
742725

743726
do {
744-
load64(&c->remove_count, &wrs1);
727+
utils_atomic_load_acquire_u64(&c->remove_count, &wrs1);
745728
struct critnib_node *n;
746-
load(&c->root, &n);
729+
utils_atomic_load_acquire_ptr((void **)&c->root, (void **)&n);
747730

748731
if (dir < 0) {
749732
k = find_le(n, key);
750733
} else if (dir > 0) {
751734
k = find_ge(n, key);
752735
} else {
753736
while (n && !is_leaf(n)) {
754-
load(&n->child[slice_index(key, n->shift)], &n);
737+
utils_atomic_load_acquire_ptr(
738+
(void **)&n->child[slice_index(key, n->shift)],
739+
(void **)&n);
755740
}
756741

757742
struct critnib_leaf *kk = to_leaf(n);
@@ -761,7 +746,7 @@ int critnib_find(struct critnib *c, uintptr_t key, enum find_dir_t dir,
761746
_rkey = k->key;
762747
_rvalue = k->value;
763748
}
764-
load64(&c->remove_count, &wrs2);
749+
utils_atomic_load_acquire_u64(&c->remove_count, &wrs2);
765750
} while (wrs1 + DELETED_LIFE <= wrs2);
766751

767752
if (k) {

src/ipc_cache.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ typedef struct ipc_opened_cache_entry_t *hash_map_t;
2828
typedef struct ipc_opened_cache_entry_t *lru_list_t;
2929

3030
typedef struct ipc_opened_cache_entry_t {
31+
uint64_t ref_count;
3132
UT_hash_handle hh;
3233
struct ipc_opened_cache_entry_t *next, *prev;
3334
ipc_opened_cache_key_t key;
34-
uint64_t ref_count;
3535
uint64_t handle_id;
3636
hash_map_t
3737
*hash_table; // pointer to the hash table to which the entry belongs
@@ -70,6 +70,7 @@ umf_result_t umfIpcCacheGlobalInit(void) {
7070
goto err_cache_global_free;
7171
}
7272

73+
// TODO: create aligned-allocator
7374
cache_global->cache_allocator =
7475
umf_ba_create(sizeof(ipc_opened_cache_entry_t));
7576
if (!cache_global->cache_allocator) {
@@ -232,7 +233,7 @@ umf_result_t umfIpcOpenedCacheGet(ipc_opened_cache_handle_t cache,
232233

233234
exit:
234235
if (ret == UMF_RESULT_SUCCESS) {
235-
utils_atomic_increment(&entry->ref_count);
236+
utils_atomic_increment_u64(&entry->ref_count);
236237
*retEntry = &entry->value;
237238
}
238239

src/libumf.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424

2525
umf_memory_tracker_handle_t TRACKER = NULL;
2626

27-
static unsigned long long umfRefCount = 0;
27+
CACHE_ALIGNED static uint64_t umfRefCount = 0;
2828

2929
int umfInit(void) {
30-
if (utils_fetch_and_add64(&umfRefCount, 1) == 0) {
30+
if (utils_fetch_and_add_u64(&umfRefCount, 1) == 0) {
3131
utils_log_init();
3232
TRACKER = umfMemoryTrackerCreate();
3333
if (!TRACKER) {
@@ -54,7 +54,7 @@ int umfInit(void) {
5454
}
5555

5656
void umfTearDown(void) {
57-
if (utils_fetch_and_add64(&umfRefCount, -1) == 1) {
57+
if (utils_fetch_and_sub_u64(&umfRefCount, 1) == 1) {
5858
#if !defined(_WIN32) && !defined(UMF_NO_HWLOC)
5959
umfMemspaceHostAllDestroy();
6060
umfMemspaceHighestCapacityDestroy();

0 commit comments

Comments
 (0)