diff options
author | Clyne Sullivan <tullivan99@gmail.com> | 2018-10-02 21:26:48 -0400 |
---|---|---|
committer | Clyne Sullivan <tullivan99@gmail.com> | 2018-10-02 21:26:48 -0400 |
commit | c66410f6319284b94e21758539ac25bfb4694d3a (patch) | |
tree | 73c1ac0da5c6507d4111cf967549184c964552c9 /src/heap.c | |
parent | 231c796f50ac4dc277978a6568e8083412c765e0 (diff) |
folder restructure
Diffstat (limited to 'src/heap.c')
-rw-r--r-- | src/heap.c | 131 |
1 files changed, 0 insertions, 131 deletions
diff --git a/src/heap.c b/src/heap.c deleted file mode 100644 index 354087f..0000000 --- a/src/heap.c +++ /dev/null @@ -1,131 +0,0 @@ -/** - * @file heap.c - * A basic memory manager - * - * Copyright (C) 2018 Clyne Sullivan - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see <https://www.gnu.org/licenses/>. - */ - -#include <heap.h> - -#define HEAP_ALIGN 4 - -static alloc_t *free_blocks; -static void *heap_end; - -void heap_init(void *buf) -{ - heap_end = buf; - free_blocks = 0; -} - -uint32_t heap_free(void) -{ - uint32_t total = 0; - for (alloc_t *node = free_blocks; node != 0; node = node->next) - total += node->size; - return total + (0x20018000 - (uint32_t)heap_end); -} - -void *malloc(uint32_t size) -{ - if (size == 0) - return 0; - - size = (size + sizeof(alloc_t) + HEAP_ALIGN) & ~(HEAP_ALIGN - 1); - - alloc_t *node = free_blocks; - alloc_t *prev = 0; - while (node != 0) { - if (node->size >= size) { - // get out of the free chain - if (prev != 0) - prev->next = node->next; - else - free_blocks = node->next; - node->next = 0; - - // split alloc if too big - if (node->size > size + 64) { - alloc_t *leftover = (alloc_t *)((uint32_t)node - + sizeof(alloc_t) + size); - leftover->size = node->size - size - sizeof(alloc_t); - leftover->next = 0; - free((uint8_t *)leftover + sizeof(alloc_t)); - node->size = size; - return (void *)((uint8_t *)node + sizeof(alloc_t)); - } - - return (void *)((uint8_t *)node + sizeof(alloc_t)); - } - - prev = node; - node = node->next; - } - - node = (alloc_t *)heap_end; - node->size = size; - node->next = 0; - - heap_end = (void *)((uint8_t *)heap_end + size); - - return (void *)((uint8_t *)node + sizeof(alloc_t)); -} - -void *calloc(uint32_t count, uint32_t size) -{ - uint8_t *buf = malloc(count * size); - for (uint32_t i = 0; i < count * size; i++) - buf[i] = 0; - return buf; -} - -void free(void *buf) -{ - if (buf == 0) - return; - - alloc_t *alloc = (alloc_t *)((uint8_t *)buf - sizeof(alloc_t)); - if (alloc->next != 0) - return; - - // check for adjacent free'd blocks - int merged = 0; - for (alloc_t *prev = 0, *node = free_blocks; node != 0; prev = node, node = node->next) { - if ((uint32_t)node + sizeof(alloc_t) + node->size == (uint32_t)alloc) { - // block before - merged |= 1; - node->size += sizeof(alloc_t) + alloc->size; - break; - //alloc = node; - } else if ((uint32_t)buf + alloc->size == (uint32_t)node) { - // block after - merged |= 1; - alloc->size += sizeof(alloc_t) + node->size; - alloc->next = node->next; - if (prev != 0) - prev->next = alloc; - else - free_blocks = alloc; - break; - } - } - - if (merged == 0) { - alloc->next = free_blocks; - free_blocks = alloc; - } - -} |