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,20 +154,21 @@ 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
- if (num > - heap_alignment ) {
162
+ if (num > - cfg -> alignment ) {
172
163
return NULL ; // prevent overflow
173
164
}
174
- num = (num + heap_alignment - 1 ) & - heap_alignment ;
165
+ num = (num + cfg -> alignment - 1 ) & - cfg -> alignment ;
175
166
if (num == 0 ) {
176
- num = heap_alignment ; // prevent zero-size block
167
+ num = cfg -> alignment ; // prevent zero-size block
177
168
}
178
169
while (ptr != NULL ) {
179
170
const int is_top = ((size_t )ptr -> addr + ptr -> size >= top ) &&
180
- (num <= (size_t )heap_limit - (size_t )ptr -> addr );
171
+ (num <= (size_t )cfg -> limit - (size_t )ptr -> addr );
181
172
if (is_top || ptr -> size >= num ) {
182
173
if (prev != NULL ) {
183
174
prev -> next = ptr -> next ;
@@ -193,17 +184,17 @@ static Block *alloc_block(size_t num) {
193
184
#ifndef TA_DISABLE_SPLIT
194
185
} else if (heap -> fresh != NULL ) {
195
186
size_t excess = ptr -> size - num ;
196
- if (excess >= heap_split_thresh ) {
187
+ if (excess >= cfg -> split_thresh ) {
197
188
ptr -> size = num ;
198
189
Block * split = heap -> fresh ;
199
190
heap -> fresh = split -> next ;
200
191
split -> addr = (void * )((size_t )ptr -> addr + num );
201
192
print_s ("split" );
202
193
print_i ((size_t )split -> addr );
203
194
split -> size = excess ;
204
- insert_block (split );
195
+ insert_block (heap , split );
205
196
#ifndef TA_DISABLE_COMPACT
206
- compact ();
197
+ compact (heap );
207
198
#endif
208
199
}
209
200
#endif
@@ -215,7 +206,7 @@ static Block *alloc_block(size_t num) {
215
206
}
216
207
// no matching free blocks
217
208
// see if any other blocks available
218
- if (heap -> fresh != NULL && (num <= (size_t )heap_limit - top )) {
209
+ if (heap -> fresh != NULL && (num <= (size_t )cfg -> limit - top )) {
219
210
ptr = heap -> fresh ;
220
211
heap -> fresh = ptr -> next ;
221
212
ptr -> addr = (void * )top ;
@@ -228,8 +219,8 @@ static Block *alloc_block(size_t num) {
228
219
return NULL ;
229
220
}
230
221
231
- void * ta_alloc (size_t num ) {
232
- Block * block = alloc_block (num );
222
+ void * ta_alloc (const ta_cfg_t * cfg , size_t num ) {
223
+ Block * block = alloc_block (cfg , num );
233
224
if (block != NULL ) {
234
225
return block -> addr ;
235
226
}
@@ -272,12 +263,12 @@ static void memcopy(void *dst, void *src, size_t num) {
272
263
}
273
264
#endif
274
265
275
- void * ta_calloc (size_t num , size_t size ) {
266
+ void * ta_calloc (const ta_cfg_t * cfg , size_t num , size_t size ) {
276
267
size_t orig = num ;
277
268
num *= size ;
278
269
// check for overflow
279
270
if (size == 0 || num / size == orig ) {
280
- Block * block = alloc_block (num );
271
+ Block * block = alloc_block (cfg , num );
281
272
if (block != NULL ) {
282
273
memclear (block -> addr , block -> size );
283
274
return block -> addr ;
@@ -289,10 +280,11 @@ void *ta_calloc(size_t num, size_t size) {
289
280
return NULL ;
290
281
}
291
282
292
- size_t ta_getsize (void * ptr ) {
283
+ size_t ta_getsize (const ta_cfg_t * cfg , void * ptr ) {
293
284
if (ptr == NULL ) {
294
285
return 0 ;
295
286
}
287
+ Heap * heap = (Heap * )cfg -> base ;
296
288
Block * block = heap -> used ;
297
289
while (block != NULL ) {
298
290
if (ptr == block -> addr ) {
@@ -303,24 +295,24 @@ size_t ta_getsize(void *ptr) {
303
295
return 0 ;
304
296
}
305
297
306
- void * ta_realloc (void * ptr , size_t num ) {
298
+ void * ta_realloc (const ta_cfg_t * cfg , void * ptr , size_t num ) {
307
299
if (ptr == NULL ) {
308
- return ta_alloc (num );
300
+ return ta_alloc (cfg , num );
309
301
} else if (num == 0 ) {
310
- ta_free (ptr );
302
+ ta_free (cfg , ptr );
311
303
return NULL ;
312
304
}
313
- size_t size = ta_getsize (ptr );
314
- if (num <= size && size - num <= heap_split_thresh ) {
305
+ size_t size = ta_getsize (cfg , ptr );
306
+ if (num <= size && size - num <= cfg -> split_thresh ) {
315
307
return ptr ; // keep current block
316
308
}
317
- Block * block = alloc_block (num );
309
+ Block * block = alloc_block (cfg , num );
318
310
if (block != NULL ) {
319
311
if (size > num ) {
320
312
size = num ;
321
313
}
322
314
memcopy (block -> addr , ptr , size );
323
- ta_free (ptr );
315
+ ta_free (cfg , ptr );
324
316
return block -> addr ;
325
317
}
326
318
#ifdef TA_USE_STDLIB
@@ -338,18 +330,22 @@ static size_t count_blocks(Block *ptr) {
338
330
return num ;
339
331
}
340
332
341
- size_t ta_num_free () {
333
+ size_t ta_num_free (const ta_cfg_t * cfg ) {
334
+ Heap * heap = (Heap * )cfg -> base ;
342
335
return count_blocks (heap -> free );
343
336
}
344
337
345
- size_t ta_num_used () {
338
+ size_t ta_num_used (const ta_cfg_t * cfg ) {
339
+ Heap * heap = (Heap * )cfg -> base ;
346
340
return count_blocks (heap -> used );
347
341
}
348
342
349
- size_t ta_num_fresh () {
343
+ size_t ta_num_fresh (const ta_cfg_t * cfg ) {
344
+ Heap * heap = (Heap * )cfg -> base ;
350
345
return count_blocks (heap -> fresh );
351
346
}
352
347
353
- bool ta_check () {
354
- return heap_max_blocks == ta_num_free () + ta_num_used () + ta_num_fresh ();
348
+ bool ta_check (const ta_cfg_t * cfg ) {
349
+ return cfg -> max_blocks ==
350
+ ta_num_free (cfg ) + ta_num_used (cfg ) + ta_num_fresh (cfg );
355
351
}
0 commit comments