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];
395 fputs(
"* Heap corruption detected: *\n", stderr);
401 #define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do { \ 402 _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next; \ 403 if (_tlsf -> matrix[_fl][_sl]) \ 404 _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL; \ 406 clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ 407 if (!_tlsf -> sl_bitmap [_fl]) \ 408 clear_bit (_fl, &_tlsf -> fl_bitmap); \ 410 _b -> ptr.free_ptr.prev = NULL; \ 411 _b -> ptr.free_ptr.next = NULL; \ 415 #define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do { \ 416 if (_b -> ptr.free_ptr.next) \ 417 _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \ 418 if (_b -> ptr.free_ptr.prev) \ 419 _b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \ 420 if (_tlsf -> matrix [_fl][_sl] == _b) { \ 421 _tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next; \ 422 if (!_tlsf -> matrix [_fl][_sl]) { \ 423 clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]); \ 424 if (!_tlsf -> sl_bitmap [_fl]) \ 425 clear_bit (_fl, &_tlsf -> fl_bitmap); \ 428 _b -> ptr.free_ptr.prev = NULL; \ 429 _b -> ptr.free_ptr.next = NULL; \ 432 #define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do { \ 433 _b -> ptr.free_ptr.prev = NULL; \ 434 _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \ 435 if (_tlsf -> matrix [_fl][_sl]) \ 436 _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b; \ 437 _tlsf -> matrix [_fl][_sl] = _b; \ 438 set_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ 439 set_bit (_fl, &_tlsf -> fl_bitmap); \ 442 #if USE_SBRK || USE_MMAP 443 static __inline__ void *get_new_area(
size_t * size)
448 area = (
void *)sbrk(0);
449 if (((
void *)sbrk(*size)) != ((
void *) -1))
453 #ifndef MAP_ANONYMOUS 455 # define MAP_ANONYMOUS MAP_ANON 460 *size =
ROUNDUP(*size, TLSF_PAGE_SIZE);
461 if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED)
464 return ((
void *) ~0);
495 static char *
mp = NULL;
505 ERROR_MSG(
"init_memory_pool (): memory_pool invalid\n");
509 if (((
unsigned long) mem_pool &
PTR_MASK)) {
510 ERROR_MSG(
"init_memory_pool (): mem_pool must be aligned to a word\n");
513 tlsf = (
tlsf_t *) mem_pool;
524 memset(mem_pool, 0,
sizeof(
tlsf_t));
537 tlsf->pool_size = mem_pool_size;
539 tlsf->overhead_size = tlsf->used_size;
540 tlsf->max_size = tlsf->used_size;
552 bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
554 memset(area, 0, area_size);
571 if ((
unsigned long) ib1 == (
unsigned long) lb0 +
BHDR_OVERHEAD) {
592 if ((
unsigned long) lb1->
ptr.
buffer == (
unsigned long) ib0) {
630 return ((
tlsf_t *) mem_pool)->pool_size;
653 return ((
tlsf_t *) mem_pool)->overhead_size;
665 return (
mp ? ((
tlsf_t *)
mp)->overhead_size : 0);
676 return ((
tlsf_t *) mem_pool)->used_size;
699 return ((
tlsf_t *) mem_pool)->max_size;
721 if((
void*)
mp == (
void*)mem_pool){
739 #if USE_MMAP || USE_SBRK 746 area = get_new_area(&area_size);
747 if (area == ((
void *) ~0))
781 #if USE_MMAP || USE_SBRK 828 #if USE_MMAP || USE_SBRK 835 area = get_new_area(&area_size);
836 if (area == ((
void *) ~0))
854 if (tmp_size >=
sizeof(
bhdr_t)) {
874 corrupt(
"malloc_ex(): Mismatched flags after allocation\n");
893 corrupt(
"free_ex(): Freeing unused block\n" );
895 corrupt(
"free_ex(): Mismatched flags\n");
924 corrupt(
"free_ex(): uncoalesced block\n");
936 bhdr_t *b, *tmp_b, *next_b;
942 return (
void *)
malloc_ex(new_size, mem_pool);
945 }
else if (!new_size) {
954 if (new_size <= tmp_size) {
966 tmp_size -= new_size;
967 if (tmp_size >=
sizeof(
bhdr_t)) {
993 if (tmp_size >=
sizeof(
bhdr_t)) {
1008 if (!(ptr_aux =
malloc_ex(new_size, mem_pool))){
1014 memcpy(ptr_aux, ptr, cpsize);
1022 void *
calloc_ex(
size_t nelem,
size_t elem_size,
void *mem_pool)
1027 if (nelem <= 0 || elem_size <= 0)
1030 if (!(ptr =
malloc_ex(nelem * elem_size, mem_pool)))
1032 memset(ptr, 0, nelem * elem_size);
1047 extern void dump_memory_region(
unsigned char *mem_ptr,
unsigned int size);
1048 extern void print_block(FILE* ff,
bhdr_t * b);
1050 extern void print_tlsf(FILE* ff,
tlsf_t * tlsf);
1052 extern void print_all_blocks(FILE* ff,
tlsf_t * tlsf);
1054 void dump_memory_region(
unsigned char *mem_ptr,
unsigned int size)
1057 unsigned long begin = (
unsigned long) mem_ptr;
1058 unsigned long end = (
unsigned long) mem_ptr + size;
1068 PRINT_MSG(
"\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
1073 while (begin < end) {
1074 if (((
unsigned char *) begin)[0] == 0)
1077 PRINT_MSG(
"%02x", ((
unsigned char *) begin)[0]);
1078 if (((
unsigned char *) begin)[1] == 0)
1081 PRINT_MSG(
"%02x ", ((
unsigned char *) begin)[1]);
1093 void print_block(FILE* ff,
bhdr_t * b)
1113 void print_tlsf_mp(FILE* ff)
1115 if (0 == ff)
return;
1116 if (0 ==
mp)
return;
1123 void print_tlsf(FILE* ff,
tlsf_t * tlsf)
1125 if (0 == ff)
return;
1126 if (0 == tlsf)
return;
1138 for (j = 0; j <
MAX_SLI; j++) {
1139 next = tlsf->
matrix[i][j];
1143 print_block(ff, next);
1151 void print_all_blocks_mp(FILE* ff)
1153 if (0 == ff)
return;
1154 if (0 ==
mp)
return;
1157 print_all_blocks(ff, (
tlsf_t *)
mp);
1161 void print_all_blocks(FILE* ff,
tlsf_t * tlsf)
1163 if (0 == ff)
return;
1164 if (0 == tlsf)
return;
1168 FPRINT_MSG(ff,
"\nTLSF at %p\nALL BLOCKS\n", tlsf);
1170 FPRINT_MSG(ff,
" pool=%lu initial overhead=%lu max-possible-available=%lu\n",
1171 tlsf->pool_size, tlsf->overhead_size, (tlsf->pool_size - tlsf->overhead_size));
1172 FPRINT_MSG(ff,
" used=%lu max-used=%lu (both including initial overhead)\n",
1173 tlsf->used_size, tlsf->max_size);
1174 FPRINT_MSG(ff,
" used=%lu max-used=%lu (both without initial overhead)\n",
1175 (tlsf->used_size - tlsf->overhead_size), (tlsf->max_size - tlsf->overhead_size));
1176 FPRINT_MSG(ff,
" sizeof items bhdr_t=%lu area_info_t=%lu tlsf_t=%lu\n\n" ,
1182 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...)