浏览代码

mem: TLSF allocator integration in kamailio

- kamailio memory counters for statistics
- use
    MEMMNG=1 MEMDBG=0 extra_defs='-DTLSF_MALLOC=1
  to enable
- support for > 4GB memory (current limit is now 1TB)
Camille Oudot 10 年之前
父节点
当前提交
92dcf77047
共有 4 个文件被更改,包括 93 次插入4 次删除
  1. 2 0
      mem/shm_mem.c
  2. 13 0
      mem/shm_mem.h
  3. 74 4
      mem/tlsf.c
  4. 4 0
      mem/tlsf.h

+ 2 - 0
mem/shm_mem.c

@@ -64,6 +64,8 @@ static void* shm_mempool=(void*)-1;
 	struct fm_block* shm_block;
 #elif DL_MALLOC
 	mspace shm_block;
+#elif TLSF_MALLOC
+	tlsf_t shm_block;
 #else
 	struct qm_block* shm_block;
 #endif

+ 13 - 0
mem/shm_mem.h

@@ -143,6 +143,19 @@
 #	define  shm_malloc_init(buf, len, type) create_mspace_with_base(buf, len, 0)
 #	define shm_malloc_destroy(b) do{}while(0)
 #	define shm_malloc_on_fork() do{}while(0)
+#elif defined TLSF_MALLOC
+#	include "tlsf.h"
+	extern pool_t shm_block;
+#	define MY_MALLOC tlsf_malloc
+#	define MY_FREE tlsf_free
+#	define MY_REALLOC tlsf_realloc
+#	define MY_STATUS(...) ((void) 0)
+#	define MY_MEMINFO	tlsf_meminfo
+#	define MY_SUMS(...) ((void) 0)
+#	define shm_malloc_init(mem, bytes, type) tlsf_create_with_pool((void*) mem, bytes)
+#	define shm_malloc_destroy(b) do{}while(0)
+#	define shm_available() qm_available(shm_block)
+#	define shm_malloc_on_fork() do{}while(0)
 #else
 #	include "q_malloc.h"
 	extern struct qm_block* shm_block;

+ 74 - 4
mem/tlsf.c

@@ -47,7 +47,7 @@ enum tlsf_private
 	** TODO: We can increase this to support larger sizes, at the expense
 	** of more overhead in the TLSF structure.
 	*/
-	FL_INDEX_MAX = 32,
+	FL_INDEX_MAX = 40,
 #else
 	FL_INDEX_MAX = 30,
 #endif
@@ -148,13 +148,24 @@ static const size_t block_size_min =
 	sizeof(block_header_t) - sizeof(block_header_t*);
 static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX;
 
+#ifdef TLSF_STATS
+	#define TLSF_INCREASE_REAL_USED(control, increment) do {control->real_used += (increment) ; control->max_used = tlsf_max(control->real_used, control->max_used);}while(0)
+	#define TLSF_INCREASE_FRAGMENTS(control) do {control->fragments++ ; control->fragments = tlsf_max(control->fragments, control->max_fragments);}while(0)
+#endif
 
 /* The TLSF control structure. */
 typedef struct control_t
 {
 	/* Empty lists point at this block to indicate they are free. */
 	block_header_t block_null;
-
+#ifdef TLSF_STATS
+	size_t total_size;
+	size_t allocated;
+	size_t real_used;
+	size_t max_used;
+	size_t fragments;
+	size_t max_fragments;
+#endif
 	/* Bitmaps for free lists. */
 	unsigned int fl_bitmap;
 	unsigned int sl_bitmap[FL_INDEX_COUNT];
@@ -401,6 +412,9 @@ static void remove_free_block(control_t* control, block_header_t* block, int fl,
 			}
 		}
 	}
+#if defined TLSF_STATS
+	control->fragments--;
+#endif
 }
 
 /* Insert a free block into the free block list. */
@@ -422,6 +436,9 @@ static void insert_free_block(control_t* control, block_header_t* block, int fl,
 	control->blocks[fl][sl] = block;
 	control->fl_bitmap |= (1 << fl);
 	control->sl_bitmap[fl] |= (1 << sl);
+#if defined TLSF_STATS
+	TLSF_INCREASE_FRAGMENTS(control);
+#endif
 }
 
 /* Remove a given block from the free list. */
@@ -580,6 +597,10 @@ static void* block_prepare_used(control_t* control, block_header_t* block, size_
 		block_trim_free(control, block, size);
 		block_mark_as_used(block);
 		p = block_to_ptr(block);
+#ifdef TLSF_STATS
+		TLSF_INCREASE_REAL_USED(control, block->size + (p - (void *)block));
+		control->allocated += block->size;
+#endif
 	}
 	return p;
 }
@@ -806,7 +827,9 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
 	block_set_free(block);
 	block_set_prev_used(block);
 	block_insert(tlsf_cast(control_t*, tlsf), block);
-
+#ifdef TLSF_STATS
+	tlsf_cast(control_t*, tlsf)->total_size += block->size;
+#endif
 	/* Split the block to create a zero-size sentinel block. */
 	next = block_link_next(block);
 	block_set_size(next, 0);
@@ -829,6 +852,9 @@ void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
 
 	mapping_insert(block_size(block), &fl, &sl);
 	remove_free_block(control, block, fl, sl);
+#ifdef TLSF_STATS
+	tlsf_cast(control_t*, tlsf)->total_size -= block->size;
+#endif
 }
 
 /*
@@ -880,7 +906,13 @@ tlsf_t tlsf_create(void* mem)
 	}
 
 	control_construct(tlsf_cast(control_t*, mem));
-
+#ifdef TLSF_STATS
+	tlsf_cast(control_t*, mem)->real_used = tlsf_size();
+	tlsf_cast(control_t*, mem)->max_used = tlsf_size();
+	tlsf_cast(control_t*, mem)->allocated = 0;
+	tlsf_cast(control_t*, mem)->total_size = tlsf_size();
+	tlsf_cast(control_t*, mem)->fragments = 0;
+#endif
 	return tlsf_cast(tlsf_t, mem);
 }
 
@@ -961,6 +993,10 @@ void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size)
 		}
 	}
 
+#ifdef TLSF_STATS
+	/* TODO */
+#endif
+
 	return block_prepare_used(control, block, adjust);
 }
 
@@ -972,6 +1008,10 @@ void tlsf_free(tlsf_t tlsf, void* ptr)
 		control_t* control = tlsf_cast(control_t*, tlsf);
 		block_header_t* block = block_from_ptr(ptr);
 		tlsf_assert(!block_is_free(block) && "block already marked as free");
+#if defined TLSF_STATS
+		control->allocated -= block->size;
+		control->real_used -= (block->size + (ptr - (void *)block));
+#endif
 		block_mark_as_free(block);
 		block = block_merge_prev(control, block);
 		block = block_merge_next(control, block);
@@ -1034,6 +1074,10 @@ void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
 		}
 		else
 		{
+#ifdef TLSF_STATS
+			control->allocated -= block->size;
+			control->real_used -= block->size;
+#endif
 			/* Do we need to expand to the next block? */
 			if (adjust > cursize)
 			{
@@ -1044,8 +1088,34 @@ void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
 			/* Trim the resulting block and return the original pointer. */
 			block_trim_used(control, block, adjust);
 			p = ptr;
+#ifdef TLSF_STATS
+			control->allocated += block->size;
+			TLSF_INCREASE_REAL_USED(control, block->size);
+#endif
 		}
 	}
 
 	return p;
 }
+
+#ifdef TLSF_STATS
+
+void tlsf_meminfo(tlsf_t pool, struct mem_info *info)
+{
+	control_t* control = tlsf_cast(control_t*, pool);
+	memset(info, 0, sizeof(*info));
+	info->free = control->total_size - control->real_used;
+	info->max_used = control->max_used;
+	info->real_used = control->max_used;
+	info->total_frags = control->fragments;
+	info->used = control->allocated;
+	info->total_size = control->total_size;
+}
+
+size_t tlsf_available(tlsf_t pool)
+{
+	control_t* control = tlsf_cast(control_t*, pool);
+	return control->total_size - control->real_used;
+}
+#endif
+

+ 4 - 0
mem/tlsf.h

@@ -17,6 +17,8 @@
 */
 
 #include <stddef.h>
+#include "meminfo.h"
+#define TLSF_STATS
 
 #if defined(__cplusplus)
 extern "C" {
@@ -61,6 +63,8 @@ void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
 int tlsf_check(tlsf_t tlsf);
 int tlsf_check_pool(pool_t pool);
 
+void tlsf_meminfo(tlsf_t pool, struct mem_info *info);
+
 #if defined(__cplusplus)
 };
 #endif