1
1
#include "tinyalloc.h"
2
+
2
3
#include <stdint.h>
3
4
4
5
#ifdef TA_DEBUG
@@ -30,19 +31,13 @@ typedef struct {
30
31
size_t top ; // top free addr
31
32
} Heap ;
32
33
33
- static Heap * heap = NULL ;
34
- static const void * heap_limit = NULL ;
35
- static size_t heap_split_thresh ;
36
- static size_t heap_alignment ;
37
- static size_t heap_max_blocks ;
38
-
39
34
/**
40
35
* If compaction is enabled, inserts block
41
36
* into free list, sorted by addr.
42
37
* If disabled, add block has new head of
43
38
* the free list.
44
39
*/
45
- static void insert_block (Block * block ) {
40
+ static void insert_block (Heap * heap , Block * block ) {
46
41
#ifndef TA_DISABLE_COMPACT
47
42
Block * ptr = heap -> free ;
48
43
Block * prev = NULL ;
@@ -72,7 +67,7 @@ static void insert_block(Block *block) {
72
67
}
73
68
74
69
#ifndef TA_DISABLE_COMPACT
75
- static void release_blocks (Block * scan , Block * to ) {
70
+ static void release_blocks (Heap * heap , Block * scan , Block * to ) {
76
71
Block * scan_next ;
77
72
while (scan != to ) {
78
73
print_s ("release" );
@@ -86,7 +81,7 @@ static void release_blocks(Block *scan, Block *to) {
86
81
}
87
82
}
88
83
89
- static void compact () {
84
+ static void compact (Heap * heap ) {
90
85
Block * ptr = heap -> free ;
91
86
Block * prev ;
92
87
Block * scan ;
@@ -108,7 +103,7 @@ static void compact() {
108
103
ptr -> size = new_size ;
109
104
Block * next = prev -> next ;
110
105
// make merged blocks available
111
- release_blocks (ptr -> next , prev -> next );
106
+ release_blocks (heap , ptr -> next , prev -> next );
112
107
// relink
113
108
ptr -> next = next ;
114
109
}
@@ -117,32 +112,27 @@ static void compact() {
117
112
}
118
113
#endif
119
114
120
- bool ta_init (const void * base , const void * limit , const size_t heap_blocks , const size_t split_thresh , const size_t alignment ) {
121
- heap = (Heap * )base ;
122
- heap_limit = limit ;
123
- heap_split_thresh = split_thresh ;
124
- heap_alignment = alignment ;
125
- heap_max_blocks = heap_blocks ;
126
-
127
- heap -> free = NULL ;
128
- heap -> used = NULL ;
129
- heap -> fresh = (Block * )(heap + 1 );
130
- heap -> top = (size_t )(heap -> fresh + heap_blocks );
115
+ void ta_init (const ta_cfg_t * cfg ) {
116
+ Heap * heap = (Heap * )cfg -> base ;
117
+ heap -> free = NULL ;
118
+ heap -> used = NULL ;
119
+ heap -> fresh = (Block * )(heap + 1 );
120
+ heap -> top = (size_t )(heap -> fresh + cfg -> max_blocks );
131
121
132
122
Block * block = heap -> fresh ;
133
- size_t i = heap_max_blocks - 1 ;
123
+ size_t i = cfg -> max_blocks - 1 ;
134
124
while (i -- ) {
135
125
block -> next = block + 1 ;
136
126
block ++ ;
137
127
}
138
128
block -> next = NULL ;
139
- return true;
140
129
}
141
130
142
- bool ta_free (void * free ) {
131
+ bool ta_free (const ta_cfg_t * cfg , void * free ) {
143
132
if (free == NULL ) {
144
133
return false;
145
134
}
135
+ Heap * heap = (Heap * )cfg -> base ;
146
136
Block * block = heap -> used ;
147
137
Block * prev = NULL ;
148
138
while (block != NULL ) {
@@ -152,9 +142,9 @@ bool ta_free(void *free) {
152
142
} else {
153
143
heap -> used = block -> next ;
154
144
}
155
- insert_block (block );
145
+ insert_block (heap , block );
156
146
#ifndef TA_DISABLE_COMPACT
157
- compact ();
147
+ compact (heap );
158
148
#endif
159
149
return true;
160
150
}
@@ -164,17 +154,19 @@ bool ta_free(void *free) {
164
154
return false;
165
155
}
166
156
167
- static Block * alloc_block (size_t num ) {
157
+ static Block * alloc_block (const ta_cfg_t * cfg , size_t num ) {
158
+ Heap * heap = (Heap * )cfg -> base ;
168
159
Block * ptr = heap -> free ;
169
160
Block * prev = NULL ;
170
161
size_t top = heap -> top ;
171
162
size_t orig = num ;
172
- num = (num + heap_alignment - 1 ) & - heap_alignment ;
163
+ num = (num + cfg -> alignment - 1 ) & - cfg -> alignment ;
173
164
if (num < orig ) {
174
165
return NULL ; // overflow
175
166
}
176
167
while (ptr != NULL ) {
177
- const int is_top = ((size_t )ptr -> addr + ptr -> size >= top ) && ((size_t )ptr -> addr + num <= (size_t )heap_limit );
168
+ const int is_top = ((size_t )ptr -> addr + ptr -> size >= top ) &&
169
+ ((size_t )ptr -> addr + num <= (size_t )cfg -> limit );
178
170
if (is_top || ptr -> size >= num ) {
179
171
if (prev != NULL ) {
180
172
prev -> next = ptr -> next ;
@@ -190,17 +182,17 @@ static Block *alloc_block(size_t num) {
190
182
#ifndef TA_DISABLE_SPLIT
191
183
} else if (heap -> fresh != NULL ) {
192
184
size_t excess = ptr -> size - num ;
193
- if (excess >= heap_split_thresh ) {
185
+ if (excess >= cfg -> split_thresh ) {
194
186
ptr -> size = num ;
195
187
Block * split = heap -> fresh ;
196
188
heap -> fresh = split -> next ;
197
189
split -> addr = (void * )((size_t )ptr -> addr + num );
198
190
print_s ("split" );
199
191
print_i ((size_t )split -> addr );
200
192
split -> size = excess ;
201
- insert_block (split );
193
+ insert_block (heap , split );
202
194
#ifndef TA_DISABLE_COMPACT
203
- compact ();
195
+ compact (heap );
204
196
#endif
205
197
}
206
198
#endif
@@ -213,7 +205,7 @@ static Block *alloc_block(size_t num) {
213
205
// no matching free blocks
214
206
// see if any other blocks available
215
207
size_t new_top = top + num ;
216
- if (heap -> fresh != NULL && new_top <= (size_t )heap_limit ) {
208
+ if (heap -> fresh != NULL && new_top <= (size_t )cfg -> limit ) {
217
209
ptr = heap -> fresh ;
218
210
heap -> fresh = ptr -> next ;
219
211
ptr -> addr = (void * )top ;
@@ -226,8 +218,8 @@ static Block *alloc_block(size_t num) {
226
218
return NULL ;
227
219
}
228
220
229
- void * ta_alloc (size_t num ) {
230
- Block * block = alloc_block (num );
221
+ void * ta_alloc (const ta_cfg_t * cfg , size_t num ) {
222
+ Block * block = alloc_block (cfg , num );
231
223
if (block != NULL ) {
232
224
return block -> addr ;
233
225
}
@@ -254,13 +246,13 @@ static void memclear(void *ptr, size_t num) {
254
246
}
255
247
#endif
256
248
257
- void * ta_calloc (size_t num , size_t size ) {
249
+ void * ta_calloc (const ta_cfg_t * cfg , size_t num , size_t size ) {
258
250
size_t orig = num ;
259
251
num *= size ;
260
252
if (size != 0 && num / size != orig ) {
261
253
goto overflow ;
262
254
}
263
- Block * block = alloc_block (num );
255
+ Block * block = alloc_block (cfg , num );
264
256
if (block != NULL ) {
265
257
memclear (block -> addr , block -> size );
266
258
return block -> addr ;
@@ -281,26 +273,31 @@ static size_t count_blocks(Block *ptr) {
281
273
return num ;
282
274
}
283
275
284
- size_t ta_num_free () {
276
+ size_t ta_num_free (const ta_cfg_t * cfg ) {
277
+ Heap * heap = (Heap * )cfg -> base ;
285
278
return count_blocks (heap -> free );
286
279
}
287
280
288
- size_t ta_num_used () {
281
+ size_t ta_num_used (const ta_cfg_t * cfg ) {
282
+ Heap * heap = (Heap * )cfg -> base ;
289
283
return count_blocks (heap -> used );
290
284
}
291
285
292
- size_t ta_num_fresh () {
286
+ size_t ta_num_fresh (const ta_cfg_t * cfg ) {
287
+ Heap * heap = (Heap * )cfg -> base ;
293
288
return count_blocks (heap -> fresh );
294
289
}
295
290
296
- bool ta_check () {
297
- return heap_max_blocks == ta_num_free () + ta_num_used () + ta_num_fresh ();
291
+ bool ta_check (const ta_cfg_t * cfg ) {
292
+ return cfg -> max_blocks ==
293
+ ta_num_free (cfg ) + ta_num_used (cfg ) + ta_num_fresh (cfg );
298
294
}
299
295
300
- size_t ta_getsize (void * ptr ) {
296
+ size_t ta_getsize (const ta_cfg_t * cfg , void * ptr ) {
301
297
if (ptr == NULL ) {
302
298
return 0 ;
303
299
}
300
+ Heap * heap = (Heap * )cfg -> base ;
304
301
Block * block = heap -> used ;
305
302
while (block != NULL ) {
306
303
if (ptr == block -> addr ) {
@@ -313,21 +310,21 @@ size_t ta_getsize(void *ptr) {
313
310
314
311
/* requires memcpy() */
315
312
#ifdef TA_USE_STDLIB
316
- void * ta_realloc (void * ptr , size_t num ) {
313
+ void * ta_realloc (const ta_cfg_t * cfg , void * ptr , size_t num ) {
317
314
if (ptr == NULL ) {
318
- return ta_alloc (num );
315
+ return ta_alloc (cfg , num );
319
316
} else if (num == 0 ) {
320
- ta_free (ptr );
317
+ ta_free (cfg , ptr );
321
318
return NULL ;
322
319
}
323
- size_t size = ta_getsize (ptr );
324
- Block * block = alloc_block (num );
320
+ size_t size = ta_getsize (cfg , ptr );
321
+ Block * block = alloc_block (cfg , num );
325
322
if (block != NULL ) {
326
323
if (size > num ) {
327
324
size = num ;
328
325
}
329
326
memcpy (block -> addr , ptr , size );
330
- ta_free (ptr );
327
+ ta_free (cfg , ptr );
331
328
return block -> addr ;
332
329
}
333
330
errno = ENOMEM ;
0 commit comments