Browse code

core: mem - use mem_safety for f_malloc when DBG_F_MALLOC defined

- added helper function to join a fragment with the next one when both
are free, controlled by define MEM_JOIN_FREE and mem_join parameter

Daniel-Constantin Mierla authored on 30/03/2012 07:29:18
Showing 1 changed files
... ...
@@ -445,6 +445,49 @@ found:
445 445
 }
446 446
 
447 447
 
448
+#ifdef MEM_JOIN_FREE
449
+/**
450
+ * join fragment f with next one (if it is free)
451
+ */
452
+static void fm_join_frag(struct fm_block* qm, struct fm_frag* f)
453
+{
454
+	int hash;
455
+	struct fm_frag **pf;
456
+	struct fm_frag* n;
457
+
458
+	n=FRAG_NEXT(f);
459
+	/* check if valid and if in free list */
460
+	if (((char*)n >= (char*)qm->last_frag) || (n->u.nxt_free==NULL))
461
+		return;
462
+
463
+	/* detach n from the free list */
464
+	hash=GET_HASH(n->size);
465
+	pf=&(qm->free_hash[hash].first);
466
+	/* find it */
467
+	for(;(*pf)&&(*pf!=n); pf=&((*pf)->u.nxt_free)); /*FIXME slow */
468
+	if (*pf==0){
469
+		/* not found, bad! */
470
+		LM_WARN("could not find %p in free list (hash=%ld)\n", n, GET_HASH(n->size));
471
+		return;
472
+	}
473
+	/* detach */
474
+	*pf=n->u.nxt_free;
475
+	qm->free_hash[hash].no--;
476
+#ifdef F_MALLOC_HASH_BITMAP
477
+	if (qm->free_hash[hash].no==0)
478
+		fm_bmp_reset(qm, hash);
479
+#endif /* F_MALLOC_HASH_BITMAP */
480
+	/* join */
481
+	f->size+=n->size+FRAG_OVERHEAD;
482
+#if defined(DBG_F_MALLOC) || defined(MALLOC_STATS)
483
+	qm->real_used-=FRAG_OVERHEAD;
484
+#ifdef MALLOC_STATS
485
+	sr_event_exec(SREV_PKG_SET_REAL_USED, (void*)qm->real_used);
486
+#endif /* MALLOC_STATS */
487
+#endif /* DBG_F_MALLOC || MALLOC_STATS*/
488
+}
489
+#endif /*MEM_JOIN_FREE*/
490
+
448 491
 /**
449 492
  * \brief Main memory manager free function
450 493
  * 
... ...
@@ -465,9 +508,11 @@ void fm_free(struct fm_block* qm, void* p)
465 508
 #ifdef DBG_F_MALLOC
466 509
 	MDBG("fm_free(%p, %p), called from %s: %s(%d)\n", qm, p, file, func, line);
467 510
 	if (p>(void*)qm->last_frag || p<(void*)qm->first_frag){
468
-		LOG(L_CRIT, "BUG: fm_free: bad pointer %p (out of memory block!) - "
469
-				"aborting\n", p);
470
-		abort();
511
+		LOG(L_CRIT, "BUG: fm_free: bad pointer %p (out of memory block!),"
512
+				" called from %s: %s(%d) - aborting\n", p,
513
+				file, func, line);
514
+		if(likely(cfg_get(core, core_cfg, mem_safety)==0))
515
+			abort();
471 516
 	}
472 517
 #endif
473 518
 	if (p==0) {
... ...
@@ -493,6 +538,10 @@ void fm_free(struct fm_block* qm, void* p)
493 538
 	f->func=func;
494 539
 	f->line=line;
495 540
 #endif
541
+#ifdef MEM_JOIN_FREE
542
+	if(unlikely(cfg_get(core, core_cfg, mem_join)!=0))
543
+		fm_join_frag(qm, f);
544
+#endif /*MEM_JOIN_FREE*/
496 545
 	fm_insert_free(qm, f);
497 546
 }
498 547