Module: sip-router
Branch: master
Commit: 1ccbd33558e7e09f36f39fd984ac99a7bfd3eba2
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=1ccbd33…
Author: Andrei Pelinescu-Onciul <andrei(a)iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei(a)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++){