diff --git a/mem/f_malloc.c b/mem/f_malloc.c index 55c48ec247c..da13e565e50 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -91,7 +91,8 @@ ((qm)->free_bitmap[(b)/FM_HASH_BMP_BITS] & (1UL<<((b)%FM_HASH_BMP_BITS))) -#define fm_is_free(f) ((f)->u.nxt_free) +#define fm_is_free(f) ((f)->is_free) + /** * \brief Find the first free fragment in a memory block * @@ -158,12 +159,10 @@ inline static int fm_bmp_first_set(struct fm_block* qm, int start) * \name Memory manager boundary check pattern */ /*@{ */ -#ifdef DBG_F_MALLOC #define ST_CHECK_PATTERN 0xf0f0f0f0 /** inserted at the beginning */ #define END_CHECK_PATTERN1 0xc0c0c0c0 /** inserted at the end */ #define END_CHECK_PATTERN2 0xabcdefed /** inserted at the end */ /*@} */ -#endif /** @@ -177,26 +176,25 @@ static inline void fm_extract_free(struct fm_block* qm, struct fm_frag* frag) hash = GET_HASH(frag->size); - if(frag->prv_free) { - frag->prv_free->u.nxt_free = frag->u.nxt_free; + if(frag->prev_free) { + frag->prev_free->next_free = frag->next_free; } else { - if(frag->u.nxt_free!=qm->last_frag) - qm->free_hash[hash].first = frag->u.nxt_free; - else - qm->free_hash[hash].first = NULL; + qm->free_hash[hash].first = frag->next_free; } - if(frag->u.nxt_free && frag->u.nxt_free!=qm->last_frag) { - frag->u.nxt_free->prv_free = frag->prv_free; + if(frag->next_free) { + frag->next_free->prev_free = frag->prev_free; } + frag->prev_free = NULL; + frag->next_free = NULL; + frag->is_free = 0; + qm->ffrags--; qm->free_hash[hash].no--; #ifdef F_MALLOC_HASH_BITMAP if (qm->free_hash[hash].no==0) fm_bmp_reset(qm, hash); #endif /* F_MALLOC_HASH_BITMAP */ - frag->prv_free = NULL; - frag->u.nxt_free = NULL; qm->real_used+=frag->size; qm->used+=frag->size; @@ -210,55 +208,41 @@ static inline void fm_extract_free(struct fm_block* qm, struct fm_frag* frag) static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag) { struct fm_frag* f; + struct fm_frag* p; int hash; - int after; hash=GET_HASH(frag->size); f=qm->free_hash[hash].first; + p=NULL; if (frag->size > F_MALLOC_OPTIMIZE){ /* because of '<=' in GET_HASH, (different from 0.8.1[24] on purpose --andrei ) */ - after = 0; /* large fragments list -- add at a position ordered by size */ - for(; f; f=f->u.nxt_free){ + for(; f; f=f->next_free){ if (frag->size <= f->size) break; - if(f->u.nxt_free==qm->last_frag) { - /*size greater than last frag in slot*/ - after = 1; - break; - } + p = f; } + frag->next_free = f; + frag->prev_free = p; if(f) { - if(after) { - /*insert frag after f*/ - frag->prv_free=f; - f->u.nxt_free=frag; - frag->u.nxt_free = qm->last_frag; - } else { - /*insert frag before f*/ - frag->u.nxt_free = f; - frag->prv_free=f->prv_free; - if(f->prv_free) f->prv_free->u.nxt_free = frag; - if(qm->free_hash[hash].first==f) qm->free_hash[hash].first = frag; - } + f->prev_free = frag; + } + if(p) { + p->next_free = frag; } else { - /* to be only one in slot */ qm->free_hash[hash].first = frag; - frag->prv_free=0; - frag->u.nxt_free = qm->last_frag; } } else { /* fixed fragment size list -- add first */ - frag->prv_free=0; + frag->prev_free = 0; + frag->next_free = f; if(f) { - f->prv_free = frag; - frag->u.nxt_free = f; - } else { - frag->u.nxt_free = qm->last_frag; + f->prev_free = frag; } qm->free_hash[hash].first = frag; } + frag->is_free = 1; qm->ffrags++; qm->free_hash[hash].no++; #ifdef F_MALLOC_HASH_BITMAP @@ -307,8 +291,8 @@ void fm_split_frag(struct fm_block* qm, struct fm_frag* frag, n->file=file; n->func="frag. from fm_split_frag"; n->line=line; - n->check=ST_CHECK_PATTERN; #endif + n->check=ST_CHECK_PATTERN; /* reinsert n in free list*/ qm->used-=FRAG_OVERHEAD; fm_insert_free(qm, n); @@ -366,17 +350,17 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size, int type) qm->last_frag=(struct fm_frag*)(end-sizeof(struct fm_frag)); /* init first fragment*/ qm->first_frag->size=size; - qm->first_frag->prv_free=0; - qm->first_frag->u.nxt_free=0; + qm->first_frag->prev_free=0; + qm->first_frag->next_free=0; + qm->first_frag->is_free=0; /* init last fragment*/ qm->last_frag->size=0; - qm->last_frag->prv_free=0; - qm->last_frag->u.nxt_free=0; + qm->last_frag->prev_free=0; + qm->last_frag->next_free=0; + qm->last_frag->is_free=0; -#ifdef DBG_F_MALLOC qm->first_frag->check=ST_CHECK_PATTERN; qm->last_frag->check=END_CHECK_PATTERN1; -#endif /* link initial fragment into the free list*/ @@ -464,7 +448,7 @@ void* fm_malloc(void* qmp, unsigned long size) if (likely(hash>=0)){ if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */ f=qm->free_hash[hash].first; - if(likely(f && f!=qm->last_frag)) goto found; + if(likely(f)) goto found; #ifdef DBG_F_MALLOC MDBG(" block %p hash %d empty but no. is %lu\n", qm, hash, qm->free_hash[hash].no); @@ -482,7 +466,7 @@ void* fm_malloc(void* qmp, unsigned long size) hash buckets. */ do { - for(f=qm->free_hash[hash].first; f && f!=qm->last_frag; f=f->u.nxt_free) + for(f=qm->free_hash[hash].first; f; f=f->next_free) if (f->size>=size) goto found; hash++; /* try in next hash cell */ }while((hash < F_HASH_SIZE) && @@ -491,7 +475,7 @@ void* fm_malloc(void* qmp, unsigned long size) #else /* F_MALLOC_HASH_BITMAP */ for(hash=GET_HASH(size);hashfree_hash[hash].first; - for(;f && f!=qm->last_frag; f=f->u.nxt_free) + for(; f; f=f->u.nxt_free) if (f->size>=size) goto found; /* try in a bigger bucket */ } @@ -523,10 +507,10 @@ void* fm_malloc(void* qmp, unsigned long size) frag->file=file; frag->func=func; frag->line=line; - frag->check=ST_CHECK_PATTERN; MDBG("fm_malloc(%p, %lu) returns address %p \n", qm, size, (char*)frag+sizeof(struct fm_frag)); #endif + frag->check=ST_CHECK_PATTERN; if (qm->max_real_usedreal_used) qm->max_real_used=qm->real_used; @@ -804,7 +788,7 @@ void fm_status(void* qmp) for(h=0,i=0,size=0;hfree_hash[h].first,j=0; f; - size+=f->size,f=f->u.nxt_free,i++,j++){ + size+=f->size,f=f->next_free,i++,j++){ if (!FRAG_WAS_USED(f)){ unused++; #ifdef DBG_F_MALLOC diff --git a/mem/f_malloc.h b/mem/f_malloc.h index 629fd45db3a..9344ea07a18 100644 --- a/mem/f_malloc.h +++ b/mem/f_malloc.h @@ -79,19 +79,16 @@ typedef unsigned long fm_hash_bitmap_t; * - +1 .... end - size = 2^k, big buckets */ struct fm_frag{ - unsigned long size; /* size of fragment */ - union{ - struct fm_frag* nxt_free; /* next free frag in slot, last poitns to qm last_frag, - used to detect if fragment is free (when not null) */ - long reserved; - }u; - struct fm_frag* prv_free; /* prev free frag in slot - for faster join/defrag */ + unsigned long size; /* size of fragment */ + struct fm_frag* next_free; /* next free frag in slot */ + struct fm_frag* prev_free; /* prev free frag in slot - for faster join/defrag */ + unsigned int is_free; /* used to detect if fragment is free (when not 0) */ #ifdef DBG_F_MALLOC const char* file; const char* func; unsigned long line; - unsigned long check; #endif + unsigned int check; }; struct fm_frag_lnk{