This source file includes following definitions.
- sshmem_ucx_shadow_is_free
- sshmem_ucx_shadow_set_elem
- sshmem_ucx_shadow_create
- sshmem_ucx_shadow_destroy
- sshmem_ucx_shadow_alloc
- sshmem_ucx_shadow_merge_blocks
- sshmem_ucx_shadow_realloc
- sshmem_ucx_shadow_free
- sshmem_ucx_shadow_size
1
2
3
4
5
6
7
8
9
10
11 #include "oshmem_config.h"
12
13 #include "oshmem/mca/sshmem/sshmem.h"
14 #include "oshmem/include/shmemx.h"
15 #include "oshmem/mca/sshmem/base/base.h"
16
17 #include "sshmem_ucx.h"
18
19 #define SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE 0x1
20
21 typedef struct sshmem_ucx_shadow_alloc_elem {
22 unsigned flags;
23 unsigned block_size;
24 } sshmem_ucx_shadow_alloc_elem_t;
25
26 struct sshmem_ucx_shadow_allocator {
27 size_t num_elems;
28 sshmem_ucx_shadow_alloc_elem_t elems[];
29 };
30
31 static int sshmem_ucx_shadow_is_free(sshmem_ucx_shadow_alloc_elem_t *elem)
32 {
33 return elem->flags & SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE;
34 }
35
36 static void sshmem_ucx_shadow_set_elem(sshmem_ucx_shadow_alloc_elem_t *elem,
37 unsigned flags, unsigned block_size)
38 {
39 elem->flags = flags;
40 elem->block_size = block_size;
41 }
42
43 sshmem_ucx_shadow_allocator_t *sshmem_ucx_shadow_create(unsigned count)
44 {
45 sshmem_ucx_shadow_allocator_t *allocator;
46
47 allocator = calloc(1, sizeof(*allocator) +
48 count * sizeof(*allocator->elems));
49 if (allocator) {
50
51 sshmem_ucx_shadow_set_elem(&allocator->elems[0],
52 SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE, count);
53 allocator->num_elems = count;
54 }
55
56 return allocator;
57 }
58
59 void sshmem_ucx_shadow_destroy(sshmem_ucx_shadow_allocator_t *allocator)
60 {
61 free(allocator);
62 }
63
64 int sshmem_ucx_shadow_alloc(sshmem_ucx_shadow_allocator_t *allocator,
65 unsigned count, unsigned *index)
66 {
67 sshmem_ucx_shadow_alloc_elem_t *end = &allocator->elems[allocator->num_elems];
68 sshmem_ucx_shadow_alloc_elem_t *elem;
69
70 assert(count > 0);
71
72 for (elem = &allocator->elems[0]; elem < end; elem += elem->block_size) {
73 if (sshmem_ucx_shadow_is_free(elem) && (elem->block_size >= count)) {
74
75 if (elem->block_size > count) {
76
77 sshmem_ucx_shadow_set_elem(elem + count,
78 SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE,
79 elem->block_size - count);
80 }
81
82
83 sshmem_ucx_shadow_set_elem(elem, 0, count);
84 *index = elem - &allocator->elems[0];
85 return OSHMEM_SUCCESS;
86 }
87 }
88
89 return OSHMEM_ERR_OUT_OF_RESOURCE;
90 }
91
92 static void sshmem_ucx_shadow_merge_blocks(sshmem_ucx_shadow_allocator_t *allocator)
93 {
94 sshmem_ucx_shadow_alloc_elem_t *elem = &allocator->elems[0];
95 sshmem_ucx_shadow_alloc_elem_t *end = &allocator->elems[allocator->num_elems];
96 sshmem_ucx_shadow_alloc_elem_t *next_elem;
97
98 while ( (next_elem = (elem + elem->block_size)) < end) {
99 if (sshmem_ucx_shadow_is_free(elem) && sshmem_ucx_shadow_is_free(next_elem)) {
100
101 elem->block_size += next_elem->block_size;
102
103 sshmem_ucx_shadow_set_elem(next_elem, 0, 0);
104 } else {
105 elem = next_elem;
106 }
107 }
108 }
109
110
111
112 int sshmem_ucx_shadow_realloc(sshmem_ucx_shadow_allocator_t *allocator,
113 unsigned count, unsigned old_index, unsigned *index,
114 int *inplace)
115 {
116 sshmem_ucx_shadow_alloc_elem_t *elem = &allocator->elems[old_index];
117 unsigned old_count = elem->block_size;
118 sshmem_ucx_shadow_alloc_elem_t *end;
119 sshmem_ucx_shadow_alloc_elem_t *next;
120
121 assert(count > 0);
122 assert(!sshmem_ucx_shadow_is_free(elem));
123
124 *inplace = 1;
125
126 if (count == old_count) {
127 *index = old_index;
128 return OSHMEM_SUCCESS;
129 }
130
131 if (count < old_count) {
132
133
134 sshmem_ucx_shadow_set_elem(elem + count,
135 SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE,
136 elem->block_size - count);
137 elem->block_size = count;
138 *index = old_index;
139 sshmem_ucx_shadow_merge_blocks(allocator);
140 return OSHMEM_SUCCESS;
141 }
142
143 assert(count > old_count);
144
145 end = &allocator->elems[allocator->num_elems];
146 next = &elem[old_count];
147
148 if ((next < end) &&
149 sshmem_ucx_shadow_is_free(next) &&
150 (old_count + next->block_size >= count))
151 {
152 assert(elem < next);
153 assert(elem + count > next);
154 assert(elem + count <= end);
155 assert(next + next->block_size <= end);
156
157 if (old_count + next->block_size > count) {
158 sshmem_ucx_shadow_set_elem(elem + count, SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE,
159 old_count + next->block_size - count);
160 }
161
162 sshmem_ucx_shadow_set_elem(next, 0, 0);
163 elem->block_size = count;
164 *index = old_index;
165 return OSHMEM_SUCCESS;
166 }
167
168 *inplace = 0;
169 return sshmem_ucx_shadow_alloc(allocator, count, index);
170 }
171
172 int sshmem_ucx_shadow_free(sshmem_ucx_shadow_allocator_t *allocator,
173 unsigned index)
174 {
175 sshmem_ucx_shadow_alloc_elem_t *elem = &allocator->elems[index];
176
177 elem->flags |= SSHMEM_UCX_SHADOW_ELEM_FLAG_FREE;
178 sshmem_ucx_shadow_merge_blocks(allocator);
179 return OSHMEM_SUCCESS;
180 }
181
182 unsigned sshmem_ucx_shadow_size(sshmem_ucx_shadow_allocator_t *allocator,
183 unsigned index)
184 {
185 sshmem_ucx_shadow_alloc_elem_t *elem = &allocator->elems[index];
186
187 assert(!sshmem_ucx_shadow_is_free(elem));
188 return elem->block_size;
189 }