Module: sip-router Branch: master Commit: 1ccbd33558e7e09f36f39fd984ac99a7bfd3eba2 URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1ccbd335...
Author: Andrei Pelinescu-Onciul andrei@iptel.org Committer: Andrei Pelinescu-Onciul andrei@iptel.org Date: Thu Sep 30 01:28:00 2010 +0200
mem: fix f_malloc big fragments search
In some situation (depending on previous allocation and frees) trying to allocate a "big" fragment (>16k) would fail even if enough memory was available (the fragment search algorithm missed fallback to bigger buckets when using the free bitmap).
---
mem/f_malloc.c | 28 +++++++++++++++++++++++----- 1 files changed, 23 insertions(+), 5 deletions(-)
diff --git a/mem/f_malloc.c b/mem/f_malloc.c index 49c4b7a..6fa88c3 100644 --- a/mem/f_malloc.c +++ b/mem/f_malloc.c @@ -34,6 +34,12 @@ * 2007-02-23 added fm_available() (andrei) * 2007-06-23 added hash bitmap (andrei) * 2009-09-28 added fm_sums() (patch from Dragos Vingarzan) + * 2010-03-11 fix big fragments bug (smaller fragment was wrongly + * returned sometimes) (andrei) + * 2010-03-12 fix real_used stats for realloc: a realloc that shrank an + * allocation accounted twice fro the frag. overhead (andrei) + * 2010-09-30 fixed search for big fragments using the hash bitmap + * (only the first bucket was tried) (andrei) */
@@ -336,11 +342,23 @@ void* fm_malloc(struct fm_block* qm, unsigned long size) #ifdef F_MALLOC_HASH_BITMAP hash=fm_bmp_first_set(qm, GET_HASH(size)); if (likely(hash>=0)){ - f=&(qm->free_hash[hash].first); - if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) /* return first match */ - goto found; - for(;(*f); f=&((*f)->u.nxt_free)) - if ((*f)->size>=size) goto found; + if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */ + f=&(qm->free_hash[hash].first); + goto found; + } + /* if we are here we are searching for a "big" fragment + between F_MALLOC_OPTIMIZE/ROUNDTO+1 + and F_MALLOC_OPTIMIZE/ROUNDTO + (32|64) - F_MALLOC_OPTIMIZE_FACTOR + => 18 hash buckets on 32 bits and 50 buckets on 64 bits + The free hash bitmap is used to jump directly to non-empty + hash buckets. + */ + do { + for(f=&(qm->free_hash[hash].first);(*f); f=&((*f)->u.nxt_free)) + if ((*f)->size>=size) goto found; + hash++; /* try in next hash cell */ + }while((hash < F_HASH_SIZE) && + ((hash=fm_bmp_first_set(qm, hash)) >= 0)); } #else /* F_MALLOC_HASH_BITMAP */ for(hash=GET_HASH(size);hash<F_HASH_SIZE;hash++){