Browse code

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 authored on 21/04/2015 15:03:06
Showing 4 changed files
... ...
@@ -64,6 +64,8 @@ static void* shm_mempool=(void*)-1;
64 64
 	struct fm_block* shm_block;
65 65
 #elif DL_MALLOC
66 66
 	mspace shm_block;
67
+#elif TLSF_MALLOC
68
+	tlsf_t shm_block;
67 69
 #else
68 70
 	struct qm_block* shm_block;
69 71
 #endif
... ...
@@ -143,6 +143,19 @@
143 143
 #	define  shm_malloc_init(buf, len, type) create_mspace_with_base(buf, len, 0)
144 144
 #	define shm_malloc_destroy(b) do{}while(0)
145 145
 #	define shm_malloc_on_fork() do{}while(0)
146
+#elif defined TLSF_MALLOC
147
+#	include "tlsf.h"
148
+	extern pool_t shm_block;
149
+#	define MY_MALLOC tlsf_malloc
150
+#	define MY_FREE tlsf_free
151
+#	define MY_REALLOC tlsf_realloc
152
+#	define MY_STATUS(...) ((void) 0)
153
+#	define MY_MEMINFO	tlsf_meminfo
154
+#	define MY_SUMS(...) ((void) 0)
155
+#	define shm_malloc_init(mem, bytes, type) tlsf_create_with_pool((void*) mem, bytes)
156
+#	define shm_malloc_destroy(b) do{}while(0)
157
+#	define shm_available() qm_available(shm_block)
158
+#	define shm_malloc_on_fork() do{}while(0)
146 159
 #else
147 160
 #	include "q_malloc.h"
148 161
 	extern struct qm_block* shm_block;
... ...
@@ -47,7 +47,7 @@ enum tlsf_private
47 47
 	** TODO: We can increase this to support larger sizes, at the expense
48 48
 	** of more overhead in the TLSF structure.
49 49
 	*/
50
-	FL_INDEX_MAX = 32,
50
+	FL_INDEX_MAX = 40,
51 51
 #else
52 52
 	FL_INDEX_MAX = 30,
53 53
 #endif
... ...
@@ -148,13 +148,24 @@ static const size_t block_size_min =
148 148
 	sizeof(block_header_t) - sizeof(block_header_t*);
149 149
 static const size_t block_size_max = tlsf_cast(size_t, 1) << FL_INDEX_MAX;
150 150
 
151
+#ifdef TLSF_STATS
152
+	#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)
153
+	#define TLSF_INCREASE_FRAGMENTS(control) do {control->fragments++ ; control->fragments = tlsf_max(control->fragments, control->max_fragments);}while(0)
154
+#endif
151 155
 
152 156
 /* The TLSF control structure. */
153 157
 typedef struct control_t
154 158
 {
155 159
 	/* Empty lists point at this block to indicate they are free. */
156 160
 	block_header_t block_null;
157
-
161
+#ifdef TLSF_STATS
162
+	size_t total_size;
163
+	size_t allocated;
164
+	size_t real_used;
165
+	size_t max_used;
166
+	size_t fragments;
167
+	size_t max_fragments;
168
+#endif
158 169
 	/* Bitmaps for free lists. */
159 170
 	unsigned int fl_bitmap;
160 171
 	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,
401 401
 			}
402 402
 		}
403 403
 	}
404
+#if defined TLSF_STATS
405
+	control->fragments--;
406
+#endif
404 407
 }
405 408
 
406 409
 /* 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,
422 422
 	control->blocks[fl][sl] = block;
423 423
 	control->fl_bitmap |= (1 << fl);
424 424
 	control->sl_bitmap[fl] |= (1 << sl);
425
+#if defined TLSF_STATS
426
+	TLSF_INCREASE_FRAGMENTS(control);
427
+#endif
425 428
 }
426 429
 
427 430
 /* 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_
580 580
 		block_trim_free(control, block, size);
581 581
 		block_mark_as_used(block);
582 582
 		p = block_to_ptr(block);
583
+#ifdef TLSF_STATS
584
+		TLSF_INCREASE_REAL_USED(control, block->size + (p - (void *)block));
585
+		control->allocated += block->size;
586
+#endif
583 587
 	}
584 588
 	return p;
585 589
 }
... ...
@@ -806,7 +827,9 @@ pool_t tlsf_add_pool(tlsf_t tlsf, void* mem, size_t bytes)
806 806
 	block_set_free(block);
807 807
 	block_set_prev_used(block);
808 808
 	block_insert(tlsf_cast(control_t*, tlsf), block);
809
-
809
+#ifdef TLSF_STATS
810
+	tlsf_cast(control_t*, tlsf)->total_size += block->size;
811
+#endif
810 812
 	/* Split the block to create a zero-size sentinel block. */
811 813
 	next = block_link_next(block);
812 814
 	block_set_size(next, 0);
... ...
@@ -829,6 +852,9 @@ void tlsf_remove_pool(tlsf_t tlsf, pool_t pool)
829 829
 
830 830
 	mapping_insert(block_size(block), &fl, &sl);
831 831
 	remove_free_block(control, block, fl, sl);
832
+#ifdef TLSF_STATS
833
+	tlsf_cast(control_t*, tlsf)->total_size -= block->size;
834
+#endif
832 835
 }
833 836
 
834 837
 /*
... ...
@@ -880,7 +906,13 @@ tlsf_t tlsf_create(void* mem)
880 880
 	}
881 881
 
882 882
 	control_construct(tlsf_cast(control_t*, mem));
883
-
883
+#ifdef TLSF_STATS
884
+	tlsf_cast(control_t*, mem)->real_used = tlsf_size();
885
+	tlsf_cast(control_t*, mem)->max_used = tlsf_size();
886
+	tlsf_cast(control_t*, mem)->allocated = 0;
887
+	tlsf_cast(control_t*, mem)->total_size = tlsf_size();
888
+	tlsf_cast(control_t*, mem)->fragments = 0;
889
+#endif
884 890
 	return tlsf_cast(tlsf_t, mem);
885 891
 }
886 892
 
... ...
@@ -961,6 +993,10 @@ void* tlsf_memalign(tlsf_t tlsf, size_t align, size_t size)
961 961
 		}
962 962
 	}
963 963
 
964
+#ifdef TLSF_STATS
965
+	/* TODO */
966
+#endif
967
+
964 968
 	return block_prepare_used(control, block, adjust);
965 969
 }
966 970
 
... ...
@@ -972,6 +1008,10 @@ void tlsf_free(tlsf_t tlsf, void* ptr)
972 972
 		control_t* control = tlsf_cast(control_t*, tlsf);
973 973
 		block_header_t* block = block_from_ptr(ptr);
974 974
 		tlsf_assert(!block_is_free(block) && "block already marked as free");
975
+#if defined TLSF_STATS
976
+		control->allocated -= block->size;
977
+		control->real_used -= (block->size + (ptr - (void *)block));
978
+#endif
975 979
 		block_mark_as_free(block);
976 980
 		block = block_merge_prev(control, block);
977 981
 		block = block_merge_next(control, block);
... ...
@@ -1034,6 +1074,10 @@ void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
1034 1034
 		}
1035 1035
 		else
1036 1036
 		{
1037
+#ifdef TLSF_STATS
1038
+			control->allocated -= block->size;
1039
+			control->real_used -= block->size;
1040
+#endif
1037 1041
 			/* Do we need to expand to the next block? */
1038 1042
 			if (adjust > cursize)
1039 1043
 			{
... ...
@@ -1044,8 +1088,34 @@ void* tlsf_realloc(tlsf_t tlsf, void* ptr, size_t size)
1044 1044
 			/* Trim the resulting block and return the original pointer. */
1045 1045
 			block_trim_used(control, block, adjust);
1046 1046
 			p = ptr;
1047
+#ifdef TLSF_STATS
1048
+			control->allocated += block->size;
1049
+			TLSF_INCREASE_REAL_USED(control, block->size);
1050
+#endif
1047 1051
 		}
1048 1052
 	}
1049 1053
 
1050 1054
 	return p;
1051 1055
 }
1056
+
1057
+#ifdef TLSF_STATS
1058
+
1059
+void tlsf_meminfo(tlsf_t pool, struct mem_info *info)
1060
+{
1061
+	control_t* control = tlsf_cast(control_t*, pool);
1062
+	memset(info, 0, sizeof(*info));
1063
+	info->free = control->total_size - control->real_used;
1064
+	info->max_used = control->max_used;
1065
+	info->real_used = control->max_used;
1066
+	info->total_frags = control->fragments;
1067
+	info->used = control->allocated;
1068
+	info->total_size = control->total_size;
1069
+}
1070
+
1071
+size_t tlsf_available(tlsf_t pool)
1072
+{
1073
+	control_t* control = tlsf_cast(control_t*, pool);
1074
+	return control->total_size - control->real_used;
1075
+}
1076
+#endif
1077
+
... ...
@@ -17,6 +17,8 @@
17 17
 */
18 18
 
19 19
 #include <stddef.h>
20
+#include "meminfo.h"
21
+#define TLSF_STATS
20 22
 
21 23
 #if defined(__cplusplus)
22 24
 extern "C" {
... ...
@@ -61,6 +63,8 @@ void tlsf_walk_pool(pool_t pool, tlsf_walker walker, void* user);
61 61
 int tlsf_check(tlsf_t tlsf);
62 62
 int tlsf_check_pool(pool_t pool);
63 63
 
64
+void tlsf_meminfo(tlsf_t pool, struct mem_info *info);
65
+
64 66
 #if defined(__cplusplus)
65 67
 };
66 68
 #endif