static inline void sfm_insert_free(struct sfm_block* qm, struct sfm_frag* frag, int split) { struct sfm_frag** f; unsigned long p_id; int hash; unsigned long hash_bit; if (likely(frag->size<=SF_POOL_MAX_SIZE)){ hash=GET_SMALL_HASH(frag->size); if (unlikely((p_id=sfm_choose_pool(qm, frag, hash, split))== (unsigned long)-1)){ /* add it back to the "main" hash */ SFM_MAIN_HASH_LOCK(qm, hash); frag->id=(unsigned long)(-1); /* main hash marker */ /*insert it here*/ frag_push(&(qm->free_hash[hash].first), frag); qm->free_hash[hash].no++; /* set it only if not already set (avoids an expensive * cache trashing atomic write op) */ hash_bit=HASH_TO_BITMAP(hash); if (!(atomic_get_long((long*)&qm->bitmap) & hash_bit)) atomic_or_long((long*)&qm->bitmap, hash_bit); SFM_MAIN_HASH_UNLOCK(qm, hash); }else{ /* add it to one of the pools pool */ sfm_pool_insert(&qm->pool[p_id], hash, frag); } }else{ hash=GET_BIG_HASH(frag->size); SFM_MAIN_HASH_LOCK(qm, hash); f=&(qm->free_hash[hash].first); for(; *f; f=&((*f)->u.nxt_free)) if (frag->size <= (*f)->size) break; frag->id=(unsigned long)(-1); /* main hash marker */ /*insert it here*/ frag->u.nxt_free=*f; *f=frag; qm->free_hash[hash].no++; /* inc. big hash free size ? */ SFM_MAIN_HASH_UNLOCK(qm, hash); } }
void* sfm_malloc(struct sfm_block* qm, unsigned long size) #endif { struct sfm_frag* frag; int hash; unsigned int i; #ifdef DBG_F_MALLOC MDBG("sfm_malloc(%p, %lu) called from %s: %s(%d)\n", qm, size, file, func, line); #endif /*size must be a multiple of 8*/ size=ROUNDUP(size); /* if (size>(qm->size-qm->real_used)) return 0; */ /* check if our pool id is set */ sfm_fix_pool_id(qm); /*search for a suitable free frag*/ if (likely(size<=SF_POOL_MAX_SIZE)){ hash=GET_SMALL_HASH(size); /* try first in our pool */ #ifdef DBG_F_MALLOC if (likely((frag=pool_get_frag(qm, &qm->pool[pool_id], hash, size, file, func, line))!=0)) goto found; /* try in the "main" free hash, go through all the hash */ if (likely((frag=main_get_frag(qm, hash, size, file, func, line))!=0)) goto found; /* really low mem , try in other pools */ for (i=(pool_id+1); i< (pool_id+SFM_POOLS_NO); i++){ if ((frag=pool_get_frag(qm, &qm->pool[i%SFM_POOLS_NO], hash, size, file, func, line))!=0) goto found; } #else if (likely((frag=pool_get_frag(qm, &qm->pool[pool_id], hash, size)) !=0 )) goto found; /* try in the "main" free hash, go through all the hash */ if (likely((frag=main_get_frag(qm, hash, size))!=0)) goto found; /* really low mem , try in other pools */ for (i=(pool_id+1); i< (pool_id+SFM_POOLS_NO); i++){ if ((frag=pool_get_frag(qm, &qm->pool[i%SFM_POOLS_NO], hash, size)) !=0 ) goto found; } #endif /* not found, bad! */ return 0; }else{ hash=GET_BIG_HASH(size); #ifdef DBG_F_MALLOC if ((frag=main_get_frag(qm, hash, size, file, func, line))==0) return 0; /* not found, bad! */ #else if ((frag=main_get_frag(qm, hash, size))==0) return 0; /* not found, bad! */ #endif } found: /* we found it!*/ #ifdef DBG_F_MALLOC frag->file=file; frag->func=func; frag->line=line; frag->check=ST_CHECK_PATTERN; MDBG("sfm_malloc(%p, %lu) returns address %p \n", qm, size, (char*)frag+sizeof(struct sfm_frag)); #endif FRAG_MARK_USED(frag); /* mark it as used */ return (char*)frag+sizeof(struct sfm_frag); }