From 3c8b9481088b546af3f0fd161a432ba0f0cb682e Mon Sep 17 00:00:00 2001 From: Guido Günther Date: Sun, 26 Apr 2009 14:57:08 +0200 Subject: Move libc functions into a pseudo libc away from libarc --- common/stdlib.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) create mode 100644 common/stdlib.c (limited to 'common/stdlib.c') diff --git a/common/stdlib.c b/common/stdlib.c new file mode 100644 index 0000000..1d3355a --- /dev/null +++ b/common/stdlib.c @@ -0,0 +1,116 @@ +/* + * Copyright 1999 Silicon Graphics, Inc. + */ +#include "stdlib.h" +#include "string.h" + + +typedef struct _Node { + size_t size; + struct _Node *next; +} Node; + +static Node *freeList = NULL; + +void *malloc(size_t size) +{ + Node **free, *mem; + + size += + /* header */ sizeof(Node) + /* round up */ (sizeof(Node) - 1); + size -= size % sizeof(Node); + + free = &freeList; + while ((*free != NULL) && ((*free)->size < size)) + free = &((*free)->next); + + mem = *free; + if (mem != NULL) { + if (mem->size > size) { + Node *split = mem + (size / sizeof(Node)); + + split->size = mem->size - size; + split->next = mem->next; + mem->size = size; + mem->next = split; + } + *free = mem->next; + mem += 1; + } + + return ((void *) mem); +} + + +void free(void *ptr) +{ + if (ptr != NULL) { + Node *mem = ((Node *) ptr) - 1; + Node **free = &freeList; + + while ((*free != NULL) && (*free < mem)) { + if (mem == + (*free + ((*free)->size / sizeof(Node)))) { + (*free)->size += mem->size; + mem = *free; + break; + } + free = &((*free)->next); + } + + if (mem != *free) { + mem->next = *free; + *free = mem; + } + + if (mem->next == (mem + (mem->size / sizeof(Node)))) { + mem->size += mem->next->size; + mem->next = mem->next->next; + } + } +} + + +void *realloc(void *ptr, size_t size) +{ + if (ptr == NULL) { + ptr = malloc(size); + } else { + Node *mem = ((Node *) ptr) - 1; + + size += + /* header */ sizeof(Node) + + /* round up */ (sizeof(Node) - 1); + size -= size % sizeof(Node); + + if (size > mem->size) { + /* Should try to grow */ + void *optr = ptr; + + ptr = malloc(size); + if (ptr != NULL) { + memcpy(ptr, optr, + mem->size - sizeof(Node)); + free(optr); + } + } else if (size < mem->size) { + Node *split = mem + (size / sizeof(Node)); + + split->size = mem->size - size; + split->next = mem->next; + mem->size = size; + free((void *) (split + 1)); + } + } + + return ptr; +} + + +void arclib_malloc_add(unsigned long start, unsigned long size) +{ + Node *node = (Node *) start; + + node->size = size - (size % sizeof(Node)); + free((void *) (node + 1)); +} -- cgit v1.2.3