tlsf.c
Go to the documentation of this file.
1 /*
2  * Two Levels Segregate Fit memory allocator (TLSF)
3  * Version 2.4.6
4  *
5  * Written by Miguel Masmano Tello <mimastel@doctor.upv.es>
6  *
7  * Thanks to Ismael Ripoll for his suggestions and reviews
8  *
9  * Copyright (C) 2008, 2007, 2006, 2005, 2004
10  *
11  * This code is released using a dual license strategy: GPL/LGPL
12  * You can choose the licence that better fits your requirements.
13  *
14  * Released under the terms of the GNU General Public License Version 2.0
15  * Released under the terms of the GNU Lesser General Public License Version 2.1
16  *
17  */
18 
19 /*
20  * Code contributions:
21  *
22  * (Jul 28 2007) Herman ten Brugge <hermantenbrugge@home.nl>:
23  *
24  * - Add 64 bit support. It now runs on x86_64 and solaris64.
25  * - I also tested this on vxworks/32and solaris/32 and i386/32 processors.
26  * - Remove assembly code. I could not measure any performance difference
27  * on my core2 processor. This also makes the code more portable.
28  * - Moved defines/typedefs from tlsf.h to tlsf.c
29  * - Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to
30  * (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact
31  * that the minumum size is still sizeof
32  * (bhdr_t).
33  * - Changed all C++ comment style to C style. (// -> /.* ... *./)
34  * - Used ls_bit instead of ffs and ms_bit instead of fls. I did this to
35  * avoid confusion with the standard ffs function which returns
36  * different values.
37  * - Created set_bit/clear_bit fuctions because they are not present
38  * on x86_64.
39  * - Added locking support + extra file target.h to show how to use it.
40  * - Added get_used_size function (REMOVED in 2.4)
41  * - Added rtl_realloc and rtl_calloc function
42  * - Implemented realloc clever support.
43  * - Added some test code in the example directory.
44  * - Bug fixed (discovered by the rockbox project: www.rockbox.org).
45  *
46  * (Oct 23 2006) Adam Scislowicz:
47  *
48  * - Support for ARMv5 implemented
49  *
50  */
51 
52 /*#define USE_SBRK (0) */
53 /*#define USE_MMAP (0) */
54 
55 
56 // needed for sbrk() and MAP_ANON in 10.6 (at least)
57 #ifdef __APPLE__
58 #define _DARWIN_C_SOURCE
59 #else
60 #include "../fosi.h"
61 #endif
62 
63 #ifndef USE_PRINTF
64 #define USE_PRINTF (1)
65 #endif
66 
67 #include <string.h>
68 
69 #ifndef TLSF_USE_LOCKS
70 #define TLSF_USE_LOCKS (1)
71 #endif
72 
73 #ifndef TLSF_STATISTIC
74 #define TLSF_STATISTIC (0)
75 #endif
76 
77 #ifndef USE_MMAP
78 #define USE_MMAP (0)
79 #endif
80 
81 #ifndef USE_SBRK
82 #define USE_SBRK (0)
83 #endif
84 
85 
86 #if TLSF_USE_LOCKS
87 #include "target.h"
88 #else
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)
93 #endif
94 
95 #if TLSF_STATISTIC
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; \
100  } while(0)
101 
102 #define TLSF_REMOVE_SIZE(tlsf, b) do { \
103  tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \
104  } while(0)
105 #else
106 #define TLSF_ADD_SIZE(tlsf, b) do{}while(0)
107 #define TLSF_REMOVE_SIZE(tlsf, b) do{}while(0)
108 #endif
109 
110 #if USE_MMAP || USE_SBRK
111 #include <unistd.h>
112 #endif
113 
114 #if USE_MMAP
115 #include <sys/mman.h>
116 #endif
117 
118 #define ORO_MEMORY_POOL
119 #include "tlsf.h"
120 
121 #if !defined(__GNUC__)
122 #ifndef __inline__
123 #define __inline__
124 #endif
125 #endif
126 
127 /* The debug functions only can be used when _DEBUG_TLSF_ is set. */
128 #ifndef _DEBUG_TLSF_
129 #define _DEBUG_TLSF_ (0)
130 #endif
131 
132 /*************************************************************************/
133 /* Definition of the structures used by TLSF */
134 
135 
136 /* Some IMPORTANT TLSF parameters */
137 /* Unlike the preview TLSF versions, now they are statics */
138 #define BLOCK_ALIGN (sizeof(void *) * 2)
139 
140 #define MAX_FLI (30)
141 #define MAX_LOG2_SLI (5)
142 #define MAX_SLI (1 << MAX_LOG2_SLI) /* MAX_SLI = 2^MAX_LOG2_SLI */
143 
144 #define FLI_OFFSET (6) /* tlsf structure just will manage blocks bigger */
145 /* than 128 bytes */
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)
151 
152 #define PTR_MASK (sizeof(void *) - 1)
153 #define BLOCK_SIZE ((intptr_t)~PTR_MASK)
154 
155 
156 /* Dereferencing type-punned pointers will break strict aliasing.*/
157 #ifdef __GNUC__
158 /* GCC guarantees that casting through a union is valid. */
159 #define TYPE_PUN(dsttype, srctype, x) \
160  (((union {srctype *a; dsttype *b;})(x)).b)
161 #else
162 #define TYPE_PUN(dsttype, srctype, x) ( (dsttype*)(x) )
163 #endif /* __GNUC__ */
164 
165 #define GET_NEXT_BLOCK(_addr, _r) TYPE_PUN(bhdr_t, char, (char *) (_addr) + (_r))
166 
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))
171 
172 #define BLOCK_STATE (0x1)
173 #define PREV_STATE (0x2)
174 #define STATE_MASK (BLOCK_STATE | PREV_STATE)
175 
176 /* bit 0 of the block size */
177 #define FREE_BLOCK (0x1)
178 #define USED_BLOCK (0x0)
179 
180 /* bit 1 of the block size */
181 #define PREV_FREE (0x2)
182 #define PREV_USED (0x0)
183 
184 
185 #define DEFAULT_AREA_SIZE (1024*10)
186 
187 #if USE_MMAP
188 #define TLSF_PAGE_SIZE (getpagesize())
189 #endif
190 
191 #ifdef USE_PRINTF
192 #include <stdio.h>
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)
196 #else
197 # if !defined(PRINT_MSG)
198 # define PRINT_MSG(fmt, args...)
199 # endif
200 # if !defined(ERROR_MSG)
201 # define ERROR_MSG(fmt, args...)
202 # endif
203 #endif
204 
205 typedef unsigned int u32_t; /* NOTE: Make sure that this type is 4 bytes long on your computer */
206 typedef unsigned char u8_t; /* NOTE: Make sure that this type is 1 byte on your computer */
207 
208 typedef struct free_ptr_struct {
209  struct bhdr_struct *prev;
210  struct bhdr_struct *next;
211 } free_ptr_t;
212 
213 typedef struct bhdr_struct {
214  /* This pointer is just valid if the first bit of size is set */
216  /* The size is stored in bytes */
217  size_t size; /* bit 0 indicates whether the block is used and */
218  /* bit 1 allows to know whether the previous block is free */
219  union {
220  struct free_ptr_struct free_ptr;
221  u8_t buffer[1]; /*sizeof(struct free_ptr_struct)]; */
222  } ptr;
223 } bhdr_t;
224 
225 /* This structure is embedded at the beginning of each area, giving us
226  * enough information to cope with a set of areas */
227 
228 typedef struct area_info_struct {
231 } area_info_t;
232 
233 typedef struct TLSF_struct {
234  /* the TLSF's structure signature */
236 
237 #if TLSF_USE_LOCKS
239 #endif
240 
241 #if TLSF_STATISTIC
242  /* These can not be calculated outside tlsf because we
243  * do not know the sizes when freeing/reallocing memory. */
244  size_t pool_size; // total pool area
245  size_t overhead_size; // TLSF overhead
246  size_t used_size; // currently used (includes overhead)
247  size_t max_size; // max used (includes overhead)
248 #endif
249 
250  /* A linked list holding all the existing areas */
252 
253  /* the first-level bitmap */
254  /* This array should have a size of REAL_FLI bits */
256 
257  /* the second-level bitmap */
258  u32_t sl_bitmap[REAL_FLI];
259 
261 } tlsf_t;
262 
263 
264 /******************************************************************/
265 /************** Helping functions **************************/
266 /******************************************************************/
267 void abort(void);
268 
269 static __inline__ void corrupt(const char *s);
270 static __inline__ void set_bit(int nr, u32_t * addr);
271 static __inline__ void clear_bit(int nr, u32_t * addr);
272 static __inline__ int ls_bit(int x);
273 static __inline__ int ms_bit(int x);
274 static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl);
275 static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl);
276 static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl);
277 static __inline__ bhdr_t *process_area(void *area, size_t size);
278 #if USE_SBRK || USE_MMAP
279 static __inline__ void *get_new_area(size_t * size);
280 #endif
281 
282 
283 static __inline__ bhdr_t *encode_prev_block( bhdr_t *prev, size_t size ) {
284  return (bhdr_t*) ( ((intptr_t)prev | STATE_MASK) & ~(size & STATE_MASK) );
285 }
286 
287 static const int table[] = {
288  -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4,
289  4, 4,
290  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,
292  5,
293  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,
295  6,
296  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,
298  6,
299  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,
301  7,
302  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,
304  7,
305  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,
307  7,
308  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,
310  7,
311  7, 7, 7, 7, 7, 7, 7
312 };
313 
314 static __inline__ int ls_bit(int i)
315 {
316  unsigned int a;
317  unsigned int x = i & -i;
318 
319  a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
320  return table[x >> a] + a;
321 }
322 
323 static __inline__ int ms_bit(int i)
324 {
325  unsigned int a;
326  unsigned int x = (unsigned int) i;
327 
328  a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ? 16 : 24);
329  return table[x >> a] + a;
330 }
331 
332 static __inline__ void set_bit(int nr, u32_t * addr)
333 {
334  addr[nr >> 5] |= 1 << (nr & 0x1f);
335 }
336 
337 static __inline__ void clear_bit(int nr, u32_t * addr)
338 {
339  addr[nr >> 5] &= ~(1 << (nr & 0x1f));
340 }
341 
342 static __inline__ void MAPPING_SEARCH(size_t * _r, int *_fl, int *_sl)
343 {
344  int _t;
345 
346  if (*_r < SMALL_BLOCK) {
347  *_fl = 0;
348  *_sl = *_r / (SMALL_BLOCK / MAX_SLI);
349  } else {
350  _t = (1 << (ms_bit(*_r) - MAX_LOG2_SLI)) - 1;
351  *_r = *_r + _t;
352  *_fl = ms_bit(*_r);
353  *_sl = (*_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
354  *_fl -= FLI_OFFSET;
355  /*if ((*_fl -= FLI_OFFSET) < 0) // FL wil be always >0!
356  *_fl = *_sl = 0;
357  */
358  *_r &= ~_t;
359  }
360 }
361 
362 static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
363 {
364  if (_r < SMALL_BLOCK) {
365  *_fl = 0;
366  *_sl = _r / (SMALL_BLOCK / MAX_SLI);
367  } else {
368  *_fl = ms_bit(_r);
369  *_sl = (_r >> (*_fl - MAX_LOG2_SLI)) - MAX_SLI;
370  *_fl -= FLI_OFFSET;
371  }
372 }
373 
374 
375 static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl)
376 {
377  u32_t _tmp = _tlsf->sl_bitmap[*_fl] & (~0 << *_sl);
378  bhdr_t *_b = NULL;
379 
380  if (_tmp) {
381  *_sl = ls_bit(_tmp);
382  _b = _tlsf->matrix[*_fl][*_sl];
383  } else {
384  *_fl = ls_bit(_tlsf->fl_bitmap & (~0 << (*_fl + 1)));
385  if (*_fl > 0) { /* likely */
386  *_sl = ls_bit(_tlsf->sl_bitmap[*_fl]);
387  _b = _tlsf->matrix[*_fl][*_sl];
388  }
389  }
390  return _b;
391 }
392 
393 static __inline__ void corrupt(const char *msg) {
394 #ifdef USE_PRINTF
395  fputs("* Heap corruption detected: *\n", stderr);
396  fputs(msg, stderr);
397 #endif
398  abort();
399 }
400 
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; \
405  else { \
406  clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \
407  if (!_tlsf -> sl_bitmap [_fl]) \
408  clear_bit (_fl, &_tlsf -> fl_bitmap); \
409  } \
410  _b -> ptr.free_ptr.prev = NULL; \
411  _b -> ptr.free_ptr.next = NULL; \
412  }while(0)
413 
414 
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); \
426  } \
427  } \
428  _b -> ptr.free_ptr.prev = NULL; \
429  _b -> ptr.free_ptr.next = NULL; \
430  } while(0)
431 
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); \
440  } while(0)
441 
442 #if USE_SBRK || USE_MMAP
443 static __inline__ void *get_new_area(size_t * size)
444 {
445  void *area;
446 
447 #if USE_SBRK
448  area = (void *)sbrk(0);
449  if (((void *)sbrk(*size)) != ((void *) -1))
450  return area;
451 #endif
452 
453 #ifndef MAP_ANONYMOUS
454 /* https://dev.openwrt.org/ticket/322 */
455 # define MAP_ANONYMOUS MAP_ANON
456 #endif
457 
458 
459 #if USE_MMAP
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)
462  return area;
463 #endif
464  return ((void *) ~0);
465 }
466 #endif
467 
468 static __inline__ bhdr_t *process_area(void *area, size_t size)
469 {
470  bhdr_t *b, *lb, *ib;
471  area_info_t *ai;
472 
473  ib = (bhdr_t *) area;
474  ib->size =
475  (sizeof(area_info_t) <
477  ib->prev_hdr = encode_prev_block( NULL, ib->size );
478  b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
479  b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED;
480  b->prev_hdr = encode_prev_block( NULL, b->size );
481  b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0;
482  lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
483  lb->size = 0 | USED_BLOCK | PREV_FREE;
484  lb->prev_hdr = encode_prev_block( b, lb->size );
485  ai = TYPE_PUN(area_info_t, u8_t, ib->ptr.buffer);
486  ai->next = 0;
487  ai->end = lb;
488  return ib;
489 }
490 
491 /******************************************************************/
492 /******************** Begin of the allocator code *****************/
493 /******************************************************************/
494 
495 static char *mp = NULL; /* Default memory pool. */
496 
497 /******************************************************************/
498 size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
499 {
500 /******************************************************************/
501  tlsf_t *tlsf;
502  bhdr_t *b, *ib;
503 
504  if (!mem_pool || !mem_pool_size || mem_pool_size < sizeof(tlsf_t) + BHDR_OVERHEAD * 8) {
505  ERROR_MSG("init_memory_pool (): memory_pool invalid\n");
506  return -1;
507  }
508 
509  if (((unsigned long) mem_pool & PTR_MASK)) {
510  ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n");
511  return -1;
512  }
513  tlsf = (tlsf_t *) mem_pool;
514  /* Check if already initialised */
515  if (tlsf->tlsf_signature == TLSF_SIGNATURE) {
516  b = GET_NEXT_BLOCK(mp, ROUNDUP_SIZE(sizeof(tlsf_t)));
517  return b->size & BLOCK_SIZE;
518  }
519 
520  if(mp == 0)
521  mp = mem_pool;
522 
523  /* Zeroing the memory pool */
524  memset(mem_pool, 0, sizeof(tlsf_t));
525 
527 
528  TLSF_CREATE_LOCK(&tlsf->lock);
529 
531  (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)));
532  b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
533  free_ex(b->ptr.buffer, tlsf);
534  tlsf->area_head = TYPE_PUN(area_info_t, u8_t, ib->ptr.buffer);
535 
536 #if TLSF_STATISTIC
537  tlsf->pool_size = mem_pool_size;
538  tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE);
539  tlsf->overhead_size = tlsf->used_size;
540  tlsf->max_size = tlsf->used_size;
541 #endif
542 
543  return (b->size & BLOCK_SIZE);
544 }
545 
546 /******************************************************************/
547 size_t add_new_area(void *area, size_t area_size, void *mem_pool)
548 {
549 /******************************************************************/
550  tlsf_t *tlsf = (tlsf_t *) mem_pool;
551  area_info_t *ptr, *ptr_prev, *ai;
552  bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
553 
554  memset(area, 0, area_size);
555  ptr = tlsf->area_head;
556  ptr_prev = 0;
557 
558  ib0 = process_area(area, area_size);
559  b0 = GET_NEXT_BLOCK(ib0->ptr.buffer, ib0->size & BLOCK_SIZE);
560  lb0 = GET_NEXT_BLOCK(b0->ptr.buffer, b0->size & BLOCK_SIZE);
561 
562  /* Before inserting the new area, we have to merge this area with the
563  already existing ones */
564 
565  while (ptr) {
566  ib1 = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
567  b1 = GET_NEXT_BLOCK(ib1->ptr.buffer, ib1->size & BLOCK_SIZE);
568  lb1 = ptr->end;
569 
570  /* Merging the new area with the next physically contigous one */
571  if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) {
572  if (tlsf->area_head == ptr) {
573  tlsf->area_head = ptr->next;
574  ptr = ptr->next;
575  } else {
576  ptr_prev->next = ptr->next;
577  ptr = ptr->next;
578  }
579 
580  b0->size =
581  ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
582  (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED;
583 
584  b1->prev_hdr = encode_prev_block( b0, b0->size );
585  lb0 = lb1;
586 
587  continue;
588  }
589 
590  /* Merging the new area with the previous physically contigous
591  one */
592  if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) {
593  if (tlsf->area_head == ptr) {
594  tlsf->area_head = ptr->next;
595  ptr = ptr->next;
596  } else {
597  ptr_prev->next = ptr->next;
598  ptr = ptr->next;
599  }
600 
601  lb1->size =
602  ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
603  (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE);
604  next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE);
605  next_b->prev_hdr = encode_prev_block( lb1, next_b->size );
606  b0 = lb1;
607  ib0 = ib1;
608 
609  continue;
610  }
611  ptr_prev = ptr;
612  ptr = ptr->next;
613  }
614 
615  /* Inserting the area in the list of linked areas */
616  ai = TYPE_PUN(area_info_t, u8_t, ib0->ptr.buffer);
617  ai->next = tlsf->area_head;
618  ai->end = lb0;
619  tlsf->area_head = ai;
620  free_ex(b0->ptr.buffer, mem_pool);
621  return (b0->size & BLOCK_SIZE);
622 }
623 
624 
625 /******************************************************************/
626 size_t get_pool_size(void *mem_pool)
627 {
628 /******************************************************************/
629 #if TLSF_STATISTIC
630  return ((tlsf_t *) mem_pool)->pool_size;
631 #else
632  return 0;
633 #endif
634 }
635 
636 /******************************************************************/
637 // use default memory pool
638 size_t get_pool_size_mp(void)
639 {
640 /******************************************************************/
641 #if TLSF_STATISTIC
642  return (mp ? ((tlsf_t *) mp)->pool_size : 0);
643 #else
644  return 0;
645 #endif
646 }
647 
648 /******************************************************************/
649 size_t get_overhead_size(void *mem_pool)
650 {
651 /******************************************************************/
652 #if TLSF_STATISTIC
653  return ((tlsf_t *) mem_pool)->overhead_size;
654 #else
655  return 0;
656 #endif
657 }
658 
659 /******************************************************************/
660 // use default memory pool
662 {
663 /******************************************************************/
664 #if TLSF_STATISTIC
665  return (mp ? ((tlsf_t *) mp)->overhead_size : 0);
666 #else
667  return 0;
668 #endif
669 }
670 
671 /******************************************************************/
672 size_t get_used_size(void *mem_pool)
673 {
674 /******************************************************************/
675 #if TLSF_STATISTIC
676  return ((tlsf_t *) mem_pool)->used_size;
677 #else
678  return 0;
679 #endif
680 }
681 
682 /******************************************************************/
683 // use default memory pool
684 size_t get_used_size_mp(void)
685 {
686 /******************************************************************/
687 #if TLSF_STATISTIC
688  return (mp ? ((tlsf_t *) mp)->used_size : 0);
689 #else
690  return 0;
691 #endif
692 }
693 
694 /******************************************************************/
695 size_t get_max_size(void *mem_pool)
696 {
697 /******************************************************************/
698 #if TLSF_STATISTIC
699  return ((tlsf_t *) mem_pool)->max_size;
700 #else
701  return 0;
702 #endif
703 }
704 
705 /******************************************************************/
706 // use default memory pool
707 size_t get_max_size_mp(void)
708 {
709 /******************************************************************/
710 #if TLSF_STATISTIC
711  return (mp ? ((tlsf_t *) mp)->max_size : 0);
712 #else
713  return 0;
714 #endif
715 }
716 
717 /******************************************************************/
718 void destroy_memory_pool(void *mem_pool)
719 {
720 /******************************************************************/
721  if((void*)mp == (void*)mem_pool){
722  mp = 0;
723  }
724 
725  tlsf_t *tlsf = (tlsf_t *) mem_pool;
726  tlsf->tlsf_signature = 0;
727 
728  TLSF_DESTROY_LOCK(&tlsf->lock);
729 
730 }
731 
732 
733 /******************************************************************/
734 void *tlsf_malloc(size_t size)
735 {
736 /******************************************************************/
737  void *ret;
738 
739 #if USE_MMAP || USE_SBRK
740  if (!mp) {
741  size_t area_size;
742  void *area;
743 
744  area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */
745  area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
746  area = get_new_area(&area_size);
747  if (area == ((void *) ~0))
748  return NULL; /* Not enough system memory */
749  init_memory_pool(area_size, area);
750  }
751 #endif
752 
753  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
754 
755  ret = malloc_ex(size, mp);
756 
757  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
758 
759  return ret;
760 }
761 
762 /******************************************************************/
763 void tlsf_free(void *ptr)
764 {
765 /******************************************************************/
766 
767  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
768 
769  free_ex(ptr, mp);
770 
771  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
772 
773 }
774 
775 /******************************************************************/
776 void *tlsf_realloc(void *ptr, size_t size)
777 {
778 /******************************************************************/
779  void *ret;
780 
781 #if USE_MMAP || USE_SBRK
782  if (!mp) {
783  return tlsf_malloc(size);
784  }
785 #endif
786 
787  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
788 
789  ret = realloc_ex(ptr, size, mp);
790 
791  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
792 
793  return ret;
794 }
795 
796 /******************************************************************/
797 void *tlsf_calloc(size_t nelem, size_t elem_size)
798 {
799 /******************************************************************/
800  void *ret;
801 
802  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
803 
804  ret = calloc_ex(nelem, elem_size, mp);
805 
806  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
807 
808  return ret;
809 }
810 
811 /******************************************************************/
812 void *malloc_ex(size_t size, void *mem_pool)
813 {
814 /******************************************************************/
815  tlsf_t *tlsf = (tlsf_t *) mem_pool;
816  bhdr_t *b, *b2, *next_b;
817  int fl, sl;
818  size_t tmp_size;
819 
820  size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
821 
822  /* Rounding up the requested size and calculating fl and sl */
823  MAPPING_SEARCH(&size, &fl, &sl);
824 
825  /* Searching a free block, recall that this function changes the values of fl and sl,
826  so they are not longer valid when the function fails */
827  b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
828 #if USE_MMAP || USE_SBRK
829  if (!b) {
830  size_t area_size;
831  void *area;
832  /* Growing the pool size when needed */
833  area_size = size + BHDR_OVERHEAD * 8; /* size plus enough room for the requered headers. */
834  area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
835  area = get_new_area(&area_size); /* Call sbrk or mmap */
836  if (area == ((void *) ~0))
837  return NULL; /* Not enough system memory */
838  add_new_area(area, area_size, mem_pool);
839  /* Rounding up the requested size and calculating fl and sl */
840  MAPPING_SEARCH(&size, &fl, &sl);
841  /* Searching a free block */
842  b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
843  }
844 #endif
845  if (!b)
846  return NULL; /* Not found */
847 
848  EXTRACT_BLOCK_HDR(b, tlsf, fl, sl);
849 
850  /*-- found: */
851  next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
852  /* Should the block be split? */
853  tmp_size = (b->size & BLOCK_SIZE) - size;
854  if (tmp_size >= sizeof(bhdr_t)) {
855  tmp_size -= BHDR_OVERHEAD;
856  b2 = GET_NEXT_BLOCK(b->ptr.buffer, size);
857  b2->size = tmp_size | FREE_BLOCK | PREV_USED;
858  b2->prev_hdr = encode_prev_block( b2->prev_hdr, b2->size );
859  next_b->prev_hdr = encode_prev_block(b2, next_b->size);
860  MAPPING_INSERT(tmp_size, &fl, &sl);
861  INSERT_BLOCK(b2, tlsf, fl, sl);
862 
863  b->size = size | (b->size & PREV_STATE);
864  } else {
865  next_b->size &= (~PREV_FREE);
866  next_b->prev_hdr = encode_prev_block( next_b->prev_hdr, next_b->size );
867  b->size &= (~FREE_BLOCK); /* Now it's used */
868  }
869  b->prev_hdr = encode_prev_block( b->prev_hdr, b->size );
870 
871  TLSF_ADD_SIZE(tlsf, b);
872 
873  if( (b->size & BLOCK_STATE) != (~(intptr_t)b->prev_hdr & BLOCK_STATE) )
874  corrupt("malloc_ex(): Mismatched flags after allocation\n");
875 
876  return (void *) b->ptr.buffer;
877 }
878 
879 /******************************************************************/
880 void free_ex(void *ptr, void *mem_pool)
881 {
882 /******************************************************************/
883  tlsf_t *tlsf = (tlsf_t *) mem_pool;
884  bhdr_t *b, *tmp_b;
885  int fl = 0, sl = 0;
886 
887  if (!ptr) {
888  return;
889  }
890  b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
891 
892  if( (b->size & BLOCK_STATE) != USED_BLOCK )
893  corrupt( "free_ex(): Freeing unused block\n" );
894  if( (b->size & BLOCK_STATE) != (~(intptr_t)b->prev_hdr & BLOCK_STATE) )
895  corrupt("free_ex(): Mismatched flags\n");
896 
897  b->size |= FREE_BLOCK;
898 
899  TLSF_REMOVE_SIZE(tlsf, b);
900 
901  b->ptr.free_ptr.prev = NULL;
902  b->ptr.free_ptr.next = NULL;
903  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
904  if (tmp_b->size & FREE_BLOCK) {
905  /* Coalesce next block */
906  MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
907  EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
908  b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
909  }
910  if (b->size & PREV_FREE) {
911  /* Coalesce previous block */
912  tmp_b = (bhdr_t*) ( (intptr_t)b->prev_hdr & BLOCK_SIZE );
913  MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
914  EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
915  tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
916  b = tmp_b;
917  }
918  MAPPING_INSERT(b->size & BLOCK_SIZE, &fl, &sl);
919  INSERT_BLOCK(b, tlsf, fl, sl);
920 
921  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
922  /* if tmp_b is free, it should have been coalesced */
923  if( (tmp_b->size & BLOCK_STATE) == FREE_BLOCK )
924  corrupt( "free_ex(): uncoalesced block\n");
925  tmp_b->size |= PREV_FREE;
926  tmp_b->prev_hdr = encode_prev_block(b, tmp_b->size);
927 }
928 
929 /******************************************************************/
930 void *realloc_ex(void *ptr, size_t new_size, void *mem_pool)
931 {
932 /******************************************************************/
933  tlsf_t *tlsf = (tlsf_t *) mem_pool;
934  void *ptr_aux;
935  unsigned int cpsize;
936  bhdr_t *b, *tmp_b, *next_b;
937  int fl, sl;
938  size_t tmp_size;
939 
940  if (!ptr) {
941  if (new_size)
942  return (void *) malloc_ex(new_size, mem_pool);
943  if (!new_size)
944  return NULL;
945  } else if (!new_size) {
946  free_ex(ptr, mem_pool);
947  return NULL;
948  }
949 
950  b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
951  next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
952  new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size);
953  tmp_size = (b->size & BLOCK_SIZE);
954  if (new_size <= tmp_size) {
955  /* shrink allocated portion */
956  TLSF_REMOVE_SIZE(tlsf, b);
957  if (next_b->size & FREE_BLOCK) {
958  /* coalesce next block (free) */
959  MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
960  EXTRACT_BLOCK(next_b, tlsf, fl, sl);
961  tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
962  next_b = GET_NEXT_BLOCK(next_b->ptr.buffer, next_b->size & BLOCK_SIZE);
963  /* We allways reenter this free block because tmp_size will
964  be greater then sizeof (bhdr_t) */
965  }
966  tmp_size -= new_size;
967  if (tmp_size >= sizeof(bhdr_t)) {
968  /* add tail as free block */
969  tmp_size -= BHDR_OVERHEAD;
970  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
971  tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
972  tmp_b->prev_hdr = encode_prev_block( NULL, tmp_b->size );
973  next_b->size |= PREV_FREE;
974  next_b->prev_hdr = encode_prev_block( tmp_b, next_b->size );
975  MAPPING_INSERT(tmp_size, &fl, &sl);
976  INSERT_BLOCK(tmp_b, tlsf, fl, sl);
977  b->size = new_size | (b->size & PREV_STATE);
978  }
979  TLSF_ADD_SIZE(tlsf, b);
980  return (void *) b->ptr.buffer;
981  }
982  if ((next_b->size & FREE_BLOCK)) {
983  if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) {
984  /* allocate out of next block */
985  TLSF_REMOVE_SIZE(tlsf, b);
986  MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
987  EXTRACT_BLOCK(next_b, tlsf, fl, sl);
988  b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
989  next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
990  next_b->size &= ~PREV_FREE;
991  next_b->prev_hdr = encode_prev_block( b, next_b->size );
992  tmp_size = (b->size & BLOCK_SIZE) - new_size;
993  if (tmp_size >= sizeof(bhdr_t)) {
994  tmp_size -= BHDR_OVERHEAD;
995  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
996  tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
997  next_b->size |= PREV_FREE;
998  next_b->prev_hdr = encode_prev_block(tmp_b, next_b->size);
999  MAPPING_INSERT(tmp_size, &fl, &sl);
1000  INSERT_BLOCK(tmp_b, tlsf, fl, sl);
1001  b->size = new_size | (b->size & PREV_STATE);
1002  }
1003  TLSF_ADD_SIZE(tlsf, b);
1004  return (void *) b->ptr.buffer;
1005  }
1006  }
1007 
1008  if (!(ptr_aux = malloc_ex(new_size, mem_pool))){
1009  return NULL;
1010  }
1011 
1012  cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE);
1013 
1014  memcpy(ptr_aux, ptr, cpsize);
1015 
1016  free_ex(ptr, mem_pool);
1017  return ptr_aux;
1018 }
1019 
1020 
1021 /******************************************************************/
1022 void *calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
1023 {
1024 /******************************************************************/
1025  void *ptr;
1026 
1027  if (nelem <= 0 || elem_size <= 0)
1028  return NULL;
1029 
1030  if (!(ptr = malloc_ex(nelem * elem_size, mem_pool)))
1031  return NULL;
1032  memset(ptr, 0, nelem * elem_size);
1033 
1034  return ptr;
1035 }
1036 
1037 
1038 
1039 #if _DEBUG_TLSF_
1040 
1041 /*************** DEBUG FUNCTIONS **************/
1042 
1043 /* The following functions have been designed to ease the debugging of */
1044 /* the TLSF structure. For non-developing purposes, it may be they */
1045 /* haven't too much worth. To enable them, _DEBUG_TLSF_ must be set. */
1046 
1047 extern void dump_memory_region(unsigned char *mem_ptr, unsigned int size);
1048 extern void print_block(FILE* ff, bhdr_t * b);
1049 //extern void print_tlsf_mp(); in tlsf.h
1050 extern void print_tlsf(FILE* ff, tlsf_t * tlsf);
1051 //extern void print_all_blocks_mp(); in tlsf.h
1052 extern void print_all_blocks(FILE* ff, tlsf_t * tlsf);
1053 
1054 void dump_memory_region(unsigned char *mem_ptr, unsigned int size)
1055 {
1056 
1057  unsigned long begin = (unsigned long) mem_ptr;
1058  unsigned long end = (unsigned long) mem_ptr + size;
1059  int column = 0;
1060 
1061  begin >>= 2;
1062  begin <<= 2;
1063 
1064  end >>= 2;
1065  end++;
1066  end <<= 2;
1067 
1068  PRINT_MSG("\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
1069 
1070  column = 0;
1071  PRINT_MSG("0x%lx ", begin);
1072 
1073  while (begin < end) {
1074  if (((unsigned char *) begin)[0] == 0)
1075  PRINT_MSG("00");
1076  else
1077  PRINT_MSG("%02x", ((unsigned char *) begin)[0]);
1078  if (((unsigned char *) begin)[1] == 0)
1079  PRINT_MSG("00 ");
1080  else
1081  PRINT_MSG("%02x ", ((unsigned char *) begin)[1]);
1082  begin += 2;
1083  column++;
1084  if (column == 8) {
1085  PRINT_MSG("\n0x%lx ", begin);
1086  column = 0;
1087  }
1088 
1089  }
1090  PRINT_MSG("\n\n");
1091 }
1092 
1093 void print_block(FILE* ff, bhdr_t * b)
1094 {
1095  if (!b)
1096  return;
1097  FPRINT_MSG(ff, ">> [%p] (", b);
1098  if ((b->size & BLOCK_SIZE))
1099  FPRINT_MSG(ff, "%lu bytes, ", (unsigned long) ((intptr_t)b->size & BLOCK_SIZE));
1100  else
1101  FPRINT_MSG(ff, "sentinel, ");
1102  if ((b->size & BLOCK_STATE) == FREE_BLOCK)
1103  FPRINT_MSG(ff, "free [%p, %p], ", b->ptr.free_ptr.prev, b->ptr.free_ptr.next);
1104  else
1105  FPRINT_MSG(ff, "used, ");
1106  if ((b->size & PREV_STATE) == PREV_FREE)
1107  FPRINT_MSG(ff, "prev. free [%p])\n", (void*)((intptr_t)b->prev_hdr & BLOCK_SIZE));
1108  else
1109  FPRINT_MSG(ff, "prev used)\n");
1110 }
1111 
1112 // use default memory pool
1113 void print_tlsf_mp(FILE* ff)
1114 {
1115  if (0 == ff) return;
1116  if (0 == mp) return;
1117 
1118  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
1119  print_tlsf(ff, (tlsf_t *)mp);
1120  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
1121 }
1122 
1123 void print_tlsf(FILE* ff, tlsf_t * tlsf)
1124 {
1125  if (0 == ff) return;
1126  if (0 == tlsf) return;
1127 
1128  bhdr_t *next;
1129  int i, j;
1130 
1131  FPRINT_MSG(ff, "\nTLSF at %p\n", tlsf);
1132 
1133  FPRINT_MSG(ff, "FL bitmap: 0x%x\n\n", (unsigned) tlsf->fl_bitmap);
1134 
1135  for (i = 0; i < REAL_FLI; i++) {
1136  if (tlsf->sl_bitmap[i])
1137  FPRINT_MSG(ff, "SL bitmap 0x%x\n", (unsigned) tlsf->sl_bitmap[i]);
1138  for (j = 0; j < MAX_SLI; j++) {
1139  next = tlsf->matrix[i][j];
1140  if (next)
1141  FPRINT_MSG(ff, "-> [%d][%d]\n", i, j);
1142  while (next) {
1143  print_block(ff, next);
1144  next = next->ptr.free_ptr.next;
1145  }
1146  }
1147  }
1148 }
1149 
1150 // use default memory pool
1151 void print_all_blocks_mp(FILE* ff)
1152 {
1153  if (0 == ff) return;
1154  if (0 == mp) return;
1155 
1156  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
1157  print_all_blocks(ff, (tlsf_t *)mp);
1158  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
1159 }
1160 
1161 void print_all_blocks(FILE* ff, tlsf_t * tlsf)
1162 {
1163  if (0 == ff) return;
1164  if (0 == tlsf) return;
1165 
1166  area_info_t *ai;
1167  bhdr_t *next;
1168  FPRINT_MSG(ff, "\nTLSF at %p\nALL BLOCKS\n", tlsf);
1169  FPRINT_MSG(ff, "Sizes (bytes)\n");
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" ,
1177  sizeof(bhdr_t), sizeof(area_info_t), sizeof(tlsf_t));
1178  ai = tlsf->area_head;
1179  while (ai) {
1180  next = (bhdr_t *) ((char *) ai - BHDR_OVERHEAD);
1181  while (next) {
1182  print_block(ff, next);
1183  if ((next->size & BLOCK_SIZE))
1184  next = GET_NEXT_BLOCK(next->ptr.buffer, next->size & BLOCK_SIZE);
1185  else
1186  next = NULL;
1187  }
1188  ai = ai->next;
1189  }
1190 }
1191 
1192 #endif
#define BLOCK_STATE
Definition: tlsf.c:172
bhdr_t * matrix[REAL_FLI][MAX_SLI]
Definition: tlsf.c:260
struct bhdr_struct * next
Definition: tlsf.c:210
#define ROUNDUP(_x, _v)
Definition: tlsf.c:170
#define ERROR_MSG(fmt, args...)
Definition: tlsf.c:195
#define TLSF_ACQUIRE_LOCK(l)
Definition: target.h:47
void * realloc_ex(void *ptr, size_t new_size, void *mem_pool)
Definition: tlsf.c:930
#define TLSF_SIGNATURE
Definition: tlsf.c:150
#define PREV_FREE
Definition: tlsf.c:181
void * tlsf_malloc(size_t size)
Definition: tlsf.c:734
#define FLI_OFFSET
Definition: tlsf.c:144
#define INSERT_BLOCK(_b, _tlsf, _fl, _sl)
Definition: tlsf.c:432
struct TLSF_struct tlsf_t
void * malloc_ex(size_t size, void *mem_pool)
Definition: tlsf.c:812
struct area_info_struct area_info_t
u8_t buffer[1]
Definition: tlsf.c:221
static __inline__ int ms_bit(int x)
Definition: tlsf.c:323
#define PTR_MASK
Definition: tlsf.c:152
u32_t fl_bitmap
Definition: tlsf.c:255
size_t add_new_area(void *area, size_t area_size, void *mem_pool)
Definition: tlsf.c:547
size_t get_max_size(void *mem_pool)
Definition: tlsf.c:695
void * calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
Definition: tlsf.c:1022
#define TYPE_PUN(dsttype, srctype, x)
Definition: tlsf.c:162
#define BHDR_OVERHEAD
Definition: tlsf.c:149
struct free_ptr_struct free_ptr_t
union bhdr_struct::@4 ptr
static __inline__ void MAPPING_SEARCH(size_t *_r, int *_fl, int *_sl)
Definition: tlsf.c:342
#define FREE_BLOCK
Definition: tlsf.c:177
static __inline__ int ls_bit(int x)
Definition: tlsf.c:314
size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
Definition: tlsf.c:498
#define GET_NEXT_BLOCK(_addr, _r)
Definition: tlsf.c:165
static __inline__ bhdr_t * FIND_SUITABLE_BLOCK(tlsf_t *_tlsf, int *_fl, int *_sl)
Definition: tlsf.c:375
#define PRINT_MSG(fmt, args...)
Definition: tlsf.c:193
#define ROUNDUP_SIZE(_r)
Definition: tlsf.c:168
size_t size
Definition: tlsf.c:217
#define TLSF_CREATE_LOCK(l)
Definition: target.h:45
#define USED_BLOCK
Definition: tlsf.c:178
void destroy_memory_pool(void *mem_pool)
Definition: tlsf.c:718
static __inline__ void MAPPING_INSERT(size_t _r, int *_fl, int *_sl)
Definition: tlsf.c:362
size_t get_overhead_size_mp(void)
Definition: tlsf.c:661
void * tlsf_realloc(void *ptr, size_t size)
Definition: tlsf.c:776
void tlsf_free(void *ptr)
Definition: tlsf.c:763
size_t get_used_size_mp(void)
Definition: tlsf.c:684
size_t get_pool_size_mp(void)
Definition: tlsf.c:638
void abort(void)
#define MAX_SLI
Definition: tlsf.c:142
#define TLSF_MLOCK_T
Definition: target.h:44
static char * mp
Definition: tlsf.c:495
#define __inline__
Definition: tlsf.c:123
static const int table[]
Definition: tlsf.c:287
#define PREV_STATE
Definition: tlsf.c:173
#define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl)
Definition: tlsf.c:401
TLSF_MLOCK_T lock
Definition: tlsf.c:238
void * tlsf_calloc(size_t nelem, size_t elem_size)
Definition: tlsf.c:797
u32_t tlsf_signature
Definition: tlsf.c:235
struct area_info_struct * next
Definition: tlsf.c:230
static __inline__ void set_bit(int nr, u32_t *addr)
Definition: tlsf.c:332
#define MIN_BLOCK_SIZE
Definition: tlsf.c:148
u32_t sl_bitmap[REAL_FLI]
Definition: tlsf.c:258
#define TLSF_RELEASE_LOCK(l)
Definition: target.h:48
#define DEFAULT_AREA_SIZE
Definition: tlsf.c:185
static __inline__ void corrupt(const char *s)
Definition: tlsf.c:393
size_t get_pool_size(void *mem_pool)
Definition: tlsf.c:626
#define SMALL_BLOCK
Definition: tlsf.c:146
#define BLOCK_SIZE
Definition: tlsf.c:153
#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl)
Definition: tlsf.c:415
#define STATE_MASK
Definition: tlsf.c:174
#define MAX_LOG2_SLI
Definition: tlsf.c:141
struct free_ptr_struct free_ptr
Definition: tlsf.c:220
static __inline__ bhdr_t * process_area(void *area, size_t size)
Definition: tlsf.c:468
size_t get_overhead_size(void *mem_pool)
Definition: tlsf.c:649
static __inline__ void clear_bit(int nr, u32_t *addr)
Definition: tlsf.c:337
#define TLSF_DESTROY_LOCK(l)
Definition: target.h:46
#define TLSF_REMOVE_SIZE(tlsf, b)
Definition: tlsf.c:107
#define REAL_FLI
Definition: tlsf.c:147
size_t get_max_size_mp(void)
Definition: tlsf.c:707
struct bhdr_struct bhdr_t
#define TLSF_ADD_SIZE(tlsf, b)
Definition: tlsf.c:106
void free_ex(void *ptr, void *mem_pool)
Definition: tlsf.c:880
static __inline__ bhdr_t * encode_prev_block(bhdr_t *prev, size_t size)
Definition: tlsf.c:283
size_t get_used_size(void *mem_pool)
Definition: tlsf.c:672
bhdr_t * end
Definition: tlsf.c:229
struct bhdr_struct * prev_hdr
Definition: tlsf.c:215
struct bhdr_struct * prev
Definition: tlsf.c:209
area_info_t * area_head
Definition: tlsf.c:251
#define ROUNDDOWN_SIZE(_r)
Definition: tlsf.c:169
unsigned char u8_t
Definition: tlsf.c:206
#define PREV_USED
Definition: tlsf.c:182
#define FPRINT_MSG(ff, fmt, args...)
Definition: tlsf.c:194
unsigned int u32_t
Definition: tlsf.c:205


rtt
Author(s): RTT Developers
autogenerated on Fri Oct 25 2019 03:59:44