Пример #1
0
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);
	}
	
}
Пример #2
0
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);
}