Skip to content

Commit 824a640

Browse files
author
Matt Reyer
committed
Move compile-time configuration into a runtime configuration.
- Updated README
1 parent 9ebd4a4 commit 824a640

File tree

3 files changed

+36
-47
lines changed

3 files changed

+36
-47
lines changed

README.md

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,21 @@ The list of freed blocks is sorted by block start address. When a block is being
3333

3434
## API
3535

36-
### ta\_init()
36+
### ta\_init(void \*base, void \*limit, size_t heap_blocks, size_t split_thresh, size_t alignment)
3737

3838
Initializes the control datastructure. MUST be called prior to any other **tinyalloc** function.
3939

40+
| Argument | Description |
41+
|----------|-------------|
42+
| `base` | Address of **tinyalloc** control structure, typically at the beginning of your heap |
43+
| `limit` | Heap space end address |
44+
| `heap_blocks` | Max. number of memory chunks (e.g. 256) |
45+
| `split_thresh` | Size threshold for splitting chunks (a good default is 16) |
46+
| `alignment` | Word size for pointer alignment (e.g. 8) |
47+
48+
- `alignment` is assumed to be >= native word size
49+
- `base` must be an address in RAM (on embedded devices)
50+
4051
### void* ta\_alloc(size\_t num)
4152

4253
Like standard `malloc`, returns aligned pointer to address in heap space, or `NULL` if allocation failed.
@@ -45,7 +56,7 @@ Like standard `malloc`, returns aligned pointer to address in heap space, or `NU
4556

4657
Like standard `calloc`, returns aligned pointer to zeroed memory in heap space, or `NULL` if allocation failed.
4758

48-
### bool ta\_free(void *ptr)
59+
### bool ta\_free(void \*ptr)
4960

5061
Like `free`, but returns boolean result (true, if freeing succeeded). By default, any consecutive memory blocks are being merged during the freeing operation.
5162

@@ -59,24 +70,14 @@ Structural validation. Returns `true` if internal heap structure is ok.
5970

6071
| Define | Default | Comment |
6172
|--------|---------|---------|
62-
| `TA_ALIGN` | 8 | Word size for pointer alignment |
63-
| `TA_BASE` | 0x400 | Address of **tinyalloc** control data structure |
6473
| `TA_DEBUG` | undefined | Trace debug information |
6574
| `TA_DISABLE_COMPACT` | undefined | Disable free block compaction |
6675
| `TA_DISABLE_SPLIT` | undefined | Disable free block splitting during re-alloc |
67-
| `TA_HEAP_START` | 0x1010 | Heap space start address |
68-
| `TA_HEAP_LIMIT` | 0xffffff | Heap space end address |
69-
| `TA_HEAP_BLOCKS` | 256 | Max. number of memory chunks |
70-
| `TA_SPLIT_THRESH` | 16 | Size threshold for splitting chunks |
7176

7277
On a 32bit system, the default configuration causes an overhead of 3088 bytes in RAM, but can be reduced if fewer memory blocks are needed.
7378

7479
**Notes:**
7580

76-
- `TA_ALIGN` is assumed to be >= native word size
77-
- `TA_BASE` must be an address in RAM (on embedded devices)
78-
- `TA_HEAP_START` is assumed to be properly aligned
79-
8081
If building in debug mode (if `TA_DEBUG` symbol is defined), two externally defined functions are required:
8182

8283
- `print_s(char *)` - to print a single string

tinyalloc.c

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,6 @@
11
#include "tinyalloc.h"
22
#include <stdint.h>
33

4-
#ifndef TA_ALIGN
5-
#define TA_ALIGN 8
6-
#endif
7-
8-
#ifndef TA_BASE
9-
#define TA_BASE 0x400
10-
#endif
11-
12-
#ifndef TA_HEAP_START
13-
#define TA_HEAP_START (TA_BASE + sizeof(Heap))
14-
#endif
15-
16-
#ifndef TA_HEAP_LIMIT
17-
#define TA_HEAP_LIMIT (1 << 24)
18-
#endif
19-
20-
#ifndef TA_HEAP_BLOCKS
21-
#define TA_HEAP_BLOCKS 256
22-
#endif
23-
24-
#ifndef TA_SPLIT_THRESH
25-
#define TA_SPLIT_THRESH 16
26-
#endif
27-
284
#ifdef TA_DEBUG
295
extern void print_s(char *);
306
extern void print_i(size_t);
@@ -46,10 +22,14 @@ typedef struct {
4622
Block *used; // first used block
4723
Block *fresh; // first available blank block
4824
size_t top; // top free addr
49-
Block blocks[TA_HEAP_BLOCKS];
25+
Block *blocks;
5026
} Heap;
5127

52-
static Heap *heap = (Heap *)TA_BASE;
28+
static Heap *heap = NULL;
29+
static void *heap_limit = NULL;
30+
static size_t heap_split_thresh;
31+
static size_t heap_alignment;
32+
static size_t heap_max_blocks;
5333

5434
/**
5535
* If compaction is enabled, inserts block
@@ -132,13 +112,21 @@ static void compact() {
132112
}
133113
#endif
134114

135-
bool ta_init() {
115+
bool ta_init(const void *base, const void *limit, const size_t heap_blocks, const size_t split_thresh, const size_t alignment) {
116+
heap = (Heap *)base;
117+
heap_limit = limit;
118+
heap_split_thresh = split_thresh;
119+
heap_alignment = alignment;
120+
heap_max_blocks = heap_blocks;
121+
136122
heap->free = NULL;
137123
heap->used = NULL;
138124
heap->fresh = heap->blocks;
139-
heap->top = TA_HEAP_START;
125+
heap->top = (size_t)base + sizeof(Heap) + heap_blocks * sizeof(Block);
126+
heap->blocks = base + sizeof(Heap);
127+
140128
Block *block = heap->blocks;
141-
size_t i = TA_HEAP_BLOCKS - 1;
129+
size_t i = heap_max_blocks - 1;
142130
while (i--) {
143131
block->next = block + 1;
144132
block++;
@@ -173,9 +161,9 @@ static Block *alloc_block(size_t num) {
173161
Block *ptr = heap->free;
174162
Block *prev = NULL;
175163
size_t top = heap->top;
176-
num = (num + TA_ALIGN - 1) & -TA_ALIGN;
164+
num = (num + heap_alignment - 1) & -heap_alignment;
177165
while (ptr != NULL) {
178-
const int is_top = ((size_t)ptr->addr + ptr->size >= top) && ((size_t)ptr->addr + num <= TA_HEAP_LIMIT);
166+
const int is_top = ((size_t)ptr->addr + ptr->size >= top) && ((size_t)ptr->addr + num <= heap_limit);
179167
if (is_top || ptr->size >= num) {
180168
if (prev != NULL) {
181169
prev->next = ptr->next;
@@ -191,7 +179,7 @@ static Block *alloc_block(size_t num) {
191179
#ifndef TA_DISABLE_SPLIT
192180
} else if (heap->fresh != NULL) {
193181
size_t excess = ptr->size - num;
194-
if (excess >= TA_SPLIT_THRESH) {
182+
if (excess >= heap_split_thresh) {
195183
ptr->size = num;
196184
Block *split = heap->fresh;
197185
heap->fresh = split->next;
@@ -214,7 +202,7 @@ static Block *alloc_block(size_t num) {
214202
// no matching free blocks
215203
// see if any other blocks available
216204
size_t new_top = top + num;
217-
if (heap->fresh != NULL && new_top <= TA_HEAP_LIMIT) {
205+
if (heap->fresh != NULL && new_top <= heap_limit) {
218206
ptr = heap->fresh;
219207
heap->fresh = ptr->next;
220208
ptr->addr = (void *)top;
@@ -280,5 +268,5 @@ size_t ta_num_fresh() {
280268
}
281269

282270
bool ta_check() {
283-
return TA_HEAP_BLOCKS == ta_num_free() + ta_num_used() + ta_num_fresh();
271+
return heap_max_blocks == ta_num_free() + ta_num_used() + ta_num_fresh();
284272
}

tinyalloc.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#include <stdbool.h>
22
#include <stddef.h>
33

4-
bool ta_init();
4+
bool ta_init(const void *base, const void *limit, const size_t heap_blocks, const size_t split_thresh, const size_t alignment);
55
void *ta_alloc(size_t num);
66
void *ta_calloc(size_t num, size_t size);
77
bool ta_free(void *ptr);

0 commit comments

Comments
 (0)