56 #define USE_PRINTF (1) 61 #ifndef TLSF_USE_LOCKS 62 #define TLSF_USE_LOCKS (0) 65 #ifndef TLSF_STATISTIC 66 #define TLSF_STATISTIC (0) 77 #ifndef CHECK_DOUBLE_FREE 78 #define CHECK_DOUBLE_FREE (0) 84 #define TLSF_CREATE_LOCK(_unused_) do{}while(0) 85 #define TLSF_DESTROY_LOCK(_unused_) do{}while(0) 86 #define TLSF_ACQUIRE_LOCK(_unused_) do{}while(0) 87 #define TLSF_RELEASE_LOCK(_unused_) do{}while(0) 91 #define TLSF_ADD_SIZE(tlsf, b) do { \ 92 tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ 93 if (tlsf->used_size > tlsf->max_size) { \ 94 tlsf->max_size = tlsf->used_size; \ 98 #define TLSF_REMOVE_SIZE(tlsf, b) do { \ 99 tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ 102 #define TLSF_ADD_SIZE(tlsf, b) do{}while(0) 103 #define TLSF_REMOVE_SIZE(tlsf, b) do{}while(0) 106 #if USE_MMAP || USE_SBRK 111 #include <sys/mman.h> 116 #if !defined(__GNUC__) 124 #define _DEBUG_TLSF_ (0) 133 #define BLOCK_ALIGN (sizeof(void *) * 2) 136 #define MAX_LOG2_SLI (5) 137 #define MAX_SLI (1 << MAX_LOG2_SLI) 139 #define FLI_OFFSET (6) 141 #define SMALL_BLOCK (128) 142 #define REAL_FLI (MAX_FLI - FLI_OFFSET) 143 #define MIN_BLOCK_SIZE (sizeof (free_ptr_t)) 144 #define BHDR_OVERHEAD (sizeof (bhdr_t) - MIN_BLOCK_SIZE) 145 #define TLSF_SIGNATURE (0x2A59FA59) 147 #define PTR_MASK (sizeof(void *) - 1) 148 #define BLOCK_SIZE (0xFFFFFFFF - PTR_MASK) 150 #define GET_NEXT_BLOCK(_addr, _r) ((bhdr_t *) ((char *) (_addr) + (_r))) 151 #define MEM_ALIGN ((BLOCK_ALIGN) - 1) 152 #define ROUNDUP_SIZE(_r) (((_r) + MEM_ALIGN) & ~MEM_ALIGN) 153 #define ROUNDDOWN_SIZE(_r) ((_r) & ~MEM_ALIGN) 154 #define ROUNDUP(_x, _v) ((((~(_x)) + 1) & ((_v)-1)) + (_x)) 156 #define BLOCK_STATE (0x1) 157 #define PREV_STATE (0x2) 160 #define FREE_BLOCK (0x1) 161 #define USED_BLOCK (0x0) 164 #define PREV_FREE (0x2) 165 #define PREV_USED (0x0) 168 #define DEFAULT_AREA_SIZE (1024*10) 171 #define PAGE_SIZE (getpagesize()) 176 # define PRINT_MSG(...) printf(__VA_ARGS__) 177 # define ERROR_MSG(...) fprintf(stderr, __VA_ARGS__) 179 # if !defined(PRINT_MSG) 180 # define PRINT_MSG(...) 182 # if !defined(ERROR_MSG) 183 # define ERROR_MSG(...) 187 #ifndef ATTRIBUTE_UNUSED 188 #if defined(__GNUC__) 189 #define ATTRIBUTE_UNUSED __attribute__ ((__unused__)) 191 #define ATTRIBUTE_UNUSED 226 u32_t tlsf_signature;
264 #if USE_SBRK || USE_MMAP 265 static __inline__ void *get_new_area(
size_t * size);
269 -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
272 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
275 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
278 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6,
281 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
284 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
287 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
290 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
297 unsigned int x = i & -i;
299 a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
300 return table[x >> a] + a;
305 unsigned int x = (
unsigned int) i;
307 a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
308 return table[x >> a] + a;
312 addr[nr >> 5] |= 1 << (nr & 0x1f);
316 addr[nr >> 5] &= ~(1 << (nr & 0x1f));
356 _b = _tlsf->
matrix[*_fl][*_sl];
361 _b = _tlsf->
matrix[*_fl][*_sl];
368 #define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do { \ 369 _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next; \ 370 if (_tlsf -> matrix[_fl][_sl]) \ 371 _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL; \ 373 clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ 374 if (!_tlsf -> sl_bitmap [_fl]) \ 375 clear_bit (_fl, &_tlsf -> fl_bitmap); \ 377 _b -> ptr.free_ptr.prev = NULL; \ 378 _b -> ptr.free_ptr.next = NULL; \ 382 #define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do { \ 383 if (_b -> ptr.free_ptr.next) \ 384 _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \ 385 if (_b -> ptr.free_ptr.prev) \ 386 _b -> ptr.free_ptr.prev -> ptr.free_ptr.next = _b -> ptr.free_ptr.next; \ 387 if (_tlsf -> matrix [_fl][_sl] == _b) { \ 388 _tlsf -> matrix [_fl][_sl] = _b -> ptr.free_ptr.next; \ 389 if (!_tlsf -> matrix [_fl][_sl]) { \ 390 clear_bit (_sl, &_tlsf -> sl_bitmap[_fl]); \ 391 if (!_tlsf -> sl_bitmap [_fl]) \ 392 clear_bit (_fl, &_tlsf -> fl_bitmap); \ 395 _b -> ptr.free_ptr.prev = NULL; \ 396 _b -> ptr.free_ptr.next = NULL; \ 399 #define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do { \ 400 _b -> ptr.free_ptr.prev = NULL; \ 401 _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \ 402 if (_tlsf -> matrix [_fl][_sl]) \ 403 _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b; \ 404 _tlsf -> matrix [_fl][_sl] = _b; \ 405 set_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ 406 set_bit (_fl, &_tlsf -> fl_bitmap); \ 409 #if USE_SBRK || USE_MMAP 410 static __inline__ void *get_new_area(
size_t * size) {
414 area = (
void *) sbrk(0);
415 if (((
void *) sbrk(*size)) != ((
void *) -1))
419 #ifndef MAP_ANONYMOUS 421 # define MAP_ANONYMOUS MAP_ANON 428 mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED)
431 return ((
void *) ~0);
461 static char *
mp = NULL;
470 ERROR_MSG(
"rtl_init_memory_pool (): memory_pool invalid\n");
474 if (((
unsigned long) mem_pool &
PTR_MASK)) {
475 ERROR_MSG(
"rtl_init_memory_pool (): mem_pool must be aligned to a word\n");
478 tlsf = (
tlsf_t *) mem_pool;
481 mp = (
char *) mem_pool;
486 mp = (
char *) mem_pool;
489 memset(mem_pool, 0,
sizeof(
tlsf_t));
504 tlsf->max_size = tlsf->used_size;
515 bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
519 savesz = tlsf->used_size;
522 memset(area, 0, area_size);
539 if ((
unsigned long) ib1 == (
unsigned long) lb0 +
BHDR_OVERHEAD) {
561 if ((
unsigned long) lb1->
ptr.
buffer == (
unsigned long) ib0) {
593 tlsf->used_size=savesz;
603 return ((
tlsf_t *) mem_pool)->used_size;
613 return ((
tlsf_t *) mem_pool)->max_size;
636 #if USE_MMAP || USE_SBRK 643 area = get_new_area(&area_size);
644 if (area == ((
void *) ~0))
676 #if USE_MMAP || USE_SBRK 721 #if USE_MMAP || USE_SBRK 728 area = get_new_area(&area_size);
729 if (area == ((
void *) ~0))
747 if (tmp_size >=
sizeof(
bhdr_t)) {
778 #ifdef CHECK_DOUBLE_FREE 780 ERROR_MSG(
"rtl_free_ex(): double free %p\n", ptr);
818 bhdr_t *b, *tmp_b, *next_b;
827 }
else if (!new_size) {
834 #ifdef CHECK_DOUBLE_FREE 836 ERROR_MSG(
"rtl_realloc_ex(): invalid pointer %p\n", ptr);
844 if (new_size <= tmp_size) {
854 tmp_size -= new_size;
855 if (tmp_size >=
sizeof(
bhdr_t)) {
878 if (tmp_size >=
sizeof(
bhdr_t)) {
899 memcpy(ptr_aux, ptr, cpsize);
911 if (nelem <= 0 || elem_size <= 0)
916 memset(ptr, 0, nelem * elem_size);
931 extern void dump_memory_region(
unsigned char *mem_ptr,
unsigned int size);
932 extern void print_block(
bhdr_t * b);
933 extern void print_tlsf(
tlsf_t * tlsf);
934 void print_all_blocks(
tlsf_t * tlsf);
936 void dump_memory_region(
unsigned char *mem_ptr,
unsigned int size) {
938 unsigned long begin = (
unsigned long) mem_ptr;
939 unsigned long end = (
unsigned long) mem_ptr + size;
949 PRINT_MSG(
"\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
954 while (begin < end) {
955 if (((
unsigned char *) begin)[0] == 0)
958 PRINT_MSG(
"%02x", ((
unsigned char *) begin)[0]);
959 if (((
unsigned char *) begin)[1] == 0)
962 PRINT_MSG(
"%02x ", ((
unsigned char *) begin)[1]);
974 void print_block(
bhdr_t * b) {
992 void print_tlsf(
tlsf_t * tlsf) {
1003 for (j = 0; j <
MAX_SLI; j++) {
1004 next = tlsf->
matrix[i][j];
1015 void print_all_blocks(
tlsf_t * tlsf) {
1018 PRINT_MSG(
"\nTLSF at %p\nALL BLOCKS\n\n", tlsf);
bhdr_t * matrix[REAL_FLI][MAX_SLI]
struct bhdr_struct * next
#define INSERT_BLOCK(_b, _tlsf, _fl, _sl)
struct TLSF_struct tlsf_t
struct area_info_struct area_info_t
static __inline__ int ms_bit(int x)
void * rtl_tlsf_malloc(size_t size)
struct free_ptr_struct free_ptr_t
void * rtl_malloc_ex(size_t size, void *mem_pool)
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 rtl_get_used_size(void *mem_pool ATTRIBUTE_UNUSED)
#define GET_NEXT_BLOCK(_addr, _r)
#define TLSF_ACQUIRE_LOCK(_unused_)
#define TLSF_RELEASE_LOCK(_unused_)
static __inline__ bhdr_t * FIND_SUITABLE_BLOCK(tlsf_t *_tlsf, int *_fl, int *_sl)
size_t rtl_add_new_area(void *area, size_t area_size, void *mem_pool)
static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
void rtl_free_ex(void *ptr, void *mem_pool)
size_t rtl_init_memory_pool(size_t mem_pool_size, void *mem_pool)
size_t rtl_get_max_size(void *mem_pool ATTRIBUTE_UNUSED)
#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl)
struct area_info_struct * next
static __inline__ void set_bit(int nr, u32_t *addr)
void * rtl_realloc_ex(void *ptr, size_t new_size, void *mem_pool)
u32_t sl_bitmap[REAL_FLI]
#define DEFAULT_AREA_SIZE
#define TLSF_DESTROY_LOCK(_unused_)
#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl)
#define TLSF_CREATE_LOCK(_unused_)
struct free_ptr_struct free_ptr
void * rtl_tlsf_calloc(size_t nelem, size_t elem_size)
static __inline__ bhdr_t * process_area(void *area, size_t size)
static __inline__ void clear_bit(int nr, u32_t *addr)
#define TLSF_REMOVE_SIZE(tlsf, b)
void * rtl_tlsf_realloc(void *ptr, size_t size)
struct bhdr_struct bhdr_t
#define TLSF_ADD_SIZE(tlsf, b)
struct bhdr_struct * prev_hdr
void rtl_tlsf_free(void *ptr)
struct bhdr_struct * prev
#define ROUNDDOWN_SIZE(_r)
void rtl_destroy_memory_pool(void *mem_pool)
void * rtl_calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)