static inline struct sfm_frag* pool_get_frag(struct sfm_block* qm, struct sfm_pool* pool, int hash, unsigned long size) #endif { int r; int next_block; struct sfm_frag* volatile* f; struct sfm_frag* frag; unsigned long b; unsigned long eob; /* special case for r=hash */ r=hash; f=&pool->pool_hash[r].first; /* detach it from the free list */ if ((frag=frag_pop((struct sfm_frag**)f))==0) goto not_found; found: atomic_dec_long((long*)&pool->pool_hash[r].no); frag->u.nxt_free=0; /* mark it as 'taken' */ frag->id=pool_id; #ifdef DBG_F_MALLOC sfm_split_frag(qm, frag, size, file, func, line); #else sfm_split_frag(qm, frag, size); #endif if (&qm->pool[pool_id]==pool) atomic_inc_long((long*)&pool->hits); return frag; not_found: atomic_inc_long((long*)&pool->pool_hash[r].misses); r++; b=HASH_BIT_POS(r); while(r<SF_HASH_POOL_SIZE){ b=_next_set_bit(b, &pool->bitmap); next_block=_hash_range(b, &eob); r=(r<next_block)?next_block:r; for (; r<eob; r++){ f=&pool->pool_hash[r].first; if ((frag=frag_pop((struct sfm_frag**)f))!=0) goto found; atomic_inc_long((long*)&pool->pool_hash[r].misses); } b++; } atomic_inc_long((long*)&pool->missed); return 0; }
static inline struct sfm_frag* main_get_frag(struct sfm_block* qm, int hash, unsigned long size) #endif { int r; int next_block; struct sfm_frag* volatile* f; struct sfm_frag* frag; unsigned long b; unsigned long eob; r=hash; b=HASH_BIT_POS(r); while(r<=SF_MALLOC_OPTIMIZE/SF_ROUNDTO){ b=_next_set_bit(b, &qm->bitmap); next_block=_hash_range(b, &eob); r=(r<next_block)?next_block:r; for (; r<eob; r++){ f=&qm->free_hash[r].first; if ((frag=frag_pop((struct sfm_frag**)f))!=0){ atomic_dec_long((long*)&qm->free_hash[r].no); frag->u.nxt_free=0; /* mark it as 'taken' */ frag->id=pool_id; #ifdef DBG_F_MALLOC sfm_split_frag(qm, frag, size, file, func, line); #else sfm_split_frag(qm, frag, size); #endif return frag; } } b++; } /* big fragments */ SFM_BIG_GET_AND_SPLIT_LOCK(qm); for (; r<= sfm_max_hash ; r++){ f=&qm->free_hash[r].first; if (*f){ SFM_MAIN_HASH_LOCK(qm, r); if (unlikely((*f)==0)){ /* not found */ SFM_MAIN_HASH_UNLOCK(qm, r); continue; } for(;(*f); f=&((*f)->u.nxt_free)) if ((*f)->size>=size){ /* found, detach it from the free list*/ frag=*f; *f=frag->u.nxt_free; frag->u.nxt_free=0; /* mark it as 'taken' */ qm->free_hash[r].no--; SFM_MAIN_HASH_UNLOCK(qm, r); frag->id=pool_id; #ifdef DBG_F_MALLOC sfm_split_frag(qm, frag, size, file, func, line); #else sfm_split_frag(qm, frag, size); #endif SFM_BIG_GET_AND_SPLIT_UNLOCK(qm); return frag; }; SFM_MAIN_HASH_UNLOCK(qm, r); /* try in a bigger bucket */ } } SFM_BIG_GET_AND_SPLIT_UNLOCK(qm); return 0; }
static inline struct sfm_frag* pool_get_frag(struct sfm_block* qm, struct sfm_pool* pool, int hash, unsigned long size) #endif { int r; int next_block; struct sfm_frag* volatile* f; struct sfm_frag* frag; unsigned long b; unsigned long eob; /* special case for r=hash */ r=hash; f=&pool->pool_hash[r].first; if (*f==0) goto not_found; SFM_POOL_LOCK(pool, r); if (unlikely(*f==0)){ SFM_POOL_UNLOCK(pool, r); goto not_found; } found: /* detach it from the free list*/ frag=frag_pop((struct sfm_frag**)f); frag->u.nxt_free=0; /* mark it as 'taken' */ frag->id=pool_id; pool->pool_hash[r].no--; SFM_POOL_UNLOCK(pool, r); #ifdef DBG_F_MALLOC sfm_split_frag(qm, frag, size, file, func, line); #else sfm_split_frag(qm, frag, size); #endif if (&qm->pool[pool_id]==pool) atomic_inc_long((long*)&pool->hits); return frag; not_found: atomic_inc_long((long*)&pool->pool_hash[r].misses); r++; b=HASH_BIT_POS(r); while(r<SF_HASH_POOL_SIZE){ b=_next_set_bit(b, &pool->bitmap); next_block=_hash_range(b, &eob); r=(r<next_block)?next_block:r; for (; r<eob; r++){ f=&pool->pool_hash[r].first; if (*f){ SFM_POOL_LOCK(pool, r); if (unlikely(*f==0)){ /* not found */ SFM_POOL_UNLOCK(pool, r); }else goto found; } atomic_inc_long((long*)&pool->pool_hash[r].misses); } b++; } #if 0 /* EXPENSIVE BUG CHECK */ for (r=hash; r<SF_HASH_POOL_SIZE; r++){ f=&pool->pool_hash[r].first; if (*f){ SFM_POOL_LOCK(pool, r); if (unlikely(*f==0)){ /* not found */ SFM_POOL_UNLOCK(pool, r); }else{ b=_next_set_bit(HASH_BIT_POS(r), &pool->bitmap); next_block=_hash_range(b, &eob); BUG("pool_get_frag: found fragm. %d at %d (bit %ld range %ld-%ld), next set bit=%ld" " bitmap %ld (%p)\n", hash, r, HASH_BIT_POS(r), next_block, eob, b, pool->bitmap, &pool->bitmap); goto found; } } } #endif atomic_inc_long((long*)&pool->missed); return 0; }