aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarsten Schmidt <k@postspectacular.com>2017-07-15 12:12:34 +0100
committerKarsten Schmidt <k@postspectacular.com>2017-07-15 12:25:51 +0100
commitfeef1bae13fa929fef3deda18d676cd25363a50e (patch)
tree1ec97eab26e09fc637f4467c3ae0a55b9bd19cb8
parentb838efb48972bc975c609179f261119a5f247a8c (diff)
remove various functions if TA_DISABLE_COMPACT, update ptr casts, update readme
-rw-r--r--README.md5
-rw-r--r--tinyalloc.c22
2 files changed, 19 insertions, 8 deletions
diff --git a/README.md b/README.md
index 23358ba..e119289 100644
--- a/README.md
+++ b/README.md
@@ -9,12 +9,14 @@ Tiny replacement for `malloc` / `free` in unmanaged, linear memory situations, e
- configurable pointer alignment in heap space
- optional compaction of consecutive free blocks
- optional block splitting during alloc (if re-using larger free'd blocks)
-- tiny, the WASM binary is 1.5KB
+- tiny, the WASM binary is 1.5KB (1.1KB w/ compaction disabled)
## Details
**tinyalloc** maintains 3 linked lists: fresh blocks, used blocks, free blocks. All lists are stored in the same fixed sized array so the memory overhead can be controlled at compile time via the [configuration vars](#configuration) listed below. During initialization all blocks are added to the list of fresh blocks.
+The difference between free & fresh blocks is the former already have an associated heap address and size from previous usage. OTOH fresh blocks are uninitialized and are only used if no existing free blocks satisfy an allocation request.
+
The diagram illustrates the state of having 1 freed block (green), 2 used blocks (red) and the beginning of the fresh (unused) block list:
![memory layout](tinyalloc.png)
@@ -72,6 +74,7 @@ On a 32bit system, the default configuration causes an overhead of 3088 bytes in
**Notes:**
- `TA_ALIGN` is assumed to be >= native word size
+- `TA_BASE` must be an address in RAM (on embedded devices)
- `TA_HEAP_START` is assumed to be properly aligned
If building in debug mode (if `TA_DEBUG` symbol is defined), two externally defined functions are required:
diff --git a/tinyalloc.c b/tinyalloc.c
index 93d568d..9b07461 100644
--- a/tinyalloc.c
+++ b/tinyalloc.c
@@ -52,9 +52,13 @@ typedef struct {
static Heap *heap = (Heap *)TA_BASE;
/**
- * Insert block into free list, sorted by addr.
+ * If compaction is enabled, inserts block
+ * into free list, sorted by addr.
+ * If disabled, add block has new head of
+ * the free list.
*/
static void insert_block(Block *block) {
+#ifndef TA_DISABLE_COMPACT
Block *ptr = heap->free;
Block *prev = NULL;
while (ptr != NULL) {
@@ -76,8 +80,13 @@ static void insert_block(Block *block) {
heap->free = block;
}
block->next = ptr;
+#else
+ block->next = heap->free;
+ heap->free = block;
+#endif
}
+#ifndef TA_DISABLE_COMPACT
static void release_blocks(Block *scan, Block *to) {
Block *scan_next;
while (scan != to) {
@@ -92,15 +101,13 @@ static void release_blocks(Block *scan, Block *to) {
}
}
-#ifndef TA_DISABLE_COMPACT
static void compact() {
Block *ptr = heap->free;
Block *prev;
Block *scan;
while (ptr != NULL) {
- prev = ptr;
- scan = ptr->next;
- size_t base = (size_t)ptr->addr;
+ prev = ptr;
+ scan = ptr->next;
while (scan != NULL &&
(size_t)prev->addr + prev->size == (size_t)scan->addr) {
print_s("merge");
@@ -109,7 +116,8 @@ static void compact() {
scan = scan->next;
}
if (prev != ptr) {
- size_t new_size = prev->addr + prev->size - ptr->addr;
+ size_t new_size =
+ (size_t)prev->addr - (size_t)ptr->addr + prev->size;
print_s("new size");
print_i(new_size);
ptr->size = new_size;
@@ -186,7 +194,7 @@ static Block *alloc_block(size_t num) {
ptr->size = num;
Block *split = heap->fresh;
heap->fresh = split->next;
- split->addr = ptr->addr + num;
+ split->addr = (void *)((size_t)ptr->addr + num);
print_s("split");
print_i((size_t)split->addr);
split->size = excess;