diff options
author | Solomon Peachy <pizza@shaftnet.org> | 2022-12-31 11:44:35 -0500 |
---|---|---|
committer | Solomon Peachy <pizza@shaftnet.org> | 2022-12-31 15:21:55 -0500 |
commit | 485e96d6beda16dc8b9ee74e7d10a957c3fddb2f (patch) | |
tree | 5e87f1f8028399bcc2df7db0a664a6b322719979 | |
parent | 85410589d14ba44f05d8d6317bd40ee56e08b163 (diff) | |
download | rockbox-485e96d6beda16dc8b9ee74e7d10a957c3fddb2f.tar.gz rockbox-485e96d6beda16dc8b9ee74e7d10a957c3fddb2f.zip |
tlsf: Update to upstream 2.4.6 release
Seems to resolve FS#13383 and FS#13384
Change-Id: I43b2f166b78e61c16723a944729aa117260320fc
-rw-r--r-- | lib/tlsf/Changelog | 39 | ||||
-rw-r--r-- | lib/tlsf/README | 2 | ||||
-rw-r--r-- | lib/tlsf/libtlsf.make | 2 | ||||
-rw-r--r-- | lib/tlsf/src/tlsf.c | 295 | ||||
-rw-r--r-- | lib/tlsf/src/tlsf.h | 4 |
5 files changed, 224 insertions, 118 deletions
diff --git a/lib/tlsf/Changelog b/lib/tlsf/Changelog index 0cdb34a8ab..f966685f6d 100644 --- a/lib/tlsf/Changelog +++ b/lib/tlsf/Changelog | |||
@@ -1,25 +1,38 @@ | |||
1 | Version History | 1 | Version History |
2 | --------------- | 2 | --------------- |
3 | -v2.4.4 (October 13 2008) | 3 | |
4 | |||
5 | -v2.4.6 (September 10 2009) | ||
6 | * Fixed a bug in the realloc func (discovered by the rockbox | ||
7 | project: www.rockbox.org). | ||
8 | |||
9 | |||
10 | -v2.4.5 (November 24 2008) | ||
11 | * Working on OSX/FreeBSD (may be for OpenBSD/NetBSD too). | ||
12 | Reported by Younès HAFRI. | ||
13 | printf (and stdio.h include) is now optional. | ||
14 | Reported by Masaki Muranaka | ||
15 | |||
16 | -v2.4.4 (October 13 2008) | ||
4 | * Corrected minor syntactic bug on statistic gathering code. | 17 | * Corrected minor syntactic bug on statistic gathering code. |
5 | Reported by Tim Cussins and P. Mantegazza. | 18 | Reported by Tim Cussins and P. Mantegazza. |
6 | 19 | ||
7 | -v2.4.3 (July 30 2008) | 20 | -v2.4.3 (July 30 2008) |
8 | * Minor fixes to compile with the greenhills compiler. | 21 | * Minor fixes to compile with the greenhills compiler. |
9 | Reported by "Kaya, Sinan SEA" <sinan.kaya@siemens.com> | 22 | Reported by "Kaya, Sinan SEA" <sinan.kaya@siemens.com> |
10 | * Small change in the license in order to include TLSF in the RTEMS | 23 | * Small change in the license in order to include TLSF in the RTEMS |
11 | project. | 24 | project. |
12 | 25 | ||
13 | -v2.4.2 (May 16 2008) (Herman ten Brugge) | 26 | -v2.4.2 (May 16 2008) (Herman ten Brugge) |
14 | * Memory usage statistics added again, with cleaner and more compacted | 27 | * Memory usage statistics added again, with cleaner and more compacted |
15 | code. | 28 | code. |
16 | 29 | ||
17 | -v2.4.1 (April 30 2008) | 30 | -v2.4.1 (April 30 2008) |
18 | * Fixed a bug in the tlsf_realloc function: init the pool automatically | 31 | * Fixed a bug in the tlsf_realloc function: init the pool automatically |
19 | on the first call. | 32 | on the first call. |
20 | Reported by: Alejandro Mery <amery@geeks.cl> | 33 | Reported by: Alejandro Mery <amery@geeks.cl> |
21 | 34 | ||
22 | -v2.4 (Feb 19 2008) | 35 | -v2.4 (Feb 19 2008) |
23 | * "rtl_*" functions renamed to "tlsf_*". | 36 | * "rtl_*" functions renamed to "tlsf_*". |
24 | * Added the add_new_area function to insert new memory areas to an | 37 | * Added the add_new_area function to insert new memory areas to an |
25 | existing memory pool. | 38 | existing memory pool. |
@@ -114,6 +127,6 @@ | |||
114 | as its default memory allocator. | 127 | as its default memory allocator. |
115 | 128 | ||
116 | - v0.1 ... v1.0: First implementations were created for testing and | 129 | - v0.1 ... v1.0: First implementations were created for testing and |
117 | research purposes. Basically TLSF is implemented to | 130 | research purposes. Basically TLSF is implemented to |
118 | be used by RTLinux-GPL (www.rtlinux-gpl.org), so | 131 | be used by RTLinux-GPL (www.rtlinux-gpl.org), so |
119 | it is RTLinux-oriented. | 132 | it is RTLinux-oriented. |
diff --git a/lib/tlsf/README b/lib/tlsf/README index d755905b16..4000885614 100644 --- a/lib/tlsf/README +++ b/lib/tlsf/README | |||
@@ -1,6 +1,6 @@ | |||
1 | 1 | ||
2 | TLSF Memory Storage allocator implementation. | 2 | TLSF Memory Storage allocator implementation. |
3 | Version 2.4 Feb 2008 | 3 | Version 2.4.6 Sept 2009 |
4 | 4 | ||
5 | Authors: Miguel Masmano, Ismael Ripoll & Alfons Crespo. | 5 | Authors: Miguel Masmano, Ismael Ripoll & Alfons Crespo. |
6 | Copyright UPVLC, OCERA Consortium. | 6 | Copyright UPVLC, OCERA Consortium. |
diff --git a/lib/tlsf/libtlsf.make b/lib/tlsf/libtlsf.make index e36efe5e27..b420fdc344 100644 --- a/lib/tlsf/libtlsf.make +++ b/lib/tlsf/libtlsf.make | |||
@@ -15,7 +15,7 @@ TLSFLIB := $(BUILDDIR)/lib/libtlsf.a | |||
15 | OTHER_SRC += $(TLSFLIB_SRC) | 15 | OTHER_SRC += $(TLSFLIB_SRC) |
16 | INCLUDES += -I$(TLSFLIB_DIR)/src | 16 | INCLUDES += -I$(TLSFLIB_DIR)/src |
17 | 17 | ||
18 | TLSFLIBFLAGS = $(CFLAGS) -fstrict-aliasing -ffunction-sections $(SHARED_CFLAGS) | 18 | TLSFLIBFLAGS = $(CFLAGS) -fstrict-aliasing -ffunction-sections $(SHARED_CFLAGS) -DHAVE_CONFIG_H |
19 | 19 | ||
20 | # Enable statistics in the sim | 20 | # Enable statistics in the sim |
21 | ifneq ($(findstring sdl-sim, $(APP_TYPE)), sdl-sim) | 21 | ifneq ($(findstring sdl-sim, $(APP_TYPE)), sdl-sim) |
diff --git a/lib/tlsf/src/tlsf.c b/lib/tlsf/src/tlsf.c index 46ae7616b1..15fa8002d2 100644 --- a/lib/tlsf/src/tlsf.c +++ b/lib/tlsf/src/tlsf.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Two Levels Segregate Fit memory allocator (TLSF) | 2 | * Two Levels Segregate Fit memory allocator (TLSF) |
3 | * Version 2.4.4 | 3 | * Version 2.4.6 |
4 | * | 4 | * |
5 | * Written by Miguel Masmano Tello <mimastel@doctor.upv.es> | 5 | * Written by Miguel Masmano Tello <mimastel@doctor.upv.es> |
6 | * | 6 | * |
@@ -23,27 +23,27 @@ | |||
23 | * | 23 | * |
24 | * - Add 64 bit support. It now runs on x86_64 and solaris64. | 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. | 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 | 26 | * - Remove assembly code. I could not measure any performance difference |
27 | * on my core2 processor. This also makes the code more portable. | 27 | * on my core2 processor. This also makes the code more portable. |
28 | * - Moved defines/typedefs from tlsf.h to tlsf.c | 28 | * - Moved defines/typedefs from tlsf.h to tlsf.c |
29 | * - Changed MIN_BLOCK_SIZE to sizeof (free_ptr_t) and BHDR_OVERHEAD to | 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 | 30 | * (sizeof (bhdr_t) - MIN_BLOCK_SIZE). This does not change the fact |
31 | * that the minumum size is still sizeof | 31 | * that the minumum size is still sizeof |
32 | * (bhdr_t). | 32 | * (bhdr_t). |
33 | * - Changed all C++ comment style to C style. (// -> /.* ... *./) | 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 | 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 | 35 | * avoid confusion with the standard ffs function which returns |
36 | * different values. | 36 | * different values. |
37 | * - Created set_bit/clear_bit fuctions because they are not present | 37 | * - Created set_bit/clear_bit fuctions because they are not present |
38 | * on x86_64. | 38 | * on x86_64. |
39 | * - Added locking support + extra file target.h to show how to use it. | 39 | * - Added locking support + extra file target.h to show how to use it. |
40 | * - Added get_used_size function (REMOVED in 2.4) | 40 | * - Added get_used_size function (REMOVED in 2.4) |
41 | * - Added rtl_realloc and rtl_calloc function | 41 | * - Added rtl_realloc and rtl_calloc function |
42 | * - Implemented realloc clever support. | 42 | * - Implemented realloc clever support. |
43 | * - Added some test code in the example directory. | 43 | * - Added some test code in the example directory. |
44 | * | 44 | * - Bug fixed (discovered by the rockbox project: www.rockbox.org). |
45 | * | 45 | * |
46 | * (Oct 23 2006) Adam Scislowicz: | 46 | * (Oct 23 2006) Adam Scislowicz: |
47 | * | 47 | * |
48 | * - Support for ARMv5 implemented | 48 | * - Support for ARMv5 implemented |
49 | * | 49 | * |
@@ -52,10 +52,32 @@ | |||
52 | /*#define USE_SBRK (0) */ | 52 | /*#define USE_SBRK (0) */ |
53 | /*#define USE_MMAP (0) */ | 53 | /*#define USE_MMAP (0) */ |
54 | 54 | ||
55 | #ifdef HAVE_CONFIG_H | ||
56 | #include "config.h" | ||
57 | #endif //HAVE_CONFIG_H | ||
58 | |||
59 | #ifdef HAVE_STDIO_H | ||
55 | #include <stdio.h> | 60 | #include <stdio.h> |
56 | #include <string.h> | 61 | #endif |
62 | |||
57 | #include <stdint.h> | 63 | #include <stdint.h> |
58 | 64 | ||
65 | void abort(void); | ||
66 | |||
67 | #if defined(ROCKBOX) && (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(DEBUG) | ||
68 | #define USE_PRINTF 1 | ||
69 | #endif | ||
70 | |||
71 | #if defined(ROCKBOX) | ||
72 | #include "panic.h" | ||
73 | #endif | ||
74 | |||
75 | #ifndef USE_PRINTF | ||
76 | #define USE_PRINTF (0) | ||
77 | #endif | ||
78 | |||
79 | #include <string.h> | ||
80 | |||
59 | #ifndef TLSF_USE_LOCKS | 81 | #ifndef TLSF_USE_LOCKS |
60 | #define TLSF_USE_LOCKS (0) | 82 | #define TLSF_USE_LOCKS (0) |
61 | #endif | 83 | #endif |
@@ -65,11 +87,11 @@ | |||
65 | #endif | 87 | #endif |
66 | 88 | ||
67 | #ifndef USE_MMAP | 89 | #ifndef USE_MMAP |
68 | #define USE_MMAP (0) | 90 | #define USE_MMAP (0) |
69 | #endif | 91 | #endif |
70 | 92 | ||
71 | #ifndef USE_SBRK | 93 | #ifndef USE_SBRK |
72 | #define USE_SBRK (0) | 94 | #define USE_SBRK (0) |
73 | #endif | 95 | #endif |
74 | 96 | ||
75 | 97 | ||
@@ -77,20 +99,22 @@ | |||
77 | #include "target.h" | 99 | #include "target.h" |
78 | #else | 100 | #else |
79 | #define TLSF_CREATE_LOCK(_unused_) do{}while(0) | 101 | #define TLSF_CREATE_LOCK(_unused_) do{}while(0) |
80 | #define TLSF_DESTROY_LOCK(_unused_) do{}while(0) | 102 | #define TLSF_DESTROY_LOCK(_unused_) do{}while(0) |
81 | #define TLSF_ACQUIRE_LOCK(_unused_) do{}while(0) | 103 | #define TLSF_ACQUIRE_LOCK(_unused_) do{}while(0) |
82 | #define TLSF_RELEASE_LOCK(_unused_) do{}while(0) | 104 | #define TLSF_RELEASE_LOCK(_unused_) do{}while(0) |
83 | #endif | 105 | #endif |
84 | 106 | ||
85 | #if TLSF_STATISTIC | 107 | #if TLSF_STATISTIC |
86 | #define TLSF_ADD_SIZE(tlsf, b) do { \ | 108 | #define TLSF_ADD_SIZE(tlsf, b) \ |
87 | tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ | 109 | do { \ |
88 | if (tlsf->used_size > tlsf->max_size) \ | 110 | tlsf->used_size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ |
89 | tlsf->max_size = tlsf->used_size; \ | 111 | if (tlsf->used_size > tlsf->max_size) \ |
90 | } while(0) | 112 | tlsf->max_size = tlsf->used_size; \ |
91 | 113 | } while(0) | |
92 | #define TLSF_REMOVE_SIZE(tlsf, b) do { \ | 114 | |
93 | tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ | 115 | #define TLSF_REMOVE_SIZE(tlsf, b) \ |
116 | do { \ | ||
117 | tlsf->used_size -= (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; \ | ||
94 | } while(0) | 118 | } while(0) |
95 | #else | 119 | #else |
96 | #define TLSF_ADD_SIZE(tlsf, b) do{}while(0) | 120 | #define TLSF_ADD_SIZE(tlsf, b) do{}while(0) |
@@ -105,7 +129,6 @@ | |||
105 | #include <sys/mman.h> | 129 | #include <sys/mman.h> |
106 | #endif | 130 | #endif |
107 | 131 | ||
108 | #include "config.h" | ||
109 | #include "tlsf.h" | 132 | #include "tlsf.h" |
110 | 133 | ||
111 | #if !defined(__GNUC__) | 134 | #if !defined(__GNUC__) |
@@ -127,37 +150,49 @@ | |||
127 | /* Unlike the preview TLSF versions, now they are statics */ | 150 | /* Unlike the preview TLSF versions, now they are statics */ |
128 | #define BLOCK_ALIGN (sizeof(void *) * 2) | 151 | #define BLOCK_ALIGN (sizeof(void *) * 2) |
129 | 152 | ||
130 | #define MAX_FLI (30) | 153 | #define MAX_FLI (30) |
131 | #define MAX_LOG2_SLI (5) | 154 | #define MAX_LOG2_SLI (5) |
132 | #define MAX_SLI (1 << MAX_LOG2_SLI) /* MAX_SLI = 2^MAX_LOG2_SLI */ | 155 | #define MAX_SLI (1 << MAX_LOG2_SLI) /* MAX_SLI = 2^MAX_LOG2_SLI */ |
133 | 156 | ||
134 | #define FLI_OFFSET (6) /* tlsf structure just will manage blocks bigger */ | 157 | #define FLI_OFFSET (6) /* tlsf structure just will manage blocks bigger */ |
135 | /* than 128 bytes */ | 158 | /* than 128 bytes */ |
136 | #define SMALL_BLOCK (128) | 159 | #define SMALL_BLOCK (128) |
137 | #define REAL_FLI (MAX_FLI - FLI_OFFSET) | 160 | #define REAL_FLI (MAX_FLI - FLI_OFFSET) |
138 | #define MIN_BLOCK_SIZE (sizeof (free_ptr_t)) | 161 | #define MIN_BLOCK_SIZE (sizeof (free_ptr_t)) |
139 | #define BHDR_OVERHEAD (sizeof (bhdr_t) - MIN_BLOCK_SIZE) | 162 | #define BHDR_OVERHEAD (sizeof (bhdr_t) - MIN_BLOCK_SIZE) |
140 | #define TLSF_SIGNATURE (0x2A59FA59) | 163 | #define TLSF_SIGNATURE (0x2A59FA59) |
141 | 164 | ||
142 | #define PTR_MASK (sizeof(void *) - 1) | 165 | #define PTR_MASK (sizeof(void *) - 1) |
143 | #define BLOCK_SIZE (0xFFFFFFFF - PTR_MASK) | 166 | #define BLOCK_SIZE (0xFFFFFFFF - PTR_MASK) |
167 | |||
144 | 168 | ||
145 | #define GET_NEXT_BLOCK(_addr, _r) ((bhdr_t *) ((char *) (_addr) + (_r))) | 169 | /* Dereferencing type-punned pointers will break strict aliasing.*/ |
146 | #define MEM_ALIGN ((BLOCK_ALIGN) - 1) | 170 | #ifdef __GNUC__ |
171 | /* GCC guarantees that casting through a union is valid. */ | ||
172 | #define TYPE_PUN(dsttype, srctype, x) \ | ||
173 | (((union {srctype *a; dsttype *b;})(x)).b) | ||
174 | #else | ||
175 | #define TYPE_PUN(dsttype, srctype, x) ( (dsttype*)(x) ) | ||
176 | #endif /* __GNUC__ */ | ||
177 | |||
178 | #define GET_NEXT_BLOCK(_addr, _r) TYPE_PUN(bhdr_t, char, (char *) (_addr) + (_r)) | ||
179 | |||
180 | #define MEM_ALIGN ((BLOCK_ALIGN) - 1) | ||
147 | #define ROUNDUP_SIZE(_r) (((_r) + MEM_ALIGN) & ~MEM_ALIGN) | 181 | #define ROUNDUP_SIZE(_r) (((_r) + MEM_ALIGN) & ~MEM_ALIGN) |
148 | #define ROUNDDOWN_SIZE(_r) ((_r) & ~MEM_ALIGN) | 182 | #define ROUNDDOWN_SIZE(_r) ((_r) & ~MEM_ALIGN) |
149 | #define ROUNDUP(_x, _v) ((((~(_x)) + 1) & ((_v)-1)) + (_x)) | 183 | #define ROUNDUP(_x, _v) ((((~(_x)) + 1) & ((_v)-1)) + (_x)) |
150 | 184 | ||
151 | #define BLOCK_STATE (0x1) | 185 | #define BLOCK_STATE (0x1) |
152 | #define PREV_STATE (0x2) | 186 | #define PREV_STATE (0x2) |
187 | #define STATE_MASK (BLOCK_STATE | PREV_STATE) | ||
153 | 188 | ||
154 | /* bit 0 of the block size */ | 189 | /* bit 0 of the block size */ |
155 | #define FREE_BLOCK (0x1) | 190 | #define FREE_BLOCK (0x1) |
156 | #define USED_BLOCK (0x0) | 191 | #define USED_BLOCK (0x0) |
157 | 192 | ||
158 | /* bit 1 of the block size */ | 193 | /* bit 1 of the block size */ |
159 | #define PREV_FREE (0x2) | 194 | #define PREV_FREE (0x2) |
160 | #define PREV_USED (0x0) | 195 | #define PREV_USED (0x0) |
161 | 196 | ||
162 | 197 | ||
163 | #define DEFAULT_AREA_SIZE (1024*10) | 198 | #define DEFAULT_AREA_SIZE (1024*10) |
@@ -166,14 +201,17 @@ | |||
166 | #define PAGE_SIZE (getpagesize()) | 201 | #define PAGE_SIZE (getpagesize()) |
167 | #endif | 202 | #endif |
168 | 203 | ||
169 | #if defined(ROCKBOX) && (CONFIG_PLATFORM & PLATFORM_HOSTED) && defined(DEBUG) \ | 204 | #if USE_PRINTF |
170 | || !defined(ROCKBOX) | 205 | #include <stdio.h> |
171 | int printf(const char* fmt, ...); | 206 | # define PRINT_MSG(fmt, args...) printf(fmt, ## args) |
172 | #define PRINT_MSG(fmt, args...) printf(fmt, ## args) | 207 | # define ERROR_MSG(fmt, args...) printf(fmt, ## args) |
173 | #define ERROR_MSG(fmt, args...) printf(fmt, ## args) | ||
174 | #else | 208 | #else |
175 | #define PRINT_MSG(fmt, args...) | 209 | # if !defined(PRINT_MSG) |
176 | #define ERROR_MSG(fmt, args...) | 210 | # define PRINT_MSG(fmt, args...) |
211 | # endif | ||
212 | # if !defined(ERROR_MSG) | ||
213 | # define ERROR_MSG(fmt, args...) | ||
214 | # endif | ||
177 | #endif | 215 | #endif |
178 | 216 | ||
179 | typedef unsigned int u32_t; /* NOTE: Make sure that this type is 4 bytes long on your computer */ | 217 | typedef unsigned int u32_t; /* NOTE: Make sure that this type is 4 bytes long on your computer */ |
@@ -236,6 +274,7 @@ typedef struct TLSF_struct { | |||
236 | /******************************************************************/ | 274 | /******************************************************************/ |
237 | /************** Helping functions **************************/ | 275 | /************** Helping functions **************************/ |
238 | /******************************************************************/ | 276 | /******************************************************************/ |
277 | static __inline__ void corrupt(const char *s); | ||
239 | static __inline__ void set_bit(int nr, u32_t * addr); | 278 | static __inline__ void set_bit(int nr, u32_t * addr); |
240 | static __inline__ void clear_bit(int nr, u32_t * addr); | 279 | static __inline__ void clear_bit(int nr, u32_t * addr); |
241 | static __inline__ int ls_bit(int x); | 280 | static __inline__ int ls_bit(int x); |
@@ -248,6 +287,14 @@ static __inline__ bhdr_t *process_area(void *area, size_t size); | |||
248 | static __inline__ void *get_new_area(size_t * size); | 287 | static __inline__ void *get_new_area(size_t * size); |
249 | #endif | 288 | #endif |
250 | 289 | ||
290 | #if defined(ROCKBOX) | ||
291 | void *get_new_area(size_t * size); | ||
292 | #endif | ||
293 | |||
294 | static __inline__ bhdr_t *encode_prev_block( bhdr_t *prev, size_t size ) { | ||
295 | return (bhdr_t*) ( ((intptr_t)prev | STATE_MASK) & ~(size & STATE_MASK) ); | ||
296 | } | ||
297 | |||
251 | static const int table[] = { | 298 | static const int table[] = { |
252 | -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, | 299 | -1, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, |
253 | 4, 4, | 300 | 4, 4, |
@@ -354,22 +401,43 @@ static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl | |||
354 | return _b; | 401 | return _b; |
355 | } | 402 | } |
356 | 403 | ||
404 | #if defined(ROCKBOX) | ||
405 | static __inline__ void corrupt(const char *msg) { | ||
406 | panicf("* Heap Corruption: %s", msg); | ||
407 | } | ||
408 | |||
409 | void __attribute__((weak)) panicf( const char *fmt, ... ) | ||
410 | { | ||
411 | /* Do nothing */ | ||
412 | (void)fmt; | ||
413 | do { } while (1); | ||
414 | } | ||
415 | #else | ||
416 | static __inline__ void corrupt(const char *msg) { | ||
417 | static const char *k = "* Heap corruption detected: *\n"; | ||
418 | write( STDERR_FILENO, k, strlen(k) ); | ||
419 | write( STDERR_FILENO, msg, strlen(msg) ); | ||
420 | abort(); | ||
421 | } | ||
422 | #endif | ||
357 | 423 | ||
358 | #define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) do { \ | 424 | #define EXTRACT_BLOCK_HDR(_b, _tlsf, _fl, _sl) \ |
359 | _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next; \ | 425 | do { \ |
360 | if (_tlsf -> matrix[_fl][_sl]) \ | 426 | _tlsf -> matrix [_fl] [_sl] = _b -> ptr.free_ptr.next; \ |
361 | _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL; \ | 427 | if (_tlsf -> matrix[_fl][_sl]) \ |
362 | else { \ | 428 | _tlsf -> matrix[_fl][_sl] -> ptr.free_ptr.prev = NULL; \ |
363 | clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ | 429 | else { \ |
364 | if (!_tlsf -> sl_bitmap [_fl]) \ | 430 | clear_bit (_sl, &_tlsf -> sl_bitmap [_fl]); \ |
365 | clear_bit (_fl, &_tlsf -> fl_bitmap); \ | 431 | if (!_tlsf -> sl_bitmap [_fl]) \ |
366 | } \ | 432 | clear_bit (_fl, &_tlsf -> fl_bitmap); \ |
367 | _b -> ptr.free_ptr.prev = NULL; \ | 433 | } \ |
368 | _b -> ptr.free_ptr.next = NULL; \ | 434 | _b -> ptr.free_ptr.prev = NULL; \ |
435 | _b -> ptr.free_ptr.next = NULL; \ | ||
369 | }while(0) | 436 | }while(0) |
370 | 437 | ||
371 | 438 | ||
372 | #define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) do { \ | 439 | #define EXTRACT_BLOCK(_b, _tlsf, _fl, _sl) \ |
440 | do { \ | ||
373 | if (_b -> ptr.free_ptr.next) \ | 441 | if (_b -> ptr.free_ptr.next) \ |
374 | _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \ | 442 | _b -> ptr.free_ptr.next -> ptr.free_ptr.prev = _b -> ptr.free_ptr.prev; \ |
375 | if (_b -> ptr.free_ptr.prev) \ | 443 | if (_b -> ptr.free_ptr.prev) \ |
@@ -382,13 +450,14 @@ static __inline__ bhdr_t *FIND_SUITABLE_BLOCK(tlsf_t * _tlsf, int *_fl, int *_sl | |||
382 | clear_bit (_fl, &_tlsf -> fl_bitmap); \ | 450 | clear_bit (_fl, &_tlsf -> fl_bitmap); \ |
383 | } \ | 451 | } \ |
384 | } \ | 452 | } \ |
385 | _b -> ptr.free_ptr.prev = NULL; \ | 453 | _b -> ptr.free_ptr.prev = NULL; \ |
386 | _b -> ptr.free_ptr.next = NULL; \ | 454 | _b -> ptr.free_ptr.next = NULL; \ |
387 | } while(0) | 455 | } while(0) |
388 | 456 | ||
389 | #define INSERT_BLOCK(_b, _tlsf, _fl, _sl) do { \ | 457 | #define INSERT_BLOCK(_b, _tlsf, _fl, _sl) \ |
390 | _b -> ptr.free_ptr.prev = NULL; \ | 458 | do { \ |
391 | _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \ | 459 | _b -> ptr.free_ptr.prev = NULL; \ |
460 | _b -> ptr.free_ptr.next = _tlsf -> matrix [_fl][_sl]; \ | ||
392 | if (_tlsf -> matrix [_fl][_sl]) \ | 461 | if (_tlsf -> matrix [_fl][_sl]) \ |
393 | _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b; \ | 462 | _tlsf -> matrix [_fl][_sl] -> ptr.free_ptr.prev = _b; \ |
394 | _tlsf -> matrix [_fl][_sl] = _b; \ | 463 | _tlsf -> matrix [_fl][_sl] = _b; \ |
@@ -405,7 +474,7 @@ void * __attribute__((weak)) get_new_area(size_t * size) | |||
405 | #endif | 474 | #endif |
406 | 475 | ||
407 | #if USE_SBRK || USE_MMAP | 476 | #if USE_SBRK || USE_MMAP |
408 | static __inline__ void *get_new_area(size_t * size) | 477 | static __inline__ void *get_new_area(size_t * size) |
409 | { | 478 | { |
410 | void *area; | 479 | void *area; |
411 | 480 | ||
@@ -415,12 +484,18 @@ static __inline__ void *get_new_area(size_t * size) | |||
415 | return area; | 484 | return area; |
416 | #endif | 485 | #endif |
417 | 486 | ||
487 | #ifndef MAP_ANONYMOUS | ||
488 | /* https://dev.openwrt.org/ticket/322 */ | ||
489 | # define MAP_ANONYMOUS MAP_ANON | ||
490 | #endif | ||
491 | |||
492 | |||
418 | #if USE_MMAP | 493 | #if USE_MMAP |
419 | *size = ROUNDUP(*size, PAGE_SIZE); | 494 | *size = ROUNDUP(*size, PAGE_SIZE); |
420 | if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) | 495 | if ((area = mmap(0, *size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED) |
421 | return area; | 496 | return area; |
422 | #endif | 497 | #endif |
423 | return ((void *) ~0); | 498 | return ((void *) ~0u); |
424 | } | 499 | } |
425 | #endif | 500 | #endif |
426 | 501 | ||
@@ -433,13 +508,15 @@ static __inline__ bhdr_t *process_area(void *area, size_t size) | |||
433 | ib->size = | 508 | ib->size = |
434 | (sizeof(area_info_t) < | 509 | (sizeof(area_info_t) < |
435 | MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(sizeof(area_info_t)) | USED_BLOCK | PREV_USED; | 510 | MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(sizeof(area_info_t)) | USED_BLOCK | PREV_USED; |
436 | b = (bhdr_t *) GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE); | 511 | ib->prev_hdr = encode_prev_block( NULL, ib->size ); |
512 | b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE); | ||
437 | b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED; | 513 | b->size = ROUNDDOWN_SIZE(size - 3 * BHDR_OVERHEAD - (ib->size & BLOCK_SIZE)) | USED_BLOCK | PREV_USED; |
514 | b->prev_hdr = encode_prev_block( NULL, b->size ); | ||
438 | b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0; | 515 | b->ptr.free_ptr.prev = b->ptr.free_ptr.next = 0; |
439 | lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); | 516 | lb = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); |
440 | lb->prev_hdr = b; | ||
441 | lb->size = 0 | USED_BLOCK | PREV_FREE; | 517 | lb->size = 0 | USED_BLOCK | PREV_FREE; |
442 | ai = (area_info_t *) ib->ptr.buffer; | 518 | lb->prev_hdr = encode_prev_block( b, lb->size ); |
519 | ai = TYPE_PUN(area_info_t, u8_t, ib->ptr.buffer); | ||
443 | ai->next = 0; | 520 | ai->next = 0; |
444 | ai->end = lb; | 521 | ai->end = lb; |
445 | return ib; | 522 | return ib; |
@@ -463,7 +540,7 @@ size_t init_memory_pool(size_t mem_pool_size, void *mem_pool) | |||
463 | return -1; | 540 | return -1; |
464 | } | 541 | } |
465 | 542 | ||
466 | if (((intptr_t) mem_pool & PTR_MASK)) { | 543 | if (((unsigned long) mem_pool & PTR_MASK)) { |
467 | ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n"); | 544 | ERROR_MSG("init_memory_pool (): mem_pool must be aligned to a word\n"); |
468 | return -1; | 545 | return -1; |
469 | } | 546 | } |
@@ -488,7 +565,7 @@ size_t init_memory_pool(size_t mem_pool_size, void *mem_pool) | |||
488 | (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t))); | 565 | (mem_pool, ROUNDUP_SIZE(sizeof(tlsf_t))), ROUNDDOWN_SIZE(mem_pool_size - sizeof(tlsf_t))); |
489 | b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE); | 566 | b = GET_NEXT_BLOCK(ib->ptr.buffer, ib->size & BLOCK_SIZE); |
490 | free_ex(b->ptr.buffer, tlsf); | 567 | free_ex(b->ptr.buffer, tlsf); |
491 | tlsf->area_head = (area_info_t *) ib->ptr.buffer; | 568 | tlsf->area_head = TYPE_PUN(area_info_t, u8_t, ib->ptr.buffer); |
492 | 569 | ||
493 | #if TLSF_STATISTIC | 570 | #if TLSF_STATISTIC |
494 | tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE); | 571 | tlsf->used_size = mem_pool_size - (b->size & BLOCK_SIZE); |
@@ -506,9 +583,6 @@ size_t add_new_area(void *area, size_t area_size, void *mem_pool) | |||
506 | area_info_t *ptr, *ptr_prev, *ai; | 583 | area_info_t *ptr, *ptr_prev, *ai; |
507 | bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b; | 584 | bhdr_t *ib0, *b0, *lb0, *ib1, *b1, *lb1, *next_b; |
508 | 585 | ||
509 | /* FW 28-10-17: disabled memset due to crashes on ARM. Functions | ||
510 | * fine without it. */ | ||
511 | /* BILGUS 17-7-19 re-enabled after setting pluginbuf aligned to 8 bytes */ | ||
512 | memset(area, 0, area_size); | 586 | memset(area, 0, area_size); |
513 | ptr = tlsf->area_head; | 587 | ptr = tlsf->area_head; |
514 | ptr_prev = 0; | 588 | ptr_prev = 0; |
@@ -526,7 +600,7 @@ size_t add_new_area(void *area, size_t area_size, void *mem_pool) | |||
526 | lb1 = ptr->end; | 600 | lb1 = ptr->end; |
527 | 601 | ||
528 | /* Merging the new area with the next physically contigous one */ | 602 | /* Merging the new area with the next physically contigous one */ |
529 | if ((uintptr_t) ib1 == (uintptr_t) lb0 + BHDR_OVERHEAD) { | 603 | if ((unsigned long) ib1 == (unsigned long) lb0 + BHDR_OVERHEAD) { |
530 | if (tlsf->area_head == ptr) { | 604 | if (tlsf->area_head == ptr) { |
531 | tlsf->area_head = ptr->next; | 605 | tlsf->area_head = ptr->next; |
532 | ptr = ptr->next; | 606 | ptr = ptr->next; |
@@ -539,7 +613,7 @@ size_t add_new_area(void *area, size_t area_size, void *mem_pool) | |||
539 | ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) + | 613 | ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) + |
540 | (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED; | 614 | (ib1->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | PREV_USED; |
541 | 615 | ||
542 | b1->prev_hdr = b0; | 616 | b1->prev_hdr = encode_prev_block( b0, b0->size ); |
543 | lb0 = lb1; | 617 | lb0 = lb1; |
544 | 618 | ||
545 | continue; | 619 | continue; |
@@ -547,7 +621,7 @@ size_t add_new_area(void *area, size_t area_size, void *mem_pool) | |||
547 | 621 | ||
548 | /* Merging the new area with the previous physically contigous | 622 | /* Merging the new area with the previous physically contigous |
549 | one */ | 623 | one */ |
550 | if ((intptr_t) lb1->ptr.buffer == (intptr_t) ib0) { | 624 | if ((unsigned long) lb1->ptr.buffer == (unsigned long) ib0) { |
551 | if (tlsf->area_head == ptr) { | 625 | if (tlsf->area_head == ptr) { |
552 | tlsf->area_head = ptr->next; | 626 | tlsf->area_head = ptr->next; |
553 | ptr = ptr->next; | 627 | ptr = ptr->next; |
@@ -560,7 +634,7 @@ size_t add_new_area(void *area, size_t area_size, void *mem_pool) | |||
560 | ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) + | 634 | ROUNDDOWN_SIZE((b0->size & BLOCK_SIZE) + |
561 | (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE); | 635 | (ib0->size & BLOCK_SIZE) + 2 * BHDR_OVERHEAD) | USED_BLOCK | (lb1->size & PREV_STATE); |
562 | next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE); | 636 | next_b = GET_NEXT_BLOCK(lb1->ptr.buffer, lb1->size & BLOCK_SIZE); |
563 | next_b->prev_hdr = lb1; | 637 | next_b->prev_hdr = encode_prev_block( lb1, next_b->size ); |
564 | b0 = lb1; | 638 | b0 = lb1; |
565 | ib0 = ib1; | 639 | ib0 = ib1; |
566 | 640 | ||
@@ -571,7 +645,7 @@ size_t add_new_area(void *area, size_t area_size, void *mem_pool) | |||
571 | } | 645 | } |
572 | 646 | ||
573 | /* Inserting the area in the list of linked areas */ | 647 | /* Inserting the area in the list of linked areas */ |
574 | ai = (area_info_t *) ib0->ptr.buffer; | 648 | ai = TYPE_PUN(area_info_t, u8_t, ib0->ptr.buffer); |
575 | ai->next = tlsf->area_head; | 649 | ai->next = tlsf->area_head; |
576 | ai->end = lb0; | 650 | ai->end = lb0; |
577 | tlsf->area_head = ai; | 651 | tlsf->area_head = ai; |
@@ -587,9 +661,7 @@ size_t get_used_size(void *mem_pool) | |||
587 | #if TLSF_STATISTIC | 661 | #if TLSF_STATISTIC |
588 | return ((tlsf_t *) mem_pool)->used_size; | 662 | return ((tlsf_t *) mem_pool)->used_size; |
589 | #else | 663 | #else |
590 | #ifdef ROCKBOX | 664 | (void)mem_pool; |
591 | (void) mem_pool; | ||
592 | #endif /* ROCKBOX */ | ||
593 | return 0; | 665 | return 0; |
594 | #endif | 666 | #endif |
595 | } | 667 | } |
@@ -601,9 +673,7 @@ size_t get_max_size(void *mem_pool) | |||
601 | #if TLSF_STATISTIC | 673 | #if TLSF_STATISTIC |
602 | return ((tlsf_t *) mem_pool)->max_size; | 674 | return ((tlsf_t *) mem_pool)->max_size; |
603 | #else | 675 | #else |
604 | #ifdef ROCKBOX | 676 | (void)mem_pool; |
605 | (void) mem_pool; | ||
606 | #endif /* ROCKBOX */ | ||
607 | return 0; | 677 | return 0; |
608 | #endif | 678 | #endif |
609 | } | 679 | } |
@@ -635,7 +705,7 @@ void *tlsf_malloc(size_t size) | |||
635 | area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */ | 705 | area_size = sizeof(tlsf_t) + BHDR_OVERHEAD * 8; /* Just a safety constant */ |
636 | area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE; | 706 | area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE; |
637 | area = get_new_area(&area_size); | 707 | area = get_new_area(&area_size); |
638 | if (area == ((void *) ~0)) | 708 | if (area == ((void *) ~0u)) |
639 | return NULL; /* Not enough system memory */ | 709 | return NULL; /* Not enough system memory */ |
640 | init_memory_pool(area_size, area); | 710 | init_memory_pool(area_size, area); |
641 | } | 711 | } |
@@ -670,9 +740,9 @@ void *tlsf_realloc(void *ptr, size_t size) | |||
670 | void *ret; | 740 | void *ret; |
671 | 741 | ||
672 | #if USE_MMAP || USE_SBRK || defined(ROCKBOX) | 742 | #if USE_MMAP || USE_SBRK || defined(ROCKBOX) |
673 | if (!mp) { | 743 | if (!mp) { |
674 | return tlsf_malloc(size); | 744 | return tlsf_malloc(size); |
675 | } | 745 | } |
676 | #endif | 746 | #endif |
677 | 747 | ||
678 | TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock); | 748 | TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock); |
@@ -716,7 +786,6 @@ void *malloc_ex(size_t size, void *mem_pool) | |||
716 | /* Searching a free block, recall that this function changes the values of fl and sl, | 786 | /* Searching a free block, recall that this function changes the values of fl and sl, |
717 | so they are not longer valid when the function fails */ | 787 | so they are not longer valid when the function fails */ |
718 | b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl); | 788 | b = FIND_SUITABLE_BLOCK(tlsf, &fl, &sl); |
719 | |||
720 | #if USE_MMAP || USE_SBRK || defined(ROCKBOX) | 789 | #if USE_MMAP || USE_SBRK || defined(ROCKBOX) |
721 | if (!b) { | 790 | if (!b) { |
722 | size_t area_size; | 791 | size_t area_size; |
@@ -725,7 +794,7 @@ void *malloc_ex(size_t size, void *mem_pool) | |||
725 | area_size = size + BHDR_OVERHEAD * 8; /* size plus enough room for the requered headers. */ | 794 | area_size = size + BHDR_OVERHEAD * 8; /* size plus enough room for the requered headers. */ |
726 | area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE; | 795 | area_size = (area_size > DEFAULT_AREA_SIZE) ? area_size : DEFAULT_AREA_SIZE; |
727 | area = get_new_area(&area_size); /* Call sbrk or mmap */ | 796 | area = get_new_area(&area_size); /* Call sbrk or mmap */ |
728 | if (area == ((void *) ~0)) | 797 | if (area == ((void *) ~0u)) |
729 | return NULL; /* Not enough system memory */ | 798 | return NULL; /* Not enough system memory */ |
730 | add_new_area(area, area_size, mem_pool); | 799 | add_new_area(area, area_size, mem_pool); |
731 | /* Rounding up the requested size and calculating fl and sl */ | 800 | /* Rounding up the requested size and calculating fl and sl */ |
@@ -747,18 +816,24 @@ void *malloc_ex(size_t size, void *mem_pool) | |||
747 | tmp_size -= BHDR_OVERHEAD; | 816 | tmp_size -= BHDR_OVERHEAD; |
748 | b2 = GET_NEXT_BLOCK(b->ptr.buffer, size); | 817 | b2 = GET_NEXT_BLOCK(b->ptr.buffer, size); |
749 | b2->size = tmp_size | FREE_BLOCK | PREV_USED; | 818 | b2->size = tmp_size | FREE_BLOCK | PREV_USED; |
750 | next_b->prev_hdr = b2; | 819 | b2->prev_hdr = encode_prev_block( b2->prev_hdr, b2->size ); |
820 | next_b->prev_hdr = encode_prev_block(b2, next_b->size); | ||
751 | MAPPING_INSERT(tmp_size, &fl, &sl); | 821 | MAPPING_INSERT(tmp_size, &fl, &sl); |
752 | INSERT_BLOCK(b2, tlsf, fl, sl); | 822 | INSERT_BLOCK(b2, tlsf, fl, sl); |
753 | 823 | ||
754 | b->size = size | (b->size & PREV_STATE); | 824 | b->size = size | (b->size & PREV_STATE); |
755 | } else { | 825 | } else { |
756 | next_b->size &= (~PREV_FREE); | 826 | next_b->size &= (~PREV_FREE); |
827 | next_b->prev_hdr = encode_prev_block( next_b->prev_hdr, next_b->size ); | ||
757 | b->size &= (~FREE_BLOCK); /* Now it's used */ | 828 | b->size &= (~FREE_BLOCK); /* Now it's used */ |
758 | } | 829 | } |
830 | b->prev_hdr = encode_prev_block( b->prev_hdr, b->size ); | ||
759 | 831 | ||
760 | TLSF_ADD_SIZE(tlsf, b); | 832 | TLSF_ADD_SIZE(tlsf, b); |
761 | 833 | ||
834 | if( (b->size & BLOCK_STATE) != (~(intptr_t)b->prev_hdr & BLOCK_STATE) ) | ||
835 | corrupt("malloc_ex(): Mismatched flags after allocation\n"); | ||
836 | |||
762 | return (void *) b->ptr.buffer; | 837 | return (void *) b->ptr.buffer; |
763 | } | 838 | } |
764 | 839 | ||
@@ -773,7 +848,14 @@ void free_ex(void *ptr, void *mem_pool) | |||
773 | if (!ptr) { | 848 | if (!ptr) { |
774 | return; | 849 | return; |
775 | } | 850 | } |
851 | |||
776 | b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD); | 852 | b = (bhdr_t *) ((char *) ptr - BHDR_OVERHEAD); |
853 | |||
854 | if( (b->size & BLOCK_STATE) != USED_BLOCK ) | ||
855 | corrupt( "free_ex(): Freeing unused block\n" ); | ||
856 | if( (b->size & BLOCK_STATE) != (~(intptr_t)b->prev_hdr & BLOCK_STATE) ) | ||
857 | corrupt("free_ex(): Mismatched flags\n"); | ||
858 | |||
777 | b->size |= FREE_BLOCK; | 859 | b->size |= FREE_BLOCK; |
778 | 860 | ||
779 | TLSF_REMOVE_SIZE(tlsf, b); | 861 | TLSF_REMOVE_SIZE(tlsf, b); |
@@ -782,12 +864,14 @@ void free_ex(void *ptr, void *mem_pool) | |||
782 | b->ptr.free_ptr.next = NULL; | 864 | b->ptr.free_ptr.next = NULL; |
783 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); | 865 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); |
784 | if (tmp_b->size & FREE_BLOCK) { | 866 | if (tmp_b->size & FREE_BLOCK) { |
867 | /* Coalesce next block */ | ||
785 | MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl); | 868 | MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl); |
786 | EXTRACT_BLOCK(tmp_b, tlsf, fl, sl); | 869 | EXTRACT_BLOCK(tmp_b, tlsf, fl, sl); |
787 | b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; | 870 | b->size += (tmp_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; |
788 | } | 871 | } |
789 | if (b->size & PREV_FREE) { | 872 | if (b->size & PREV_FREE) { |
790 | tmp_b = b->prev_hdr; | 873 | /* Coalesce previous block */ |
874 | tmp_b = (bhdr_t*) ( (intptr_t)b->prev_hdr & BLOCK_SIZE ); | ||
791 | MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl); | 875 | MAPPING_INSERT(tmp_b->size & BLOCK_SIZE, &fl, &sl); |
792 | EXTRACT_BLOCK(tmp_b, tlsf, fl, sl); | 876 | EXTRACT_BLOCK(tmp_b, tlsf, fl, sl); |
793 | tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; | 877 | tmp_b->size += (b->size & BLOCK_SIZE) + BHDR_OVERHEAD; |
@@ -797,8 +881,11 @@ void free_ex(void *ptr, void *mem_pool) | |||
797 | INSERT_BLOCK(b, tlsf, fl, sl); | 881 | INSERT_BLOCK(b, tlsf, fl, sl); |
798 | 882 | ||
799 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); | 883 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); |
884 | /* if tmp_b is free, it should have been coalesced */ | ||
885 | if( (tmp_b->size & BLOCK_STATE) == FREE_BLOCK ) | ||
886 | corrupt( "free_ex(): uncoalesced block\n"); | ||
800 | tmp_b->size |= PREV_FREE; | 887 | tmp_b->size |= PREV_FREE; |
801 | tmp_b->prev_hdr = b; | 888 | tmp_b->prev_hdr = encode_prev_block(b, tmp_b->size); |
802 | } | 889 | } |
803 | 890 | ||
804 | /******************************************************************/ | 891 | /******************************************************************/ |
@@ -827,8 +914,10 @@ void *realloc_ex(void *ptr, size_t new_size, void *mem_pool) | |||
827 | new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size); | 914 | new_size = (new_size < MIN_BLOCK_SIZE) ? MIN_BLOCK_SIZE : ROUNDUP_SIZE(new_size); |
828 | tmp_size = (b->size & BLOCK_SIZE); | 915 | tmp_size = (b->size & BLOCK_SIZE); |
829 | if (new_size <= tmp_size) { | 916 | if (new_size <= tmp_size) { |
830 | TLSF_REMOVE_SIZE(tlsf, b); | 917 | /* shrink allocated portion */ |
918 | TLSF_REMOVE_SIZE(tlsf, b); | ||
831 | if (next_b->size & FREE_BLOCK) { | 919 | if (next_b->size & FREE_BLOCK) { |
920 | /* coalesce next block (free) */ | ||
832 | MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl); | 921 | MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl); |
833 | EXTRACT_BLOCK(next_b, tlsf, fl, sl); | 922 | EXTRACT_BLOCK(next_b, tlsf, fl, sl); |
834 | tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; | 923 | tmp_size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; |
@@ -838,45 +927,49 @@ void *realloc_ex(void *ptr, size_t new_size, void *mem_pool) | |||
838 | } | 927 | } |
839 | tmp_size -= new_size; | 928 | tmp_size -= new_size; |
840 | if (tmp_size >= sizeof(bhdr_t)) { | 929 | if (tmp_size >= sizeof(bhdr_t)) { |
930 | /* add tail as free block */ | ||
841 | tmp_size -= BHDR_OVERHEAD; | 931 | tmp_size -= BHDR_OVERHEAD; |
842 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size); | 932 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size); |
843 | tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED; | 933 | tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED; |
844 | next_b->prev_hdr = tmp_b; | 934 | tmp_b->prev_hdr = encode_prev_block( NULL, tmp_b->size ); |
845 | next_b->size |= PREV_FREE; | 935 | next_b->size |= PREV_FREE; |
936 | next_b->prev_hdr = encode_prev_block( tmp_b, next_b->size ); | ||
846 | MAPPING_INSERT(tmp_size, &fl, &sl); | 937 | MAPPING_INSERT(tmp_size, &fl, &sl); |
847 | INSERT_BLOCK(tmp_b, tlsf, fl, sl); | 938 | INSERT_BLOCK(tmp_b, tlsf, fl, sl); |
848 | b->size = new_size | (b->size & PREV_STATE); | 939 | b->size = new_size | (b->size & PREV_STATE); |
849 | } | 940 | } |
850 | TLSF_ADD_SIZE(tlsf, b); | 941 | TLSF_ADD_SIZE(tlsf, b); |
851 | return (void *) b->ptr.buffer; | 942 | return (void *) b->ptr.buffer; |
852 | } | 943 | } |
853 | if ((next_b->size & FREE_BLOCK)) { | 944 | if ((next_b->size & FREE_BLOCK)) { |
854 | if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) { | 945 | if (new_size <= (tmp_size + (next_b->size & BLOCK_SIZE))) { |
946 | /* allocate out of next block */ | ||
855 | TLSF_REMOVE_SIZE(tlsf, b); | 947 | TLSF_REMOVE_SIZE(tlsf, b); |
856 | MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl); | 948 | MAPPING_INSERT(next_b->size & BLOCK_SIZE, &fl, &sl); |
857 | EXTRACT_BLOCK(next_b, tlsf, fl, sl); | 949 | EXTRACT_BLOCK(next_b, tlsf, fl, sl); |
858 | b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; | 950 | b->size += (next_b->size & BLOCK_SIZE) + BHDR_OVERHEAD; |
859 | next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); | 951 | next_b = GET_NEXT_BLOCK(b->ptr.buffer, b->size & BLOCK_SIZE); |
860 | next_b->prev_hdr = b; | ||
861 | next_b->size &= ~PREV_FREE; | 952 | next_b->size &= ~PREV_FREE; |
953 | next_b->prev_hdr = encode_prev_block( b, next_b->size ); | ||
862 | tmp_size = (b->size & BLOCK_SIZE) - new_size; | 954 | tmp_size = (b->size & BLOCK_SIZE) - new_size; |
863 | if (tmp_size >= sizeof(bhdr_t)) { | 955 | if (tmp_size >= sizeof(bhdr_t)) { |
864 | tmp_size -= BHDR_OVERHEAD; | 956 | tmp_size -= BHDR_OVERHEAD; |
865 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size); | 957 | tmp_b = GET_NEXT_BLOCK(b->ptr.buffer, new_size); |
866 | tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED; | 958 | tmp_b->size = tmp_size | FREE_BLOCK | PREV_USED; |
867 | next_b->prev_hdr = tmp_b; | ||
868 | next_b->size |= PREV_FREE; | 959 | next_b->size |= PREV_FREE; |
960 | next_b->prev_hdr = encode_prev_block(tmp_b, next_b->size); | ||
869 | MAPPING_INSERT(tmp_size, &fl, &sl); | 961 | MAPPING_INSERT(tmp_size, &fl, &sl); |
870 | INSERT_BLOCK(tmp_b, tlsf, fl, sl); | 962 | INSERT_BLOCK(tmp_b, tlsf, fl, sl); |
871 | b->size = new_size | (b->size & PREV_STATE); | 963 | b->size = new_size | (b->size & PREV_STATE); |
872 | } | 964 | } |
873 | TLSF_ADD_SIZE(tlsf, b); | 965 | TLSF_ADD_SIZE(tlsf, b); |
874 | return (void *) b->ptr.buffer; | 966 | return (void *) b->ptr.buffer; |
875 | } | 967 | } |
876 | } | 968 | } |
877 | 969 | ||
878 | if (!(ptr_aux = malloc_ex(new_size, mem_pool))) | 970 | if (!(ptr_aux = malloc_ex(new_size, mem_pool))){ |
879 | return NULL; | 971 | return NULL; |
972 | } | ||
880 | 973 | ||
881 | cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE); | 974 | cpsize = ((b->size & BLOCK_SIZE) > new_size) ? new_size : (b->size & BLOCK_SIZE); |
882 | 975 | ||
@@ -971,7 +1064,7 @@ void print_block(bhdr_t * b) | |||
971 | else | 1064 | else |
972 | PRINT_MSG("used, "); | 1065 | PRINT_MSG("used, "); |
973 | if ((b->size & PREV_STATE) == PREV_FREE) | 1066 | if ((b->size & PREV_STATE) == PREV_FREE) |
974 | PRINT_MSG("prev. free [%p])\n", b->prev_hdr); | 1067 | PRINT_MSG("prev. free [%p])\n", b->prev_hdr & BLOCK_SIZE); |
975 | else | 1068 | else |
976 | PRINT_MSG("prev used)\n"); | 1069 | PRINT_MSG("prev used)\n"); |
977 | } | 1070 | } |
diff --git a/lib/tlsf/src/tlsf.h b/lib/tlsf/src/tlsf.h index 4feb5c42cc..29ffb7fcfb 100644 --- a/lib/tlsf/src/tlsf.h +++ b/lib/tlsf/src/tlsf.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * Two Levels Segregate Fit memory allocator (TLSF) | 2 | * Two Levels Segregate Fit memory allocator (TLSF) |
3 | * Version 2.4.4 | 3 | * Version 2.4.6 |
4 | * | 4 | * |
5 | * Written by Miguel Masmano Tello <mimastel@doctor.upv.es> | 5 | * Written by Miguel Masmano Tello <mimastel@doctor.upv.es> |
6 | * | 6 | * |
@@ -19,7 +19,7 @@ | |||
19 | #ifndef _TLSF_H_ | 19 | #ifndef _TLSF_H_ |
20 | #define _TLSF_H_ | 20 | #define _TLSF_H_ |
21 | 21 | ||
22 | #include <string.h> /* defines size_t */ | 22 | #include <sys/types.h> |
23 | 23 | ||
24 | extern size_t init_memory_pool(size_t, void *); | 24 | extern size_t init_memory_pool(size_t, void *); |
25 | extern size_t get_used_size(void *); | 25 | extern size_t get_used_size(void *); |