44 #ifndef included_pool_h 45 #define included_pool_h 71 #define pool_aligned_header_bytes \ 72 vec_aligned_header_bytes (sizeof (pool_header_t), sizeof (void *)) 81 extern void _pool_init_fixed (
void **,
u32,
u32);
85 #define pool_init_fixed(pool,max_elts) \ 87 _pool_init_fixed((void **)&(pool),sizeof(pool[0]),max_elts); \ 115 #define pool_validate_index(v,i) \ 117 uword __pool_validate_index = (i); \ 118 vec_validate_ha ((v), __pool_validate_index, \ 119 pool_aligned_header_bytes, 0); \ 120 pool_header_validate_index ((v), __pool_validate_index); \ 139 #define pool_len(p) vec_len(p) 145 #define _pool_len(p) _vec_len(p) 160 #define pool_bytes(P) (vec_bytes (P) + pool_header_bytes (P)) 163 #define _pool_var(v) _pool_##v 187 #define _pool_get_aligned_internal_numa(P,E,A,Z,N) \ 189 pool_header_t * _pool_var (p) = pool_header (P); \ 190 uword _pool_var (l); \ 192 STATIC_ASSERT(A==0 || ((A % sizeof(P[0]))==0) \ 193 || ((sizeof(P[0]) % A) == 0), \ 194 "Pool aligned alloc of incorrectly sized object"); \ 197 _pool_var (l) = vec_len (_pool_var (p)->free_indices); \ 199 if (_pool_var (l) > 0) \ 202 uword _pool_var (i) = \ 203 _pool_var (p)->free_indices[_pool_var (l) - 1]; \ 204 (E) = (P) + _pool_var (i); \ 205 _pool_var (p)->free_bitmap = \ 206 clib_bitmap_andnoti_notrim (_pool_var (p)->free_bitmap, \ 208 _vec_len (_pool_var (p)->free_indices) = _pool_var (l) - 1; \ 209 CLIB_MEM_UNPOISON((E), sizeof((E)[0])); \ 214 if ((P) && _pool_var(p)->max_elts) \ 216 clib_warning ("can't expand fixed-size pool"); \ 217 os_out_of_memory(); \ 220 P = _vec_resize_numa (P, \ 222 (vec_len (P) + 1) * sizeof (P[0]), \ 223 pool_aligned_header_bytes, \ 226 E = vec_end (P) - 1; \ 229 memset(E, 0, sizeof(*E)); \ 232 #define pool_get_aligned_zero_numa(P,E,A,Z,S) \ 233 _pool_get_aligned_internal_numa(P,E,A,Z,S) 235 #define pool_get_aligned_numa(P,E,A,S) \ 236 _pool_get_aligned_internal_numa(P,E,A,0,S) 238 #define pool_get_numa(P,E,S) \ 239 _pool_get_aligned_internal_numa(P,E,0,0,S) 241 #define _pool_get_aligned_internal(P,E,A,Z) \ 242 _pool_get_aligned_internal_numa(P,E,A,Z,VEC_NUMA_UNSPECIFIED) 245 #define pool_get_aligned(P,E,A) _pool_get_aligned_internal(P,E,A,0) 248 #define pool_get_aligned_zero(P,E,A) _pool_get_aligned_internal(P,E,A,1) 251 #define pool_get(P,E) pool_get_aligned(P,E,0) 254 #define pool_get_zero(P,E) pool_get_aligned_zero(P,E,0) 257 #define pool_get_aligned_will_expand(P,YESNO,A) \ 259 pool_header_t * _pool_var (p) = pool_header (P); \ 260 uword _pool_var (l); \ 265 if (_pool_var (p)->max_elts) \ 266 _pool_var (l) = _pool_var (p)->max_elts; \ 268 _pool_var (l) = vec_len (_pool_var (p)->free_indices); \ 272 if (_pool_var (l) > 0) \ 277 YESNO = _vec_resize_will_expand \ 280 (vec_len (P) + 1) * sizeof (P[0]), \ 281 pool_aligned_header_bytes, \ 287 #define pool_get_will_expand(P,YESNO) pool_get_aligned_will_expand(P,YESNO,0) 290 #define pool_is_free(P,E) \ 292 pool_header_t * _pool_var (p) = pool_header (P); \ 293 uword _pool_var (i) = (E) - (P); \ 294 (_pool_var (i) < vec_len (P)) ? clib_bitmap_get (_pool_var (p)->free_bitmap, _pool_i) : 1; \ 298 #define pool_is_free_index(P,I) pool_is_free((P),(P)+(I)) 301 #define pool_put(P,E) \ 303 typeof (P) _pool_var(p__) = (P); \ 304 typeof (E) _pool_var(e__) = (E); \ 305 pool_header_t * _pool_var (p) = pool_header (_pool_var(p__)); \ 306 uword _pool_var (l) = _pool_var(e__) - _pool_var(p__); \ 307 ASSERT (vec_is_member (_pool_var(p__), _pool_var(e__))); \ 308 ASSERT (! pool_is_free (_pool_var(p__), _pool_var(e__))); \ 311 _pool_var (p)->free_bitmap = \ 312 clib_bitmap_ori_notrim (_pool_var (p)->free_bitmap, \ 316 if (_pool_var (p)->max_elts) \ 318 ASSERT(_pool_var(l) < _pool_var (p)->max_elts); \ 319 _pool_var(p)->free_indices[_vec_len(_pool_var(p)->free_indices)] = \ 321 _vec_len(_pool_var(p)->free_indices) += 1; \ 324 vec_add1 (_pool_var (p)->free_indices, _pool_var (l)); \ 326 CLIB_MEM_POISON(_pool_var(e__), sizeof(_pool_var(e__)[0])); \ 330 #define pool_put_index(p,i) \ 332 typeof (p) _e = (p) + (i); \ 337 #define pool_alloc_aligned(P,N,A) \ 339 pool_header_t * _p; \ 343 _p = pool_header (P); \ 346 clib_warning ("Can't expand fixed-size pool"); \ 347 os_out_of_memory(); \ 351 (P) = _vec_resize ((P), 0, (vec_len (P) + (N)) * sizeof (P[0]), \ 352 pool_aligned_header_bytes, \ 354 _p = pool_header (P); \ 355 vec_resize (_p->free_indices, (N)); \ 356 _vec_len (_p->free_indices) -= (N); \ 360 #define pool_alloc(P,N) pool_alloc_aligned(P,N,0) 369 #define pool_dup_aligned(P,A) \ 371 typeof (P) _pool_var (new) = 0; \ 372 pool_header_t * _pool_var (ph), * _pool_var (new_ph); \ 373 u32 _pool_var (n) = pool_len (P); \ 376 _pool_var (new) = _vec_resize (_pool_var (new), _pool_var (n), \ 377 _pool_var (n) * sizeof ((P)[0]), \ 378 pool_aligned_header_bytes, (A)); \ 379 clib_memcpy_fast (_pool_var (new), (P), \ 380 _pool_var (n) * sizeof ((P)[0])); \ 381 _pool_var (ph) = pool_header (P); \ 382 _pool_var (new_ph) = pool_header (_pool_var (new)); \ 383 _pool_var (new_ph)->free_bitmap = \ 384 clib_bitmap_dup (_pool_var (ph)->free_bitmap); \ 385 _pool_var (new_ph)->free_indices = \ 386 vec_dup (_pool_var (ph)->free_indices); \ 387 _pool_var (new_ph)->max_elts = _pool_var (ph)->max_elts; \ 398 #define pool_dup(P) pool_dup_aligned(P,0) 436 return clib_bitmap_next_clear (h->
free_bitmap, last + 1);
440 #define pool_free(p) (p) = _pool_free(p) 452 #define pool_foreach_region(LO,HI,POOL,BODY) \ 454 uword _pool_var (i), _pool_var (lo), _pool_var (hi), _pool_var (len); \ 455 uword _pool_var (bl), * _pool_var (b); \ 456 pool_header_t * _pool_var (p); \ 458 _pool_var (p) = pool_header (POOL); \ 459 _pool_var (b) = (POOL) ? _pool_var (p)->free_bitmap : 0; \ 460 _pool_var (bl) = vec_len (_pool_var (b)); \ 461 _pool_var (len) = vec_len (POOL); \ 462 _pool_var (lo) = 0; \ 464 for (_pool_var (i) = 0; \ 465 _pool_var (i) <= _pool_var (bl); \ 468 uword _pool_var (m), _pool_var (f); \ 469 _pool_var (m) = (_pool_var (i) < _pool_var (bl) \ 470 ? _pool_var (b) [_pool_var (i)] \ 472 while (_pool_var (m) != 0) \ 474 _pool_var (f) = first_set (_pool_var (m)); \ 475 _pool_var (hi) = (_pool_var (i) * BITS (_pool_var (b)[0]) \ 476 + min_log2 (_pool_var (f))); \ 477 _pool_var (hi) = (_pool_var (i) < _pool_var (bl) \ 478 ? _pool_var (hi) : _pool_var (len)); \ 479 _pool_var (m) ^= _pool_var (f); \ 480 if (_pool_var (hi) > _pool_var (lo)) \ 482 (LO) = _pool_var (lo); \ 483 (HI) = _pool_var (hi); \ 484 do { BODY; } while (0); \ 486 _pool_var (lo) = _pool_var (hi) + 1; \ 527 #define pool_foreach(VAR,POOL) \ 529 for (VAR = POOL + pool_get_first_index (POOL); \ 530 VAR < vec_end (POOL); \ 531 VAR = POOL + pool_get_next_index (POOL, VAR - POOL)) 533 #define pool_foreach_old(VAR,POOL,BODY) \ 534 pool_foreach(VAR,POOL) \ 546 #define pool_elt_at_index(p,i) \ 548 typeof (p) _e = (p) + (i); \ 549 ASSERT (! pool_is_free (p, _e)); \ 554 #define pool_next_index(P,I) \ 556 pool_header_t * _pool_var (p) = pool_header (P); \ 557 uword _pool_var (rv) = (I) + 1; \ 560 (_pool_var (rv) < vec_len (P) ? \ 561 clib_bitmap_next_clear (_pool_var (p)->free_bitmap, _pool_var(rv)) \ 564 (_pool_var (rv) < vec_len (P) ? \ 565 _pool_var (rv) : ~0); \ 569 #define pool_foreach_index(i,v) \ 571 for (i = pool_get_first_index (v); \ 573 i = pool_get_next_index (v, i)) \ 576 #define pool_foreach_index_old(i,v,body) \ 577 pool_foreach_index (i,v) \ 588 #define pool_flush(VAR, POOL, BODY) \ 590 uword *_pool_var(ii), *_pool_var(dv) = NULL; \ 592 pool_foreach((VAR), (POOL)) \ 594 vec_add1(_pool_var(dv), (VAR) - (POOL)); \ 596 vec_foreach(_pool_var(ii), _pool_var(dv)) \ 598 (VAR) = pool_elt_at_index((POOL), *_pool_var(ii)); \ 599 do { BODY; } while (0); \ 600 pool_put((POOL), (VAR)); \ 602 vec_free(_pool_var(dv)); \ #define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static_always_inline uword pool_get_first_index(void *pool)
static void pool_header_validate_index(void *v, uword index)
static heap_elt_t * last(heap_header_t *h)
#define vec_bytes(v)
Number of data bytes in vector.
#define static_always_inline
static pool_header_t * pool_header(void *v)
Get pool header from user pool pointer.
static_always_inline uword pool_get_next_index(void *pool, uword last)
#define pool_aligned_header_bytes
Align pool header so that pointers are naturally aligned.
static uword pool_header_bytes(void *v)
Memory usage of pool header.
sll srl srl sll sra u16x4 i
static void pool_validate(void *v)
Validate a pool.
#define vec_free(V)
Free vector's memory (no header).
static void * vec_aligned_header(void *v, uword header_bytes, uword align)
#define vec_capacity(v, b)
Total number of bytes that can fit in vector with current allocation.
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Bitmaps built as vectors of machine words.
#define clib_bitmap_free(v)
Free a bitmap.
static uword clib_bitmap_count_set_bits(uword *ai)
Return the number of set bits in a bitmap.
#define vec_free_h(V, H)
Free vector's memory (general version)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define clib_unix_warning(format, args...)
static uword clib_bitmap_first_clear(uword *ai)
Return the lowest numbered clear bit in a bitmap.
static uword pool_free_elts(void *v)
Queries whether pool has at least N_FREE free elements.
static uword pool_elts(void *v)
Number of active elements in a pool.