44 #ifndef included_pool_h 45 #define included_pool_h 72 #define pool_aligned_header_bytes \ 73 vec_aligned_header_bytes (sizeof (pool_header_t), sizeof (void *)) 82 extern void _pool_init_fixed (
void **,
u32,
u32);
86 #define pool_init_fixed(pool,max_elts) \ 88 _pool_init_fixed((void **)&(pool),sizeof(pool[0]),max_elts); \ 116 #define pool_validate_index(v,i) \ 118 uword __pool_validate_index = (i); \ 119 vec_validate_ha ((v), __pool_validate_index, \ 120 pool_aligned_header_bytes, 0); \ 121 pool_header_validate_index ((v), __pool_validate_index); \ 140 #define pool_len(p) vec_len(p) 146 #define _pool_len(p) _vec_len(p) 161 #define pool_bytes(P) (vec_bytes (P) + pool_header_bytes (P)) 164 #define _pool_var(v) _pool_##v 188 #define pool_get_aligned(P,E,A) \ 190 pool_header_t * _pool_var (p) = pool_header (P); \ 191 uword _pool_var (l); \ 195 _pool_var (l) = vec_len (_pool_var (p)->free_indices); \ 197 if (_pool_var (l) > 0) \ 200 uword _pool_var (i) = _pool_var (p)->free_indices[_pool_var (l) - 1]; \ 201 (E) = (P) + _pool_var (i); \ 202 _pool_var (p)->free_bitmap = \ 203 clib_bitmap_andnoti (_pool_var (p)->free_bitmap, _pool_var (i)); \ 204 _vec_len (_pool_var (p)->free_indices) = _pool_var (l) - 1; \ 209 if ((P) && _pool_var(p)->max_elts) \ 211 clib_warning ("can't expand fixed-size pool"); \ 212 os_out_of_memory(); \ 215 P = _vec_resize (P, \ 217 (vec_len (P) + 1) * sizeof (P[0]), \ 218 pool_aligned_header_bytes, \ 220 E = vec_end (P) - 1; \ 225 #define pool_get(P,E) pool_get_aligned(P,E,0) 228 #define pool_get_aligned_will_expand(P,YESNO,A) \ 230 pool_header_t * _pool_var (p) = pool_header (P); \ 231 uword _pool_var (l); \ 236 if (_pool_var (p)->max_elts) \ 237 _pool_var (l) = _pool_var (p)->max_elts; \ 239 _pool_var (l) = vec_len (_pool_var (p)->free_indices); \ 243 if (_pool_var (l) > 0) \ 248 YESNO = _vec_resize_will_expand \ 251 (vec_len (P) + 1) * sizeof (P[0]), \ 252 pool_aligned_header_bytes, \ 257 #define pool_get_will_expand(P,YESNO) pool_get_aligned_will_expand(P,YESNO,0) 260 #define pool_is_free(P,E) \ 262 pool_header_t * _pool_var (p) = pool_header (P); \ 263 uword _pool_var (i) = (E) - (P); \ 264 (_pool_var (i) < vec_len (P)) ? clib_bitmap_get (_pool_var (p)->free_bitmap, _pool_i) : 1; \ 268 #define pool_is_free_index(P,I) pool_is_free((P),(P)+(I)) 271 #define pool_put(P,E) \ 273 pool_header_t * _pool_var (p) = pool_header (P); \ 274 uword _pool_var (l) = (E) - (P); \ 275 ASSERT (vec_is_member (P, E)); \ 276 ASSERT (! pool_is_free (P, E)); \ 279 _pool_var (p)->free_bitmap = \ 280 clib_bitmap_ori (_pool_var (p)->free_bitmap, _pool_var (l)); \ 282 if (_pool_var (p)->max_elts) \ 284 ASSERT(_pool_var(l) < _pool_var (p)->max_elts); \ 285 _pool_var(p)->free_indices[_vec_len(_pool_var(p)->free_indices)] = \ 287 _vec_len(_pool_var(p)->free_indices) += 1; \ 290 vec_add1 (_pool_var (p)->free_indices, _pool_var (l)); \ 294 #define pool_put_index(p,i) \ 296 typeof (p) _e = (p) + (i); \ 301 #define pool_alloc_aligned(P,N,A) \ 303 pool_header_t * _p; \ 307 _p = pool_header (P); \ 310 clib_warning ("Can't expand fixed-size pool"); \ 311 os_out_of_memory(); \ 315 (P) = _vec_resize ((P), 0, (vec_len (P) + (N)) * sizeof (P[0]), \ 316 pool_aligned_header_bytes, \ 318 _p = pool_header (P); \ 319 vec_resize (_p->free_indices, (N)); \ 320 _vec_len (_p->free_indices) -= (N); \ 324 #define pool_alloc(P,N) pool_alloc_aligned(P,N,0) 352 #define pool_free(p) (p) = _pool_free(p) 364 #define pool_foreach_region(LO,HI,POOL,BODY) \ 366 uword _pool_var (i), _pool_var (lo), _pool_var (hi), _pool_var (len); \ 367 uword _pool_var (bl), * _pool_var (b); \ 368 pool_header_t * _pool_var (p); \ 370 _pool_var (p) = pool_header (POOL); \ 371 _pool_var (b) = (POOL) ? _pool_var (p)->free_bitmap : 0; \ 372 _pool_var (bl) = vec_len (_pool_var (b)); \ 373 _pool_var (len) = vec_len (POOL); \ 374 _pool_var (lo) = 0; \ 376 for (_pool_var (i) = 0; \ 377 _pool_var (i) <= _pool_var (bl); \ 380 uword _pool_var (m), _pool_var (f); \ 381 _pool_var (m) = (_pool_var (i) < _pool_var (bl) \ 382 ? _pool_var (b) [_pool_var (i)] \ 384 while (_pool_var (m) != 0) \ 386 _pool_var (f) = first_set (_pool_var (m)); \ 387 _pool_var (hi) = (_pool_var (i) * BITS (_pool_var (b)[0]) \ 388 + min_log2 (_pool_var (f))); \ 389 _pool_var (hi) = (_pool_var (i) < _pool_var (bl) \ 390 ? _pool_var (hi) : _pool_var (len)); \ 391 _pool_var (m) ^= _pool_var (f); \ 392 if (_pool_var (hi) > _pool_var (lo)) \ 394 (LO) = _pool_var (lo); \ 395 (HI) = _pool_var (hi); \ 396 do { BODY; } while (0); \ 398 _pool_var (lo) = _pool_var (hi) + 1; \ 438 #define pool_foreach(VAR,POOL,BODY) \ 440 uword _pool_foreach_lo, _pool_foreach_hi; \ 441 pool_foreach_region (_pool_foreach_lo, _pool_foreach_hi, (POOL), \ 443 for ((VAR) = (POOL) + _pool_foreach_lo; \ 444 (VAR) < (POOL) + _pool_foreach_hi; \ 446 do { BODY; } while (0); \ 459 #define pool_elt_at_index(p,i) \ 461 typeof (p) _e = (p) + (i); \ 462 ASSERT (! pool_is_free (p, _e)); \ 467 #define pool_next_index(P,I) \ 469 pool_header_t * _pool_var (p) = pool_header (P); \ 470 uword _pool_var (rv) = (I) + 1; \ 473 (_pool_var (rv) < vec_len (P) ? \ 474 clib_bitmap_next_clear (_pool_var (p)->free_bitmap, _pool_var(rv)) \ 480 #define pool_foreach_index(i,v,body) \ 481 for ((i) = 0; (i) < vec_len (v); (i)++) \ 483 if (! pool_is_free_index ((v), (i))) \ 484 do { body; } while (0); \ 495 #define pool_flush(VAR, POOL, BODY) \ 497 uword *_pool_var(ii), *_pool_var(dv) = NULL; \ 499 pool_foreach((VAR), (POOL), \ 501 vec_add1(_pool_var(dv), (VAR) - (POOL)); \ 503 vec_foreach(_pool_var(ii), _pool_var(dv)) \ 505 (VAR) = pool_elt_at_index((POOL), *_pool_var(ii)); \ 506 do { BODY; } while (0); \ 507 pool_put((POOL), (VAR)); \ 509 vec_free(_pool_var(dv)); \ #define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
sll srl srl sll sra u16x4 i
static void pool_header_validate_index(void *v, uword index)
#define vec_bytes(v)
Number of data bytes in vector.
static pool_header_t * pool_header(void *v)
Get pool header from user pool pointer.
#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.
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 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.