2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 Copyright (c) 2001, 2002, 2003, 2005 Eliot Dresselhaus
18 Permission is hereby granted, free of charge, to any person obtaining
19 a copy of this software and associated documentation files (the
20 "Software"), to deal in the Software without restriction, including
21 without limitation the rights to use, copy, modify, merge, publish,
22 distribute, sublicense, and/or sell copies of the Software, and to
23 permit persons to whom the Software is furnished to do so, subject to
24 the following conditions:
26 The above copyright notice and this permission notice shall be
27 included in all copies or substantial portions of the Software.
29 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
30 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
31 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
32 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
33 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
34 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
35 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38 #ifndef included_clib_bitmap_h
39 #define included_clib_bitmap_h
41 /* Bitmaps built as vectors of machine words. */
43 #include <vppinfra/vec.h>
44 #include <vppinfra/random.h>
45 #include <vppinfra/error.h>
46 #include <vppinfra/bitops.h> /* for count_set_bits */
48 typedef uword clib_bitmap_t;
50 /* Returns 1 if the entire bitmap is zero, 0 otherwise */
52 clib_bitmap_is_zero (uword * ai)
55 for (i = 0; i < vec_len (ai); i++)
61 /* Returns 1 if two bitmaps are equal, 0 otherwise */
63 clib_bitmap_is_equal (uword * a, uword * b)
66 if (vec_len (a) != vec_len (b))
68 for (i = 0; i < vec_len (a); i++)
74 /* Duplicate a bitmap */
75 #define clib_bitmap_dup(v) vec_dup(v)
78 #define clib_bitmap_free(v) vec_free(v)
80 /* Returns the number of bytes in a bitmap */
81 #define clib_bitmap_bytes(v) vec_bytes(v)
84 #define clib_bitmap_zero(v) vec_zero(v)
86 /* Allocate bitmap with given number of bits. */
87 #define clib_bitmap_alloc(v,n_bits) \
88 v = vec_new (uword, ((n_bits) + BITS (uword) - 1) / BITS (uword))
90 #define clib_bitmap_vec_validate(v,i) vec_validate_aligned((v),(i),sizeof(uword))
92 /* Make sure that a bitmap is at least n_bits in size */
93 #define clib_bitmap_validate(v,n_bits) \
94 clib_bitmap_vec_validate ((v), ((n_bits) - 1) / BITS (uword))
96 /* low-level routine to remove trailing zeros from a bitmap */
98 _clib_bitmap_remove_trailing_zeros (uword * a)
103 for (i = _vec_len (a) - 1; i >= 0; i--)
106 _vec_len (a) = i + 1;
111 /* Sets the ith bit of a bitmap to new_value. Returns old value.
112 No sanity checking. Be careful. */
114 clib_bitmap_set_no_check (uword * a, uword i, uword new_value)
116 uword i0 = i / BITS (a[0]);
117 uword i1 = i % BITS (a[0]);
118 uword bit = (uword) 1 << i1;
121 /* Removed ASSERT since uword * a may not be a vector. */
122 /* ASSERT (i0 < vec_len (a)); */
125 old_value = (ai & bit) != 0;
127 ai |= ((uword) (new_value != 0)) << i1;
132 /* Set bit I to value (either non-zero or zero). */
133 always_inline uword *
134 clib_bitmap_set (uword * ai, uword i, uword value)
136 uword i0 = i / BITS (ai[0]);
137 uword i1 = i % BITS (ai[0]);
140 /* Check for writing a zero to beyond end of bitmap. */
141 if (value == 0 && i0 >= vec_len (ai))
142 return ai; /* Implied trailing zeros. */
144 clib_bitmap_vec_validate (ai, i0);
147 a &= ~((uword) 1 << i1);
148 a |= ((uword) (value != 0)) << i1;
151 /* If bits have been cleared, test for zero. */
153 ai = _clib_bitmap_remove_trailing_zeros (ai);
160 clib_bitmap_get (uword * ai, uword i)
162 uword i0 = i / BITS (ai[0]);
163 uword i1 = i % BITS (ai[0]);
164 return i0 < vec_len (ai) && 0 != ((ai[i0] >> i1) & 1);
169 No sanity checking. Be careful.
172 clib_bitmap_get_no_check (uword * ai, uword i)
174 uword i0 = i / BITS (ai[0]);
175 uword i1 = i % BITS (ai[0]);
176 return 0 != ((ai[i0] >> i1) & 1);
179 /* I through I + N_BITS.
181 No sanity checking. Be careful.
184 clib_bitmap_get_multiple_no_check (uword * ai, uword i, uword n_bits)
186 uword i0 = i / BITS (ai[0]);
187 uword i1 = i % BITS (ai[0]);
188 ASSERT (i1 + n_bits <= BITS (uword));
189 return 0 != ((ai[i0] >> i1) & pow2_mask (n_bits));
192 /* Fetch bits I through I + N_BITS. */
194 clib_bitmap_get_multiple (uword * bitmap, uword i, uword n_bits)
196 uword i0, i1, result;
197 uword l = vec_len (bitmap);
199 ASSERT (n_bits >= 0 && n_bits <= BITS (result));
201 i0 = i / BITS (bitmap[0]);
202 i1 = i % BITS (bitmap[0]);
204 /* Check first word. */
208 result |= (bitmap[i0] >> i1);
209 if (n_bits < BITS (bitmap[0]))
210 result &= (((uword) 1 << n_bits) - 1);
213 /* Check for overlap into next word. */
215 if (i1 + n_bits > BITS (bitmap[0]) && i0 < l)
217 n_bits -= BITS (bitmap[0]) - i1;
218 result |= (bitmap[i0] & (((uword) 1 << n_bits) - 1)) << (BITS (bitmap[0]) - i1);
224 /* Set bits I through I + N_BITS to given value.
226 New bitmap will be returned. */
227 always_inline uword *
228 clib_bitmap_set_multiple (uword * bitmap, uword i, uword value, uword n_bits)
230 uword i0, i1, l, t, m;
232 ASSERT (n_bits >= 0 && n_bits <= BITS (value));
234 i0 = i / BITS (bitmap[0]);
235 i1 = i % BITS (bitmap[0]);
237 /* Allocate bitmap. */
238 clib_bitmap_vec_validate (bitmap, (i + n_bits) / BITS (bitmap[0]));
239 l = vec_len (bitmap);
242 if (n_bits < BITS (value))
243 m = (((uword) 1 << n_bits) - 1);
246 /* Insert into first word. */
252 /* Insert into second word. */
254 if (i1 + n_bits > BITS (bitmap[0]) && i0 < l)
256 t = BITS (bitmap[0]) - i1;
260 m = ((uword) 1 << n_bits) - 1;
269 /* For a multi-word region set all bits to given value. */
270 always_inline uword *
271 clib_bitmap_set_region (uword * bitmap, uword i, uword value, uword n_bits)
276 a0 = i / BITS (bitmap[0]);
277 a1 = i % BITS (bitmap[0]);
280 b0 = i_end / BITS (bitmap[0]);
282 clib_bitmap_vec_validate (bitmap, b0);
285 mask = n_bits < BITS (bitmap[0]) ? pow2_mask (n_bits) : ~0;
293 for (a0++; a0 < b0; a0++)
294 bitmap[a0] = value ? ~0 : 0;
298 word n_bits_left = n_bits - (BITS (bitmap[0]) - a1);
299 mask = pow2_mask (n_bits_left);
309 /* Iterate through set bits. */
310 #define clib_bitmap_foreach(i,ai,body) \
312 uword __bitmap_i, __bitmap_ai, __bitmap_len, __bitmap_first_set; \
313 __bitmap_len = vec_len ((ai)); \
314 for (__bitmap_i = 0; __bitmap_i < __bitmap_len; __bitmap_i++) \
316 __bitmap_ai = (ai)[__bitmap_i]; \
317 while (__bitmap_ai != 0) \
319 __bitmap_first_set = first_set (__bitmap_ai); \
320 (i) = (__bitmap_i * BITS ((ai)[0]) \
321 + min_log2 (__bitmap_first_set)); \
322 do { body; } while (0); \
323 __bitmap_ai ^= __bitmap_first_set; \
328 /* Return lowest numbered set bit in bitmap.
330 Return infinity (~0) if bitmap is zero. */
331 always_inline uword clib_bitmap_first_set (uword * ai)
334 for (i = 0; i < vec_len (ai); i++)
338 return i * BITS (ai[0]) + log2_first_set (x);
343 /* Return highest numbered set bit in bitmap.
345 Return infinity (~0) if bitmap is zero. */
346 always_inline uword clib_bitmap_last_set (uword * ai)
350 for (i = vec_len (ai) - 1; i >= 0 ; i--)
356 count_leading_zeros (first_bit, x);
357 return (i + 1) * BITS (ai[0]) - first_bit - 1;
363 /* Return lowest numbered clear bit in bitmap. */
365 clib_bitmap_first_clear (uword * ai)
368 for (i = 0; i < vec_len (ai); i++)
372 return i * BITS (ai[0]) + log2_first_set (x);
374 return i * BITS (ai[0]);
377 /* Count number of set bits in bitmap. */
379 clib_bitmap_count_set_bits (uword * ai)
383 for (i = 0; i < vec_len (ai); i++)
384 n_set += count_set_bits (ai[i]);
388 /* ALU function definition macro for functions taking two bitmaps. */
389 #define _(name, body, check_zero) \
390 always_inline uword * \
391 clib_bitmap_##name (uword * ai, uword * bi) \
393 uword i, a, b, bi_len, n_trailing_zeros; \
395 n_trailing_zeros = 0; \
396 bi_len = vec_len (bi); \
398 clib_bitmap_vec_validate (ai, bi_len - 1); \
399 for (i = 0; i < vec_len (ai); i++) \
402 b = i < bi_len ? bi[i] : 0; \
403 do { body; } while (0); \
406 n_trailing_zeros = a ? 0 : (n_trailing_zeros + 1); \
409 _vec_len (ai) -= n_trailing_zeros; \
414 _ (and, a = a & b, 1)
415 _ (andnot, a = a &~ b, 1)
417 _ (xor, a = a ^ b, 1)
420 /* Define functions which duplicate first argument.
421 (Normal functions over-write first argument.) */
423 always_inline uword * \
424 clib_bitmap_dup_##name (uword * ai, uword * bi) \
425 { return clib_bitmap_##name (clib_bitmap_dup (ai), bi); }
434 /* ALU function definition macro for functions taking one bitmap and an immediate. */
435 #define _(name, body, check_zero) \
436 always_inline uword * \
437 clib_bitmap_##name (uword * ai, uword i) \
439 uword i0 = i / BITS (ai[0]); \
440 uword i1 = i % BITS (ai[0]); \
442 clib_bitmap_vec_validate (ai, i0); \
444 b = (uword) 1 << i1; \
445 do { body; } while (0); \
447 if (check_zero && a == 0) \
448 ai = _clib_bitmap_remove_trailing_zeros (ai); \
452 /* ALU functions immediate: */
453 _ (andi, a = a & b, 1)
454 _ (andnoti, a = a &~ b, 1)
455 _ (ori, a = a | b, 0)
456 _ (xori, a = a ^ b, 1)
460 /* Returns random bitmap of given length. */
461 always_inline uword *
462 clib_bitmap_random (uword * ai, uword n_bits, u32 * seed)
464 vec_reset_length (ai);
468 uword i = n_bits - 1;
472 log2_rand_max = min_log2 (random_u32_max ());
474 i0 = i / BITS (ai[0]);
475 i1 = i % BITS (ai[0]);
477 clib_bitmap_vec_validate (ai, i0);
478 for (i = 0; i <= i0; i++)
481 for (n = 0; n < BITS (ai[i]); n += log2_rand_max)
482 ai[i] |= random_u32 (seed) << n;
484 if (i1 + 1 < BITS (ai[0]))
485 ai[i0] &= (((uword) 1 << (i1 + 1)) - 1);
490 /* Returns next set bit starting at bit i (~0 if not found). */
492 clib_bitmap_next_set (uword * ai, uword i)
494 uword i0 = i / BITS (ai[0]);
495 uword i1 = i % BITS (ai[0]);
498 if (i0 < vec_len (ai))
500 t = (ai[i0] >> i1) << i1;
502 return log2_first_set (t) + i0 * BITS (ai[0]);
504 for (i0++; i0 < vec_len (ai); i0++)
508 return log2_first_set (t) + i0 * BITS (ai[0]);
515 /* Returns next clear bit at position >= i */
517 clib_bitmap_next_clear (uword * ai, uword i)
519 uword i0 = i / BITS (ai[0]);
520 uword i1 = i % BITS (ai[0]);
523 if (i0 < vec_len (ai))
525 t = (~ai[i0] >> i1) << i1;
527 return log2_first_set (t) + i0 * BITS (ai[0]);
529 for (i0++; i0 < vec_len (ai); i0++)
533 return log2_first_set (t) + i0 * BITS (ai[0]);
539 /* unformat list of bits into bitmap (eg "0-3,5-7,11" ) */
541 unformat_bitmap_list(unformat_input_t * input, va_list * va)
543 uword ** bitmap_return = va_arg (* va, uword **);
548 while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
551 if (unformat (input, "%u-%u,", &a, &b))
553 else if (unformat (input, "%u,", &a))
555 else if (unformat (input, "%u-%u", &a, &b))
557 else if (unformat (input, "%u", &a))
561 unformat_put_input(input);
570 for (i = a; i <= b; i++)
571 bitmap = clib_bitmap_set(bitmap, i, 1);
573 *bitmap_return = bitmap;
576 clib_bitmap_free(bitmap);
581 format_bitmap_hex(u8 * s, va_list * args)
583 uword * bitmap = va_arg (*args, uword *);
584 int i, is_trailing_zero = 1;
587 return format(s, "0");
589 i = vec_bytes (bitmap) * 2;
593 u8 x = clib_bitmap_get_multiple(bitmap, --i * 4, 4);
595 if (x && is_trailing_zero)
596 is_trailing_zero = 0;
598 if (x || !is_trailing_zero)
599 s = format(s, "%x", x);
603 #endif /* included_clib_bitmap_h */