58 #define _DARWIN_C_SOURCE 64 #define USE_PRINTF (1) 69 #ifndef TLSF_USE_LOCKS 70 #define TLSF_USE_LOCKS (1) 73 #ifndef TLSF_STATISTIC 74 #define TLSF_STATISTIC (0) 89 #define TLSF_CREATE_LOCK(_unused_) do{}while(0) 90 #define TLSF_DESTROY_LOCK(_unused_) do{}while(0) 91 #define TLSF_ACQUIRE_LOCK(_unused_) do{}while(0) 92 #define TLSF_RELEASE_LOCK(_unused_) do{}while(0) 96 #define TLSF_ADD_SIZE(tlsf, b) do { \ 97 tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ 98 if (tlsf->used_size > tlsf->max_size) \ 99 tlsf->max_size = tlsf->used_size; \ 102 #define TLSF_REMOVE_SIZE(tlsf, b) do { \ 103 tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ 106 #define TLSF_ADD_SIZE(tlsf, b) do{}while(0) 107 #define TLSF_REMOVE_SIZE(tlsf, b) do{}while(0) 110 #if USE_MMAP || USE_SBRK 115 #include <sys/mman.h> 118 #define ORO_MEMORY_POOL 121 #if !defined(__GNUC__) 129 #define _DEBUG_TLSF_ (0) 138 #define BLOCK_ALIGN (sizeof(void *) * 2) 141 #define MAX_LOG2_SLI (5) 142 #define MAX_SLI (1 << MAX_LOG2_SLI) 144 #define FLI_OFFSET (6) 146 #define SMALL_BLOCK (128) 147 #define REAL_FLI (MAX_FLI - FLI_OFFSET) 148 #define MIN_BLOCK_SIZE (sizeof (free_ptr_t)) 149 #define BHDR_OVERHEAD (sizeof (bhdr_t) - MIN_BLOCK_SIZE) 150 #define TLSF_SIGNATURE (0x2A59FA59) 152 #define PTR_MASK (sizeof(void *) - 1) 153 #define BLOCK_SIZE ((intptr_t)~PTR_MASK) 159 #define TYPE_PUN(dsttype, srctype, x) \ 160 (((union {srctype *a; dsttype *b;})(x)).b) 162 #define TYPE_PUN(dsttype, srctype, x) ( (dsttype*)(x) ) 165 #define GET_NEXT_BLOCK(_addr, _r) TYPE_PUN(bhdr_t, char, (char *) (_addr) + (_r)) 167 #define MEM_ALIGN ((BLOCK_ALIGN) - 1) 168 #define ROUNDUP_SIZE(_r) (((_r) + MEM_ALIGN) & ~MEM_ALIGN) 169 #define ROUNDDOWN_SIZE(_r) ((_r) & ~MEM_ALIGN) 170 #define ROUNDUP(_x, _v) ((((~(_x)) + 1) & ((_v)-1)) + (_x)) 172 #define BLOCK_STATE (0x1) 173 #define PREV_STATE (0x2) 174 #define STATE_MASK (BLOCK_STATE | PREV_STATE) 177 #define FREE_BLOCK (0x1) 178 #define USED_BLOCK (0x0) 181 #define PREV_FREE (0x2) 182 #define PREV_USED (0x0) 185 #define DEFAULT_AREA_SIZE (1024*10) 188 #define TLSF_PAGE_SIZE (getpagesize()) 193 #define PRINT_MSG(fmt, args...) printf(fmt, ## args) 194 #define FPRINT_MSG(ff, fmt, args...) fprintf(ff, fmt, ## args) 195 #define ERROR_MSG(fmt, args...) printf(fmt, ## args) 197 # if !defined(PRINT_MSG) 198 # define PRINT_MSG(fmt, args...) 200 # if !defined(ERROR_MSG) 201 # define ERROR_MSG(fmt, args...) 245 size_t overhead_size;
278 #if USE_SBRK || USE_MMAP 279 static __inline__ void *get_new_area(
size_t * size);
288 -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
291 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
294 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
297 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
300 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
303 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
306 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
309 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
317 unsigned int x = i & -i;
319 a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
320 return table[x >> a] + a;
326 unsigned int x = (
unsigned int) i;
328 a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
329 return table[x >> a] + a;
334 addr[nr >> 5] |= 1 << (nr & 0x1f);
339 addr[nr >> 5] &= ~(1 << (nr & 0x1f));
382 _b = _tlsf->
matrix[*_fl][*_sl];
387 _b = _tlsf->
matrix[*_fl][*_sl];
394 static const char *k =
"* Heap corruption detected: *\n";
395 (void) write( STDERR_FILENO, k, strlen(k) );
396 (void) write( STDERR_FILENO, msg, strlen(msg) );
400 #define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do { \ 401 _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next; \ 402 if (_tlsf -> matrix[_fl][_sl]) \ 403 _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL; \ 405 clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ 406 if (!_tlsf -> sl_bitmap [_fl]) \ 407 clear_bit (_fl, &_tlsf -> fl_bitmap); \ 409 _b -> ptr.free_ptr.prev = NULL; \ 410 _b -> ptr.free_ptr.next = NULL; \ 414 #define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do { \ 415 if (_b -> ptr.free_ptr.next) \ 416 _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \ 417 if (_b -> ptr.free_ptr.prev) \ 418 _b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \ 419 if (_tlsf -> matrix [_fl][_sl] == _b) { \ 420 _tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next; \ 421 if (!_tlsf -> matrix [_fl][_sl]) { \ 422 clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]); \ 423 if (!_tlsf -> sl_bitmap [_fl]) \ 424 clear_bit (_fl, &_tlsf -> fl_bitmap); \ 427 _b -> ptr.free_ptr.prev = NULL; \ 428 _b -> ptr.free_ptr.next = NULL; \ 431 #define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do { \ 432 _b -> ptr.free_ptr.prev = NULL; \ 433 _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \ 434 if (_tlsf -> matrix [_fl][_sl]) \ 435 _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b; \ 436 _tlsf -> matrix [_fl][_sl] = _b; \ 437 set_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ 438 set_bit (_fl, &_tlsf -> fl_bitmap); \ 441 #if USE_SBRK || USE_MMAP 442 static __inline__ void *get_new_area(
size_t * size)
447 area = (
void *)sbrk(0);
448 if (((
void *)sbrk(*size)) != ((
void *) -1))
452 #ifndef MAP_ANONYMOUS 454 # define MAP_ANONYMOUS MAP_ANON 459 *size =
ROUNDUP(*size, TLSF_PAGE_SIZE);
460 if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED)
463 return ((
void *) ~0);
494 static char *
mp = NULL;
504 ERROR_MSG(
"init_memory_pool (): memory_pool invalid\n");
508 if (((
unsigned long) mem_pool &
PTR_MASK)) {
509 ERROR_MSG(
"init_memory_pool (): mem_pool must be aligned to a word\n");
512 tlsf = (
tlsf_t *) mem_pool;
523 memset(mem_pool, 0,
sizeof(
tlsf_t));
536 tlsf->pool_size = mem_pool_size;
538 tlsf->overhead_size = tlsf->used_size;
539 tlsf->max_size = tlsf->used_size;
551 bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
553 memset(area, 0, area_size);
570 if ((
unsigned long) ib1 == (
unsigned long) lb0 +
BHDR_OVERHEAD) {
591 if ((
unsigned long) lb1->
ptr.
buffer == (
unsigned long) ib0) {
629 return ((
tlsf_t *) mem_pool)->pool_size;
652 return ((
tlsf_t *) mem_pool)->overhead_size;
664 return (
mp ? ((
tlsf_t *)
mp)->overhead_size : 0);
675 return ((
tlsf_t *) mem_pool)->used_size;
698 return ((
tlsf_t *) mem_pool)->max_size;
720 if((
void*)
mp == (
void*)mem_pool){
738 #if USE_MMAP || USE_SBRK 745 area = get_new_area(&area_size);
746 if (area == ((
void *) ~0))
780 #if USE_MMAP || USE_SBRK 827 #if USE_MMAP || USE_SBRK 834 area = get_new_area(&area_size);
835 if (area == ((
void *) ~0))
853 if (tmp_size >=
sizeof(
bhdr_t)) {
873 corrupt(
"malloc_ex(): Mismatched flags after allocation\n");
892 corrupt(
"free_ex(): Freeing unused block\n" );
894 corrupt(
"free_ex(): Mismatched flags\n");
923 corrupt(
"free_ex(): uncoalesced block\n");
935 bhdr_t *b, *tmp_b, *next_b;
941 return (
void *)
malloc_ex(new_size, mem_pool);
944 }
else if (!new_size) {
953 if (new_size <= tmp_size) {
965 tmp_size -= new_size;
966 if (tmp_size >=
sizeof(
bhdr_t)) {
992 if (tmp_size >=
sizeof(
bhdr_t)) {
1007 if (!(ptr_aux =
malloc_ex(new_size, mem_pool))){
1013 memcpy(ptr_aux, ptr, cpsize);
1021 void *
calloc_ex(
size_t nelem,
size_t elem_size,
void *mem_pool)
1026 if (nelem <= 0 || elem_size <= 0)
1029 if (!(ptr =
malloc_ex(nelem * elem_size, mem_pool)))
1031 memset(ptr, 0, nelem * elem_size);
1046 extern void dump_memory_region(
unsigned char *mem_ptr,
unsigned int size);
1047 extern void print_block(FILE* ff,
bhdr_t * b);
1049 extern void print_tlsf(FILE* ff,
tlsf_t * tlsf);
1051 extern void print_all_blocks(FILE* ff,
tlsf_t * tlsf);
1053 void dump_memory_region(
unsigned char *mem_ptr,
unsigned int size)
1056 unsigned long begin = (
unsigned long) mem_ptr;
1057 unsigned long end = (
unsigned long) mem_ptr + size;
1067 PRINT_MSG(
"\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
1072 while (begin < end) {
1073 if (((
unsigned char *) begin)[0] == 0)
1076 PRINT_MSG(
"%02x", ((
unsigned char *) begin)[0]);
1077 if (((
unsigned char *) begin)[1] == 0)
1080 PRINT_MSG(
"%02x ", ((
unsigned char *) begin)[1]);
1092 void print_block(FILE* ff,
bhdr_t * b)
1112 void print_tlsf_mp(FILE* ff)
1114 if (0 == ff)
return;
1115 if (0 ==
mp)
return;
1122 void print_tlsf(FILE* ff,
tlsf_t * tlsf)
1124 if (0 == ff)
return;
1125 if (0 == tlsf)
return;
1137 for (j = 0; j <
MAX_SLI; j++) {
1138 next = tlsf->
matrix[i][j];
1142 print_block(ff, next);
1150 void print_all_blocks_mp(FILE* ff)
1152 if (0 == ff)
return;
1153 if (0 ==
mp)
return;
1156 print_all_blocks(ff, (
tlsf_t *)
mp);
1160 void print_all_blocks(FILE* ff,
tlsf_t * tlsf)
1162 if (0 == ff)
return;
1163 if (0 == tlsf)
return;
1167 FPRINT_MSG(ff,
"\nTLSF at %p\nALL BLOCKS\n", tlsf);
1169 FPRINT_MSG(ff,
" pool=%lu initial overhead=%lu max-possible-available=%lu\n",
1170 tlsf->pool_size, tlsf->overhead_size, (tlsf->pool_size - tlsf->overhead_size));
1171 FPRINT_MSG(ff,
" used=%lu max-used=%lu (both including initial overhead)\n",
1172 tlsf->used_size, tlsf->max_size);
1173 FPRINT_MSG(ff,
" used=%lu max-used=%lu (both without initial overhead)\n",
1174 (tlsf->used_size - tlsf->overhead_size), (tlsf->max_size - tlsf->overhead_size));
1175 FPRINT_MSG(ff,
" sizeof items bhdr_t=%lu area_info_t=%lu tlsf_t=%lu\n\n" ,
1181 print_block(ff, next);
bhdr_t * matrix[REAL_FLI][MAX_SLI]
struct bhdr_struct * next
#define ERROR_MSG(fmt, args...)
#define TLSF_ACQUIRE_LOCK(l)
void * realloc_ex(void *ptr, size_t new_size, void *mem_pool)
void * tlsf_malloc(size_t size)
#define INSERT_BLOCK(_b, _tlsf, _fl, _sl)
struct TLSF_struct tlsf_t
void * malloc_ex(size_t size, void *mem_pool)
struct area_info_struct area_info_t
static __inline__ int ms_bit(int x)
size_t add_new_area(void *area, size_t area_size, void *mem_pool)
size_t get_max_size(void *mem_pool)
void * calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
#define TYPE_PUN(dsttype, srctype, x)
struct free_ptr_struct free_ptr_t
union bhdr_struct::@4 ptr
static __inline__ void MAPPING_SEARCH(size_t *_r, int *_fl, int *_sl)
static __inline__ int ls_bit(int x)
size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
#define GET_NEXT_BLOCK(_addr, _r)
static __inline__ bhdr_t * FIND_SUITABLE_BLOCK(tlsf_t *_tlsf, int *_fl, int *_sl)
#define PRINT_MSG(fmt, args...)
#define TLSF_CREATE_LOCK(l)
void destroy_memory_pool(void *mem_pool)
static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
size_t get_overhead_size_mp(void)
void * tlsf_realloc(void *ptr, size_t size)
void tlsf_free(void *ptr)
size_t get_used_size_mp(void)
size_t get_pool_size_mp(void)
#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl)
void * tlsf_calloc(size_t nelem, size_t elem_size)
struct area_info_struct * next
static __inline__ void set_bit(int nr, u32_t *addr)
u32_t sl_bitmap[REAL_FLI]
#define TLSF_RELEASE_LOCK(l)
#define DEFAULT_AREA_SIZE
static __inline__ void corrupt(const char *s)
size_t get_pool_size(void *mem_pool)
#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl)
struct free_ptr_struct free_ptr
static __inline__ bhdr_t * process_area(void *area, size_t size)
size_t get_overhead_size(void *mem_pool)
static __inline__ void clear_bit(int nr, u32_t *addr)
#define TLSF_DESTROY_LOCK(l)
#define TLSF_REMOVE_SIZE(tlsf, b)
size_t get_max_size_mp(void)
struct bhdr_struct bhdr_t
#define TLSF_ADD_SIZE(tlsf, b)
void free_ex(void *ptr, void *mem_pool)
static __inline__ bhdr_t * encode_prev_block(bhdr_t *prev, size_t size)
size_t get_used_size(void *mem_pool)
struct bhdr_struct * prev_hdr
struct bhdr_struct * prev
#define ROUNDDOWN_SIZE(_r)
#define FPRINT_MSG(ff, fmt, args...)