[sr-dev] git:kamailio_3.0: mem: fix f_malloc big fragments search

Andrei Pelinescu-Onciul andrei at iptel.org
Thu Sep 30 01:40:03 CEST 2010


Module: sip-router
Branch: kamailio_3.0
Commit: a22dc9b151d44dede21e3f500455eab568d14f28
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=a22dc9b151d44dede21e3f500455eab568d14f28

Author: Andrei Pelinescu-Onciul <andrei at iptel.org>
Committer: Andrei Pelinescu-Onciul <andrei at 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).
(cherry picked from commit 1ccbd33558e7e09f36f39fd984ac99a7bfd3eba2)

---

 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++){




More information about the sr-dev mailing list