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  static const char *k = "* Heap corruption detected: *\n";
395  (void) write( STDERR_FILENO, k, strlen(k) );
396  (void) write( STDERR_FILENO, msg, strlen(msg) );
397  abort();
398 }
399 
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; \
404  else { \
405  clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \
406  if (!_tlsf -> sl_bitmap [_fl]) \
407  clear_bit (_fl, &_tlsf -> fl_bitmap); \
408  } \
409  _b -> ptr.free_ptr.prev = NULL; \
410  _b -> ptr.free_ptr.next = NULL; \
411  }while(0)
412 
413 
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); \
425  } \
426  } \
427  _b -> ptr.free_ptr.prev = NULL; \
428  _b -> ptr.free_ptr.next = NULL; \
429  } while(0)
430 
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); \
439  } while(0)
440 
441 #if USE_SBRK || USE_MMAP
442 static __inline__ void *get_new_area(size_t * size)
443 {
444  void *area;
445 
446 #if USE_SBRK
447  area = (void *)sbrk(0);
448  if (((void *)sbrk(*size)) != ((void *) -1))
449  return area;
450 #endif
451 
452 #ifndef MAP_ANONYMOUS
453 /* https://dev.openwrt.org/ticket/322 */
454 # define MAP_ANONYMOUS MAP_ANON
455 #endif
456 
457 
458 #if USE_MMAP
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)
461  return area;
462 #endif
463  return ((void *) ~0);
464 }
465 #endif
466 
467 static __inline__ bhdr_t *process_area(void *area, size_t size)
468 {
469  bhdr_t *b, *lb, *ib;
470  area_info_t *ai;
471 
472  ib = (bhdr_t *) area;
473  ib->size =
474  (sizeof(area_info_t) <
476  ib->prev_hdr = encode_prev_block( NULL, ib->size );
477  b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
478  b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED;
479  b->prev_hdr = encode_prev_block( NULL, b->size );
480  b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0;
481  lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
482  lb->size = 0 | USED_BLOCK | PREV_FREE;
483  lb->prev_hdr = encode_prev_block( b, lb->size );
484  ai = TYPE_PUN(area_info_t, u8_t, ib->ptr.buffer);
485  ai->next = 0;
486  ai->end = lb;
487  return ib;
488 }
489 
490 /******************************************************************/
491 /******************** Begin of the allocator code *****************/
492 /******************************************************************/
493 
494 static char *mp = NULL; /* Default memory pool. */
495 
496 /******************************************************************/
497 size_t init_memory_pool(size_t mem_pool_size, void *mem_pool)
498 {
499 /******************************************************************/
500  tlsf_t *tlsf;
501  bhdr_t *b, *ib;
502 
503  if (!mem_pool || !mem_pool_size || mem_pool_size < sizeof(tlsf_t) + BHDR_OVERHEAD * 8) {
504  ERROR_MSG("init_memory_pool (): memory_pool invalid\n");
505  return -1;
506  }
507 
508  if (((unsigned long) mem_pool & PTR_MASK)) {
509  ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n");
510  return -1;
511  }
512  tlsf = (tlsf_t *) mem_pool;
513  /* Check if already initialised */
514  if (tlsf->tlsf_signature == TLSF_SIGNATURE) {
515  b = GET_NEXT_BLOCK(mp, ROUNDUP_SIZE(sizeof(tlsf_t)));
516  return b->size & BLOCK_SIZE;
517  }
518 
519  if(mp == 0)
520  mp = mem_pool;
521 
522  /* Zeroing the memory pool */
523  memset(mem_pool, 0, sizeof(tlsf_t));
524 
526 
527  TLSF_CREATE_LOCK(&tlsf->lock);
528 
530  (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t)));
531  b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE);
532  free_ex(b->ptr.buffer, tlsf);
533  tlsf->area_head = TYPE_PUN(area_info_t, u8_t, ib->ptr.buffer);
534 
535 #if TLSF_STATISTIC
536  tlsf->pool_size = mem_pool_size;
537  tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE);
538  tlsf->overhead_size = tlsf->used_size;
539  tlsf->max_size = tlsf->used_size;
540 #endif
541 
542  return (b->size & BLOCK_SIZE);
543 }
544 
545 /******************************************************************/
546 size_t add_new_area(void *area, size_t area_size, void *mem_pool)
547 {
548 /******************************************************************/
549  tlsf_t *tlsf = (tlsf_t *) mem_pool;
550  area_info_t *ptr, *ptr_prev, *ai;
551  bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b;
552 
553  memset(area, 0, area_size);
554  ptr = tlsf->area_head;
555  ptr_prev = 0;
556 
557  ib0 = process_area(area, area_size);
558  b0 = GET_NEXT_BLOCK(ib0->ptr.buffer, ib0->size & BLOCK_SIZE);
559  lb0 = GET_NEXT_BLOCK(b0->ptr.buffer, b0->size & BLOCK_SIZE);
560 
561  /* Before inserting the new area, we have to merge this area with the
562  already existing ones */
563 
564  while (ptr) {
565  ib1 = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
566  b1 = GET_NEXT_BLOCK(ib1->ptr.buffer, ib1->size & BLOCK_SIZE);
567  lb1 = ptr->end;
568 
569  /* Merging the new area with the next physically contigous one */
570  if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) {
571  if (tlsf->area_head == ptr) {
572  tlsf->area_head = ptr->next;
573  ptr = ptr->next;
574  } else {
575  ptr_prev->next = ptr->next;
576  ptr = ptr->next;
577  }
578 
579  b0->size =
580  ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
581  (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED;
582 
583  b1->prev_hdr = encode_prev_block( b0, b0->size );
584  lb0 = lb1;
585 
586  continue;
587  }
588 
589  /* Merging the new area with the previous physically contigous
590  one */
591  if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) {
592  if (tlsf->area_head == ptr) {
593  tlsf->area_head = ptr->next;
594  ptr = ptr->next;
595  } else {
596  ptr_prev->next = ptr->next;
597  ptr = ptr->next;
598  }
599 
600  lb1->size =
601  ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) +
602  (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE);
603  next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE);
604  next_b->prev_hdr = encode_prev_block( lb1, next_b->size );
605  b0 = lb1;
606  ib0 = ib1;
607 
608  continue;
609  }
610  ptr_prev = ptr;
611  ptr = ptr->next;
612  }
613 
614  /* Inserting the area in the list of linked areas */
615  ai = TYPE_PUN(area_info_t, u8_t, ib0->ptr.buffer);
616  ai->next = tlsf->area_head;
617  ai->end = lb0;
618  tlsf->area_head = ai;
619  free_ex(b0->ptr.buffer, mem_pool);
620  return (b0->size & BLOCK_SIZE);
621 }
622 
623 
624 /******************************************************************/
625 size_t get_pool_size(void *mem_pool)
626 {
627 /******************************************************************/
628 #if TLSF_STATISTIC
629  return ((tlsf_t *) mem_pool)->pool_size;
630 #else
631  return 0;
632 #endif
633 }
634 
635 /******************************************************************/
636 // use default memory pool
637 size_t get_pool_size_mp(void)
638 {
639 /******************************************************************/
640 #if TLSF_STATISTIC
641  return (mp ? ((tlsf_t *) mp)->pool_size : 0);
642 #else
643  return 0;
644 #endif
645 }
646 
647 /******************************************************************/
648 size_t get_overhead_size(void *mem_pool)
649 {
650 /******************************************************************/
651 #if TLSF_STATISTIC
652  return ((tlsf_t *) mem_pool)->overhead_size;
653 #else
654  return 0;
655 #endif
656 }
657 
658 /******************************************************************/
659 // use default memory pool
661 {
662 /******************************************************************/
663 #if TLSF_STATISTIC
664  return (mp ? ((tlsf_t *) mp)->overhead_size : 0);
665 #else
666  return 0;
667 #endif
668 }
669 
670 /******************************************************************/
671 size_t get_used_size(void *mem_pool)
672 {
673 /******************************************************************/
674 #if TLSF_STATISTIC
675  return ((tlsf_t *) mem_pool)->used_size;
676 #else
677  return 0;
678 #endif
679 }
680 
681 /******************************************************************/
682 // use default memory pool
683 size_t get_used_size_mp(void)
684 {
685 /******************************************************************/
686 #if TLSF_STATISTIC
687  return (mp ? ((tlsf_t *) mp)->used_size : 0);
688 #else
689  return 0;
690 #endif
691 }
692 
693 /******************************************************************/
694 size_t get_max_size(void *mem_pool)
695 {
696 /******************************************************************/
697 #if TLSF_STATISTIC
698  return ((tlsf_t *) mem_pool)->max_size;
699 #else
700  return 0;
701 #endif
702 }
703 
704 /******************************************************************/
705 // use default memory pool
706 size_t get_max_size_mp(void)
707 {
708 /******************************************************************/
709 #if TLSF_STATISTIC
710  return (mp ? ((tlsf_t *) mp)->max_size : 0);
711 #else
712  return 0;
713 #endif
714 }
715 
716 /******************************************************************/
717 void destroy_memory_pool(void *mem_pool)
718 {
719 /******************************************************************/
720  if((void*)mp == (void*)mem_pool){
721  mp = 0;
722  }
723 
724  tlsf_t *tlsf = (tlsf_t *) mem_pool;
725  tlsf->tlsf_signature = 0;
726 
727  TLSF_DESTROY_LOCK(&tlsf->lock);
728 
729 }
730 
731 
732 /******************************************************************/
733 void *tlsf_malloc(size_t size)
734 {
735 /******************************************************************/
736  void *ret;
737 
738 #if USE_MMAP || USE_SBRK
739  if (!mp) {
740  size_t area_size;
741  void *area;
742 
743  area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */
744  area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
745  area = get_new_area(&area_size);
746  if (area == ((void *) ~0))
747  return NULL; /* Not enough system memory */
748  init_memory_pool(area_size, area);
749  }
750 #endif
751 
752  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
753 
754  ret = malloc_ex(size, mp);
755 
756  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
757 
758  return ret;
759 }
760 
761 /******************************************************************/
762 void tlsf_free(void *ptr)
763 {
764 /******************************************************************/
765 
766  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
767 
768  free_ex(ptr, mp);
769 
770  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
771 
772 }
773 
774 /******************************************************************/
775 void *tlsf_realloc(void *ptr, size_t size)
776 {
777 /******************************************************************/
778  void *ret;
779 
780 #if USE_MMAP || USE_SBRK
781  if (!mp) {
782  return tlsf_malloc(size);
783  }
784 #endif
785 
786  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
787 
788  ret = realloc_ex(ptr, size, mp);
789 
790  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
791 
792  return ret;
793 }
794 
795 /******************************************************************/
796 void *tlsf_calloc(size_t nelem, size_t elem_size)
797 {
798 /******************************************************************/
799  void *ret;
800 
801  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
802 
803  ret = calloc_ex(nelem, elem_size, mp);
804 
805  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
806 
807  return ret;
808 }
809 
810 /******************************************************************/
811 void *malloc_ex(size_t size, void *mem_pool)
812 {
813 /******************************************************************/
814  tlsf_t *tlsf = (tlsf_t *) mem_pool;
815  bhdr_t *b, *b2, *next_b;
816  int fl, sl;
817  size_t tmp_size;
818 
819  size = (size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(size);
820 
821  /* Rounding up the requested size and calculating fl and sl */
822  MAPPING_SEARCH(&size, &fl, &sl);
823 
824  /* Searching a free block, recall that this function changes the values of fl and sl,
825  so they are not longer valid when the function fails */
826  b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
827 #if USE_MMAP || USE_SBRK
828  if (!b) {
829  size_t area_size;
830  void *area;
831  /* Growing the pool size when needed */
832  area_size = size + BHDR_OVERHEAD * 8; /* size plus enough room for the requered headers. */
833  area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE;
834  area = get_new_area(&area_size); /* Call sbrk or mmap */
835  if (area == ((void *) ~0))
836  return NULL; /* Not enough system memory */
837  add_new_area(area, area_size, mem_pool);
838  /* Rounding up the requested size and calculating fl and sl */
839  MAPPING_SEARCH(&size, &fl, &sl);
840  /* Searching a free block */
841  b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl);
842  }
843 #endif
844  if (!b)
845  return NULL; /* Not found */
846 
847  EXTRACT_BLOCK_HDR(b, tlsf, fl, sl);
848 
849  /*-- found: */
850  next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
851  /* Should the block be split? */
852  tmp_size = (b->size & BLOCK_SIZE) - size;
853  if (tmp_size >= sizeof(bhdr_t)) {
854  tmp_size -= BHDR_OVERHEAD;
855  b2 = GET_NEXT_BLOCK(b->ptr.buffer, size);
856  b2->size = tmp_size | FREE_BLOCK | PREV_USED;
857  b2->prev_hdr = encode_prev_block( b2->prev_hdr, b2->size );
858  next_b->prev_hdr = encode_prev_block(b2, next_b->size);
859  MAPPING_INSERT(tmp_size, &fl, &sl);
860  INSERT_BLOCK(b2, tlsf, fl, sl);
861 
862  b->size = size | (b->size & PREV_STATE);
863  } else {
864  next_b->size &= (~PREV_FREE);
865  next_b->prev_hdr = encode_prev_block( next_b->prev_hdr, next_b->size );
866  b->size &= (~FREE_BLOCK); /* Now it's used */
867  }
868  b->prev_hdr = encode_prev_block( b->prev_hdr, b->size );
869 
870  TLSF_ADD_SIZE(tlsf, b);
871 
872  if( (b->size & BLOCK_STATE) != (~(intptr_t)b->prev_hdr & BLOCK_STATE) )
873  corrupt("malloc_ex(): Mismatched flags after allocation\n");
874 
875  return (void *) b->ptr.buffer;
876 }
877 
878 /******************************************************************/
879 void free_ex(void *ptr, void *mem_pool)
880 {
881 /******************************************************************/
882  tlsf_t *tlsf = (tlsf_t *) mem_pool;
883  bhdr_t *b, *tmp_b;
884  int fl = 0, sl = 0;
885 
886  if (!ptr) {
887  return;
888  }
889  b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
890 
891  if( (b->size & BLOCK_STATE) != USED_BLOCK )
892  corrupt( "free_ex(): Freeing unused block\n" );
893  if( (b->size & BLOCK_STATE) != (~(intptr_t)b->prev_hdr & BLOCK_STATE) )
894  corrupt("free_ex(): Mismatched flags\n");
895 
896  b->size |= FREE_BLOCK;
897 
898  TLSF_REMOVE_SIZE(tlsf, b);
899 
900  b->ptr.free_ptr.prev = NULL;
901  b->ptr.free_ptr.next = NULL;
902  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
903  if (tmp_b->size & FREE_BLOCK) {
904  /* Coalesce next block */
905  MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
906  EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
907  b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
908  }
909  if (b->size & PREV_FREE) {
910  /* Coalesce previous block */
911  tmp_b = (bhdr_t*) ( (intptr_t)b->prev_hdr & BLOCK_SIZE );
912  MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl);
913  EXTRACT_BLOCK(tmp_b, tlsf, fl, sl);
914  tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
915  b = tmp_b;
916  }
917  MAPPING_INSERT(b->size & BLOCK_SIZE, &fl, &sl);
918  INSERT_BLOCK(b, tlsf, fl, sl);
919 
920  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
921  /* if tmp_b is free, it should have been coalesced */
922  if( (tmp_b->size & BLOCK_STATE) == FREE_BLOCK )
923  corrupt( "free_ex(): uncoalesced block\n");
924  tmp_b->size |= PREV_FREE;
925  tmp_b->prev_hdr = encode_prev_block(b, tmp_b->size);
926 }
927 
928 /******************************************************************/
929 void *realloc_ex(void *ptr, size_t new_size, void *mem_pool)
930 {
931 /******************************************************************/
932  tlsf_t *tlsf = (tlsf_t *) mem_pool;
933  void *ptr_aux;
934  unsigned int cpsize;
935  bhdr_t *b, *tmp_b, *next_b;
936  int fl, sl;
937  size_t tmp_size;
938 
939  if (!ptr) {
940  if (new_size)
941  return (void *) malloc_ex(new_size, mem_pool);
942  if (!new_size)
943  return NULL;
944  } else if (!new_size) {
945  free_ex(ptr, mem_pool);
946  return NULL;
947  }
948 
949  b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD);
950  next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
951  new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size);
952  tmp_size = (b->size & BLOCK_SIZE);
953  if (new_size <= tmp_size) {
954  /* shrink allocated portion */
955  TLSF_REMOVE_SIZE(tlsf, b);
956  if (next_b->size & FREE_BLOCK) {
957  /* coalesce next block (free) */
958  MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
959  EXTRACT_BLOCK(next_b, tlsf, fl, sl);
960  tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
961  next_b = GET_NEXT_BLOCK(next_b->ptr.buffer, next_b->size & BLOCK_SIZE);
962  /* We allways reenter this free block because tmp_size will
963  be greater then sizeof (bhdr_t) */
964  }
965  tmp_size -= new_size;
966  if (tmp_size >= sizeof(bhdr_t)) {
967  /* add tail as free block */
968  tmp_size -= BHDR_OVERHEAD;
969  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
970  tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
971  tmp_b->prev_hdr = encode_prev_block( NULL, tmp_b->size );
972  next_b->size |= PREV_FREE;
973  next_b->prev_hdr = encode_prev_block( tmp_b, next_b->size );
974  MAPPING_INSERT(tmp_size, &fl, &sl);
975  INSERT_BLOCK(tmp_b, tlsf, fl, sl);
976  b->size = new_size | (b->size & PREV_STATE);
977  }
978  TLSF_ADD_SIZE(tlsf, b);
979  return (void *) b->ptr.buffer;
980  }
981  if ((next_b->size & FREE_BLOCK)) {
982  if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) {
983  /* allocate out of next block */
984  TLSF_REMOVE_SIZE(tlsf, b);
985  MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl);
986  EXTRACT_BLOCK(next_b, tlsf, fl, sl);
987  b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD;
988  next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE);
989  next_b->size &= ~PREV_FREE;
990  next_b->prev_hdr = encode_prev_block( b, next_b->size );
991  tmp_size = (b->size & BLOCK_SIZE) - new_size;
992  if (tmp_size >= sizeof(bhdr_t)) {
993  tmp_size -= BHDR_OVERHEAD;
994  tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size);
995  tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED;
996  next_b->size |= PREV_FREE;
997  next_b->prev_hdr = encode_prev_block(tmp_b, next_b->size);
998  MAPPING_INSERT(tmp_size, &fl, &sl);
999  INSERT_BLOCK(tmp_b, tlsf, fl, sl);
1000  b->size = new_size | (b->size & PREV_STATE);
1001  }
1002  TLSF_ADD_SIZE(tlsf, b);
1003  return (void *) b->ptr.buffer;
1004  }
1005  }
1006 
1007  if (!(ptr_aux = malloc_ex(new_size, mem_pool))){
1008  return NULL;
1009  }
1010 
1011  cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE);
1012 
1013  memcpy(ptr_aux, ptr, cpsize);
1014 
1015  free_ex(ptr, mem_pool);
1016  return ptr_aux;
1017 }
1018 
1019 
1020 /******************************************************************/
1021 void *calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
1022 {
1023 /******************************************************************/
1024  void *ptr;
1025 
1026  if (nelem <= 0 || elem_size <= 0)
1027  return NULL;
1028 
1029  if (!(ptr = malloc_ex(nelem * elem_size, mem_pool)))
1030  return NULL;
1031  memset(ptr, 0, nelem * elem_size);
1032 
1033  return ptr;
1034 }
1035 
1036 
1037 
1038 #if _DEBUG_TLSF_
1039 
1040 /*************** DEBUG FUNCTIONS **************/
1041 
1042 /* The following functions have been designed to ease the debugging of */
1043 /* the TLSF structure. For non-developing purposes, it may be they */
1044 /* haven't too much worth. To enable them, _DEBUG_TLSF_ must be set. */
1045 
1046 extern void dump_memory_region(unsigned char *mem_ptr, unsigned int size);
1047 extern void print_block(FILE* ff, bhdr_t * b);
1048 //extern void print_tlsf_mp(); in tlsf.h
1049 extern void print_tlsf(FILE* ff, tlsf_t * tlsf);
1050 //extern void print_all_blocks_mp(); in tlsf.h
1051 extern void print_all_blocks(FILE* ff, tlsf_t * tlsf);
1052 
1053 void dump_memory_region(unsigned char *mem_ptr, unsigned int size)
1054 {
1055 
1056  unsigned long begin = (unsigned long) mem_ptr;
1057  unsigned long end = (unsigned long) mem_ptr + size;
1058  int column = 0;
1059 
1060  begin >>= 2;
1061  begin <<= 2;
1062 
1063  end >>= 2;
1064  end++;
1065  end <<= 2;
1066 
1067  PRINT_MSG("\nMemory region dumped: 0x%lx - 0x%lx\n\n", begin, end);
1068 
1069  column = 0;
1070  PRINT_MSG("0x%lx ", begin);
1071 
1072  while (begin < end) {
1073  if (((unsigned char *) begin)[0] == 0)
1074  PRINT_MSG("00");
1075  else
1076  PRINT_MSG("%02x", ((unsigned char *) begin)[0]);
1077  if (((unsigned char *) begin)[1] == 0)
1078  PRINT_MSG("00 ");
1079  else
1080  PRINT_MSG("%02x ", ((unsigned char *) begin)[1]);
1081  begin += 2;
1082  column++;
1083  if (column == 8) {
1084  PRINT_MSG("\n0x%lx ", begin);
1085  column = 0;
1086  }
1087 
1088  }
1089  PRINT_MSG("\n\n");
1090 }
1091 
1092 void print_block(FILE* ff, bhdr_t * b)
1093 {
1094  if (!b)
1095  return;
1096  FPRINT_MSG(ff, ">> [%p] (", b);
1097  if ((b->size & BLOCK_SIZE))
1098  FPRINT_MSG(ff, "%lu bytes, ", (unsigned long) ((intptr_t)b->size & BLOCK_SIZE));
1099  else
1100  FPRINT_MSG(ff, "sentinel, ");
1101  if ((b->size & BLOCK_STATE) == FREE_BLOCK)
1102  FPRINT_MSG(ff, "free [%p, %p], ", b->ptr.free_ptr.prev, b->ptr.free_ptr.next);
1103  else
1104  FPRINT_MSG(ff, "used, ");
1105  if ((b->size & PREV_STATE) == PREV_FREE)
1106  FPRINT_MSG(ff, "prev. free [%p])\n", (void*)((intptr_t)b->prev_hdr & BLOCK_SIZE));
1107  else
1108  FPRINT_MSG(ff, "prev used)\n");
1109 }
1110 
1111 // use default memory pool
1112 void print_tlsf_mp(FILE* ff)
1113 {
1114  if (0 == ff) return;
1115  if (0 == mp) return;
1116 
1117  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
1118  print_tlsf(ff, (tlsf_t *)mp);
1119  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
1120 }
1121 
1122 void print_tlsf(FILE* ff, tlsf_t * tlsf)
1123 {
1124  if (0 == ff) return;
1125  if (0 == tlsf) return;
1126 
1127  bhdr_t *next;
1128  int i, j;
1129 
1130  FPRINT_MSG(ff, "\nTLSF at %p\n", tlsf);
1131 
1132  FPRINT_MSG(ff, "FL bitmap: 0x%x\n\n", (unsigned) tlsf->fl_bitmap);
1133 
1134  for (i = 0; i < REAL_FLI; i++) {
1135  if (tlsf->sl_bitmap[i])
1136  FPRINT_MSG(ff, "SL bitmap 0x%x\n", (unsigned) tlsf->sl_bitmap[i]);
1137  for (j = 0; j < MAX_SLI; j++) {
1138  next = tlsf->matrix[i][j];
1139  if (next)
1140  FPRINT_MSG(ff, "-> [%d][%d]\n", i, j);
1141  while (next) {
1142  print_block(ff, next);
1143  next = next->ptr.free_ptr.next;
1144  }
1145  }
1146  }
1147 }
1148 
1149 // use default memory pool
1150 void print_all_blocks_mp(FILE* ff)
1151 {
1152  if (0 == ff) return;
1153  if (0 == mp) return;
1154 
1155  TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock);
1156  print_all_blocks(ff, (tlsf_t *)mp);
1157  TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock);
1158 }
1159 
1160 void print_all_blocks(FILE* ff, tlsf_t * tlsf)
1161 {
1162  if (0 == ff) return;
1163  if (0 == tlsf) return;
1164 
1165  area_info_t *ai;
1166  bhdr_t *next;
1167  FPRINT_MSG(ff, "\nTLSF at %p\nALL BLOCKS\n", tlsf);
1168  FPRINT_MSG(ff, "Sizes (bytes)\n");
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" ,
1176  sizeof(bhdr_t), sizeof(area_info_t), sizeof(tlsf_t));
1177  ai = tlsf->area_head;
1178  while (ai) {
1179  next = (bhdr_t *) ((char *) ai - BHDR_OVERHEAD);
1180  while (next) {
1181  print_block(ff, next);
1182  if ((next->size & BLOCK_SIZE))
1183  next = GET_NEXT_BLOCK(next->ptr.buffer, next->size & BLOCK_SIZE);
1184  else
1185  next = NULL;
1186  }
1187  ai = ai->next;
1188  }
1189 }
1190 
1191 #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:929
#define TLSF_SIGNATURE
Definition: tlsf.c:150
#define PREV_FREE
Definition: tlsf.c:181
void * tlsf_malloc(size_t size)
Definition: tlsf.c:733
#define FLI_OFFSET
Definition: tlsf.c:144
#define INSERT_BLOCK(_b, _tlsf, _fl, _sl)
Definition: tlsf.c:431
struct TLSF_struct tlsf_t
void * malloc_ex(size_t size, void *mem_pool)
Definition: tlsf.c:811
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:546
size_t get_max_size(void *mem_pool)
Definition: tlsf.c:694
void * calloc_ex(size_t nelem, size_t elem_size, void *mem_pool)
Definition: tlsf.c:1021
#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:497
#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:717
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:660
void * tlsf_realloc(void *ptr, size_t size)
Definition: tlsf.c:775
void tlsf_free(void *ptr)
Definition: tlsf.c:762
size_t get_used_size_mp(void)
Definition: tlsf.c:683
size_t get_pool_size_mp(void)
Definition: tlsf.c:637
void abort(void)
#define MAX_SLI
Definition: tlsf.c:142
#define TLSF_MLOCK_T
Definition: target.h:44
static char * mp
Definition: tlsf.c:494
#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:400
TLSF_MLOCK_T lock
Definition: tlsf.c:238
void * tlsf_calloc(size_t nelem, size_t elem_size)
Definition: tlsf.c:796
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:625
#define SMALL_BLOCK
Definition: tlsf.c:146
#define BLOCK_SIZE
Definition: tlsf.c:153
#define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl)
Definition: tlsf.c:414
#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:467
size_t get_overhead_size(void *mem_pool)
Definition: tlsf.c:648
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:706
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:879
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:671
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 Tue Jun 25 2019 19:33:37