This source file includes following definitions.
- pmix_bitmap_construct
- pmix_bitmap_destruct
- pmix_bitmap_set_max_size
- pmix_bitmap_init
- pmix_bitmap_set_bit
- pmix_bitmap_clear_bit
- pmix_bitmap_is_set_bit
- pmix_bitmap_clear_all_bits
- pmix_bitmap_set_all_bits
- pmix_bitmap_find_and_set_first_unset_bit
- pmix_bitmap_bitwise_and_inplace
- pmix_bitmap_bitwise_or_inplace
- pmix_bitmap_bitwise_xor_inplace
- pmix_bitmap_are_different
- pmix_bitmap_get_string
- pmix_bitmap_num_unset_bits
- pmix_bitmap_num_set_bits
- pmix_bitmap_is_clear
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 #include <src/include/pmix_config.h>
25
26 #include <stdio.h>
27 #include <limits.h>
28
29 #include "pmix_common.h"
30 #include "src/class/pmix_bitmap.h"
31
32
33
34
35 #define SIZE_OF_BASE_TYPE 64
36
37 static void pmix_bitmap_construct(pmix_bitmap_t *bm);
38 static void pmix_bitmap_destruct(pmix_bitmap_t *bm);
39
40 PMIX_CLASS_INSTANCE(pmix_bitmap_t, pmix_object_t,
41 pmix_bitmap_construct, pmix_bitmap_destruct);
42
43
44 static void
45 pmix_bitmap_construct(pmix_bitmap_t *bm)
46 {
47 bm->bitmap = NULL;
48 bm->array_size = 0;
49 bm->max_size = INT_MAX;
50 }
51
52
53 static void
54 pmix_bitmap_destruct(pmix_bitmap_t *bm)
55 {
56 if (NULL != bm->bitmap) {
57 free(bm->bitmap);
58 bm->bitmap = NULL;
59 }
60 }
61
62
63 int pmix_bitmap_set_max_size (pmix_bitmap_t *bm, int max_size)
64 {
65 if (NULL == bm) {
66 return PMIX_ERR_BAD_PARAM;
67 }
68
69
70
71
72
73
74 bm->max_size = (int)(((size_t)max_size + SIZE_OF_BASE_TYPE - 1) / SIZE_OF_BASE_TYPE);
75
76 return PMIX_SUCCESS;
77 }
78
79
80 int
81 pmix_bitmap_init(pmix_bitmap_t *bm, int size)
82 {
83
84
85
86
87
88 if ((size <= 0) || (NULL == bm) || (size > bm->max_size)) {
89 return PMIX_ERR_BAD_PARAM;
90 }
91
92 bm->array_size = (int)(((size_t)size + SIZE_OF_BASE_TYPE - 1) / SIZE_OF_BASE_TYPE);
93 if( NULL != bm->bitmap ) {
94 free(bm->bitmap);
95 if(bm->max_size < bm->array_size)
96 bm->max_size = bm->array_size;
97 }
98 bm->bitmap = (uint64_t*) malloc(bm->array_size * sizeof(uint64_t));
99 if (NULL == bm->bitmap) {
100 return PMIX_ERR_OUT_OF_RESOURCE;
101 }
102
103 pmix_bitmap_clear_all_bits(bm);
104 return PMIX_SUCCESS;
105 }
106
107
108 int
109 pmix_bitmap_set_bit(pmix_bitmap_t *bm, int bit)
110 {
111 int index, offset, new_size;
112
113 if ((bit < 0) || (NULL == bm) || (bit > bm->max_size)) {
114 return PMIX_ERR_BAD_PARAM;
115 }
116
117 index = bit / SIZE_OF_BASE_TYPE;
118 offset = bit % SIZE_OF_BASE_TYPE;
119
120 if (index >= bm->array_size) {
121
122
123
124
125
126 new_size = index + 1;
127 if( new_size > bm->max_size )
128 new_size = bm->max_size;
129
130
131
132 bm->bitmap = (uint64_t*)realloc(bm->bitmap, new_size*sizeof(uint64_t));
133 if (NULL == bm->bitmap) {
134 return PMIX_ERR_OUT_OF_RESOURCE;
135 }
136
137
138 memset(&bm->bitmap[bm->array_size], 0, (new_size - bm->array_size) * sizeof(uint64_t));
139
140
141 bm->array_size = new_size;
142 }
143
144
145 bm->bitmap[index] |= (1UL << offset);
146
147 return PMIX_SUCCESS;
148 }
149
150
151 int
152 pmix_bitmap_clear_bit(pmix_bitmap_t *bm, int bit)
153 {
154 int index, offset;
155
156 if ((bit < 0) || NULL == bm || (bit >= (bm->array_size * SIZE_OF_BASE_TYPE))) {
157 return PMIX_ERR_BAD_PARAM;
158 }
159
160 index = bit / SIZE_OF_BASE_TYPE;
161 offset = bit % SIZE_OF_BASE_TYPE;
162
163 bm->bitmap[index] &= ~(1UL << offset);
164 return PMIX_SUCCESS;
165 }
166
167
168 bool
169 pmix_bitmap_is_set_bit(pmix_bitmap_t *bm, int bit)
170 {
171 int index, offset;
172
173 if ((bit < 0) || NULL == bm || (bit >= (bm->array_size * SIZE_OF_BASE_TYPE))) {
174 return false;
175 }
176
177 index = bit / SIZE_OF_BASE_TYPE;
178 offset = bit % SIZE_OF_BASE_TYPE;
179
180 if (0 != (bm->bitmap[index] & (1UL << offset))) {
181 return true;
182 }
183
184 return false;
185 }
186
187
188 int
189 pmix_bitmap_clear_all_bits(pmix_bitmap_t *bm)
190 {
191 if (NULL == bm) {
192 return PMIX_ERR_BAD_PARAM;
193 }
194
195 memset(bm->bitmap, 0, bm->array_size * sizeof(uint64_t));
196 return PMIX_SUCCESS;
197 }
198
199
200 int
201 pmix_bitmap_set_all_bits(pmix_bitmap_t *bm)
202 {
203 if (NULL == bm) {
204 return PMIX_ERR_BAD_PARAM;
205 }
206
207 memset(bm->bitmap, 0xff, bm->array_size * sizeof(uint64_t));
208
209 return PMIX_SUCCESS;
210 }
211
212
213 int
214 pmix_bitmap_find_and_set_first_unset_bit(pmix_bitmap_t *bm, int *position)
215 {
216 int i = 0;
217 uint64_t temp, all_ones = 0xffffffffffffffffUL;
218
219 if (NULL == bm) {
220 return PMIX_ERR_BAD_PARAM;
221 }
222
223
224 *position = 0;
225 while((i < bm->array_size) && (bm->bitmap[i] == all_ones)) {
226 ++i;
227 }
228
229 if (i == bm->array_size) {
230
231 *position = bm->array_size * SIZE_OF_BASE_TYPE;
232 return pmix_bitmap_set_bit(bm, *position);
233 }
234
235
236
237 temp = bm->bitmap[i];
238 bm->bitmap[i] |= (bm->bitmap[i] + 1);
239 temp ^= bm->bitmap[i];
240 while( !(temp & 0x1) ) {
241 ++(*position);
242 temp >>= 1;
243 }
244
245 (*position) += i * SIZE_OF_BASE_TYPE;
246 return PMIX_SUCCESS;
247 }
248
249 int pmix_bitmap_bitwise_and_inplace(pmix_bitmap_t *dest, pmix_bitmap_t *right)
250 {
251 int i;
252
253
254
255
256 if( NULL == dest || NULL == right ) {
257 return PMIX_ERR_BAD_PARAM;
258 }
259 if( dest->array_size != right->array_size ) {
260 return PMIX_ERR_BAD_PARAM;
261 }
262
263
264
265
266 for(i = 0; i < dest->array_size; ++i) {
267 dest->bitmap[i] &= right->bitmap[i];
268 }
269
270 return PMIX_SUCCESS;
271 }
272
273 int pmix_bitmap_bitwise_or_inplace(pmix_bitmap_t *dest, pmix_bitmap_t *right)
274 {
275 int i;
276
277
278
279
280 if( NULL == dest || NULL == right ) {
281 return PMIX_ERR_BAD_PARAM;
282 }
283 if( dest->array_size != right->array_size ) {
284 return PMIX_ERR_BAD_PARAM;
285 }
286
287
288
289
290 for(i = 0; i < dest->array_size; ++i) {
291 dest->bitmap[i] |= right->bitmap[i];
292 }
293
294 return PMIX_SUCCESS;
295 }
296
297 int pmix_bitmap_bitwise_xor_inplace(pmix_bitmap_t *dest, pmix_bitmap_t *right)
298 {
299 int i;
300
301
302
303
304 if( NULL == dest || NULL == right ) {
305 return PMIX_ERR_BAD_PARAM;
306 }
307 if( dest->array_size != right->array_size ) {
308 return PMIX_ERR_BAD_PARAM;
309 }
310
311
312
313
314 for(i = 0; i < dest->array_size; ++i) {
315 dest->bitmap[i] ^= right->bitmap[i];
316 }
317
318 return PMIX_SUCCESS;
319 }
320
321 bool pmix_bitmap_are_different(pmix_bitmap_t *left, pmix_bitmap_t *right)
322 {
323 int i;
324
325
326
327
328 if( NULL == left || NULL == right ) {
329 return PMIX_ERR_BAD_PARAM;
330 }
331
332 if( pmix_bitmap_size(left) != pmix_bitmap_size(right) ) {
333 return true;
334 }
335
336
337
338
339 for(i = 0; i < left->array_size; ++i) {
340 if( left->bitmap[i] != right->bitmap[i] ) {
341 return true;
342 }
343 }
344
345 return false;
346 }
347
348 char * pmix_bitmap_get_string(pmix_bitmap_t *bitmap)
349 {
350 int i;
351 char *bitmap_str = NULL;
352
353 if( NULL == bitmap) {
354 return NULL;
355 }
356
357 bitmap_str = malloc(bitmap->array_size * SIZE_OF_BASE_TYPE + 1);
358 if (NULL == bitmap_str) {
359 return NULL;
360 }
361 bitmap_str[bitmap->array_size * SIZE_OF_BASE_TYPE] = '\0';
362
363 for( i = 0; i < (bitmap->array_size * SIZE_OF_BASE_TYPE); ++i) {
364 if( pmix_bitmap_is_set_bit(bitmap, i) ) {
365 bitmap_str[i] = 'X';
366 } else {
367 bitmap_str[i] = '_';
368 }
369 }
370
371 return bitmap_str;
372 }
373
374 int pmix_bitmap_num_unset_bits(pmix_bitmap_t *bm, int len)
375 {
376 return (len - pmix_bitmap_num_set_bits(bm, len));
377 }
378
379 int pmix_bitmap_num_set_bits(pmix_bitmap_t *bm, int len)
380 {
381 int i, cnt = 0;
382 uint64_t val;
383
384 #if PMIX_ENABLE_DEBUG
385 if ((len < 0) || NULL == bm || (len >= (bm->array_size * SIZE_OF_BASE_TYPE))) {
386 return 0;
387 }
388 #endif
389
390 for(i = 0; i < len; ++i) {
391 if( 0 == (val = bm->bitmap[i]) ) continue;
392
393
394 for( ; val; cnt++ ) {
395 val &= val - 1;
396 }
397 }
398
399 return cnt;
400 }
401
402 bool pmix_bitmap_is_clear(pmix_bitmap_t *bm)
403 {
404 int i;
405
406 for (i = 0; i < bm->array_size; ++i) {
407 if (0 != bm->bitmap[i]) {
408 return false;
409 }
410 }
411 return true;
412 }