aboutsummaryrefslogtreecommitdiffstats
path: root/src/heap.c
diff options
context:
space:
mode:
authorClyne Sullivan <tullivan99@gmail.com>2018-10-02 21:26:48 -0400
committerClyne Sullivan <tullivan99@gmail.com>2018-10-02 21:26:48 -0400
commitc66410f6319284b94e21758539ac25bfb4694d3a (patch)
tree73c1ac0da5c6507d4111cf967549184c964552c9 /src/heap.c
parent231c796f50ac4dc277978a6568e8083412c765e0 (diff)
folder restructure
Diffstat (limited to 'src/heap.c')
-rw-r--r--src/heap.c131
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;
- }
-
-}