Browse code

mem/f_malloc: link previous free fragment to speed up join

Daniel-Constantin Mierla authored on 03/05/2014 07:18:40
Showing 2 changed files
... ...
@@ -211,7 +211,9 @@ static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag)
211 211
 	}
212 212
 	
213 213
 	/*insert it here*/
214
+	frag->prv_free = f;
214 215
 	frag->u.nxt_free=*f;
216
+	if (*f) (*f)->prv_free = &(frag->u.nxt_free);
215 217
 	*f=frag;
216 218
 	qm->free_hash[hash].no++;
217 219
 #ifdef F_MALLOC_HASH_BITMAP
... ...
@@ -320,9 +322,12 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size)
320 322
 	
321 323
 	qm->first_frag=(struct fm_frag*)(start+ROUNDUP(sizeof(struct fm_block)));
322 324
 	qm->last_frag=(struct fm_frag*)(end-sizeof(struct fm_frag));
323
-	/* init initial fragment*/
325
+	/* init first fragment*/
324 326
 	qm->first_frag->size=size;
327
+	qm->first_frag->prv_free=0;
328
+	/* init last fragment*/
325 329
 	qm->last_frag->size=0;
330
+	qm->last_frag->prv_free=0;
326 331
 	
327 332
 #ifdef DBG_F_MALLOC
328 333
 	qm->first_frag->check=ST_CHECK_PATTERN;
... ...
@@ -418,8 +423,10 @@ found:
418 423
 	/* we found it!*/
419 424
 	/* detach it from the free list*/
420 425
 	frag=*f;
426
+	if(frag->u.nxt_free) frag->u.nxt_free->prv_free = frag->prv_free;
421 427
 	*f=frag->u.nxt_free;
422 428
 	frag->u.nxt_free=0; /* mark it as 'taken' */
429
+	frag->prv_free=0;
423 430
 	qm->free_hash[hash].no--;
424 431
 #ifdef F_MALLOC_HASH_BITMAP
425 432
 	if (qm->free_hash[hash].no==0)
... ...
@@ -472,9 +479,7 @@ static void fm_join_frag(struct fm_block* qm, struct fm_frag* f)
472 479
 
473 480
 	/* detach n from the free list */
474 481
 	hash=GET_HASH(n->size);
475
-	pf=&(qm->free_hash[hash].first);
476
-	/* find it */
477
-	for(;(*pf)&&(*pf!=n); pf=&((*pf)->u.nxt_free)); /*FIXME slow */
482
+	pf=n->prv_free;
478 483
 	if (*pf==0){
479 484
 		/* not found, bad! */
480 485
 		LM_WARN("could not find %p in free list (hash=%ld)\n", n, GET_HASH(n->size));
... ...
@@ -482,6 +487,7 @@ static void fm_join_frag(struct fm_block* qm, struct fm_frag* f)
482 487
 	}
483 488
 	/* detach */
484 489
 	*pf=n->u.nxt_free;
490
+	if(n->u.nxt_free) n->u.nxt_free->prv_free = pf;
485 491
 	qm->free_hash[hash].no--;
486 492
 #ifdef F_MALLOC_HASH_BITMAP
487 493
 	if (qm->free_hash[hash].no==0)
... ...
@@ -649,9 +655,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
649 655
 			/* join  */
650 656
 			/* detach n from the free list */
651 657
 			hash=GET_HASH(n->size);
652
-			pf=&(qm->free_hash[hash].first);
653
-			/* find it */
654
-			for(;(*pf)&&(*pf!=n); pf=&((*pf)->u.nxt_free)); /*FIXME slow */
658
+			pf=n->prv_free;
655 659
 			if (*pf==0){
656 660
 				/* not found, bad! */
657 661
 				LOG(L_CRIT, "BUG: fm_realloc: could not find %p in free "
... ...
@@ -660,6 +664,7 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
660 664
 			}
661 665
 			/* detach */
662 666
 			*pf=n->u.nxt_free;
667
+			if(n->u.nxt_free) n->u.nxt_free->prv_free = pf;
663 668
 			qm->free_hash[hash].no--;
664 669
 #ifdef F_MALLOC_HASH_BITMAP
665 670
 			if (qm->free_hash[hash].no==0)
... ...
@@ -96,6 +96,7 @@ struct fm_frag{
96 96
 		struct fm_frag* nxt_free;
97 97
 		long reserved;
98 98
 	}u;
99
+	struct fm_frag** prv_free;
99 100
 #ifdef DBG_F_MALLOC
100 101
 	const char* file;
101 102
 	const char* func;