diff options
author | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-01 12:20:45 +0200 |
---|---|---|
committer | Alex AUVOLAT <alexis211@gmail.com> | 2012-05-01 12:20:45 +0200 |
commit | 5cac9acd3aedc8043d4272d93c56805c46ff6214 (patch) | |
tree | ba9eb5ef86f7cf7afd4f7ab02de1d6bb86715632 /src/library/gc | |
parent | 66b32658d2e5aa99493dcb3abcb73cdb2cc6f0b5 (diff) | |
download | TCE-5cac9acd3aedc8043d4272d93c56805c46ff6214.tar.gz TCE-5cac9acd3aedc8043d4272d93c56805c46ff6214.zip |
Some cleanup ; relocated the kernel at 0xC0000000
Diffstat (limited to 'src/library/gc')
-rw-r--r-- | src/library/gc/mem.c | 262 | ||||
-rw-r--r-- | src/library/gc/shm.c | 100 | ||||
-rw-r--r-- | src/library/gc/syscall.c | 68 |
3 files changed, 0 insertions, 430 deletions
diff --git a/src/library/gc/mem.c b/src/library/gc/mem.c deleted file mode 100644 index fe243ba..0000000 --- a/src/library/gc/mem.c +++ /dev/null @@ -1,262 +0,0 @@ -#include "gc/mem.h" - -struct heap_header { - uint32_t magic; - uint32_t is_hole; - size_t size; -}; - -struct heap_footer { - uint32_t magic; - struct heap_header *header; -}; - -struct heap { - struct heap_header **idx; - uint32_t idxused; - size_t start_addr, end_addr, max_end; -}; - -int heap_create(struct heap *heap, size_t start, size_t idxsize, size_t datasize, size_t maxdatasize); -void* heap_alloc(struct heap *heap, size_t sz); -void heap_free(struct heap *heap, void* ptr); - -#define HEAP_MAGIC 0xBAD0BEEF -#define HEAP_MIN_SIZE 0x4000 - -/* ******************* GENERAL MEMORY FUNCTIONS ******************** */ - -static struct heap h; -static int heap_ok = 0; - -void* malloc(size_t size) { - if (heap_ok == 0) { - if (heap_create(&h, 0x20000000, 0x00010000, 0x00100000, 0x4F000000)) return 0; - heap_ok = 1; - } - return heap_alloc(&h, size); -} - -void free(void* p) { - if (heap_ok == 0 || (size_t)p < h.start_addr || (size_t)p > h.end_addr) return; - heap_free(&h, p); -} - -static int setheapseg (struct heap *heap, size_t start, size_t end, size_t prev_end) { //returns nonzero on error - if (heap == &h) { - return proc_setheap(start, end); - } //otherwise, something else might be done. - return -1; -} - -/* ******************* HEAP HEADER ****************** */ - -static void heapIdx_insert(struct heap *heap, struct heap_header *e) { - if ((heap->idxused + sizeof(struct heap_header*) + (size_t)heap->idx) >= heap->start_addr) return; - - uint32_t iterator = 0, pos; - while (iterator < heap->idxused && heap->idx[iterator]->size < e->size) { - if (heap->idx[iterator] == e) return; - iterator++; - } - if (iterator == heap->idxused) { - heap->idx[heap->idxused++] = e; - } else { - pos = iterator; - iterator = heap->idxused; - while (iterator > pos) { - heap->idx[iterator] = heap->idx[iterator - 1]; - iterator--; - } - heap->idxused++; - heap->idx[pos] = e; - } -} - -static void heapIdx_remove(struct heap *heap, struct heap_header *e) { - uint32_t iterator; - for (iterator = 0; iterator < heap->idxused; iterator++) { - if (heap->idx[iterator] == e) break; - } - if (iterator == heap->idxused) return; - heap->idxused--; - while (iterator < heap->idxused) { - heap->idx[iterator] = heap->idx[iterator + 1]; - iterator++; - } -} - -/* ******************** HEAP CONTENTS ********************* */ - -int heap_create(struct heap *heap, size_t start, size_t idxsize, size_t datasize, size_t maxdatasize) { - if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000; - - heap->start_addr = start + idxsize; - heap->end_addr = start + idxsize + datasize; - heap->max_end = start + idxsize + maxdatasize; - - if (setheapseg(heap, start, heap->end_addr, 0)) return -1; - - heap->idx = (struct heap_header**)start; - heap->idxused = 0; - - struct heap_header *hole = (struct heap_header*) heap->start_addr; - hole->size = (heap->end_addr - heap->start_addr); - hole->magic = HEAP_MAGIC; - hole->is_hole = 1; - - struct heap_footer *hole_footer = (struct heap_footer*)(heap->end_addr - sizeof(struct heap_footer)); - hole_footer->header = hole; - hole_footer->magic = HEAP_MAGIC; - - heapIdx_insert(heap, hole); - return 0; -} - -static uint32_t heap_expand(struct heap *heap, size_t quantity) { - if (quantity & 0x0FFF) { - quantity = (quantity & 0xFFFFF000) + 0x1000; - } - - if (heap->end_addr + quantity > heap->max_end) return 0; - - size_t newEnd = heap->end_addr + quantity; - - if (setheapseg(heap, (size_t)heap->idx, newEnd, heap->end_addr)) return 0; //failed to bigger segment - - struct heap_footer *last_footer = (struct heap_footer*)(heap->end_addr - sizeof(struct heap_footer)); - struct heap_header *last_header = last_footer->header; - if (last_header->is_hole) { - heapIdx_remove(heap, last_header); - last_header->size += quantity; - - last_footer = (struct heap_footer*)(newEnd - sizeof(struct heap_footer)); - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - - heapIdx_insert(heap, last_header); - } else { - last_header = (struct heap_header*)heap->end_addr; - last_footer = (struct heap_footer*)(newEnd - sizeof(struct heap_footer)); - - last_header->is_hole = 1; - last_header->magic = HEAP_MAGIC; - last_header->size = quantity; - - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - - heapIdx_insert(heap, last_header); - } - - heap->end_addr = newEnd; - - return 1; -} - -static void heap_contract(struct heap *heap) { - struct heap_footer *last_footer = (struct heap_footer*)(heap->end_addr - sizeof(struct heap_footer)); - struct heap_header *last_header = last_footer->header; - - if (last_header->is_hole == 0) return; - - size_t quantity = 0; - while ((heap->end_addr - heap->start_addr) - quantity > HEAP_MIN_SIZE && - (last_header->size - quantity) > 0x1000) - quantity += 0x1000; - if (quantity == 0) return; - - size_t newEnd = heap->end_addr - quantity; - - if (setheapseg(heap, (size_t)heap->idx, newEnd, heap->end_addr)) return; //error ocurred - - heapIdx_remove(heap, last_header); - last_header->size -= quantity; - last_footer = (struct heap_footer*)((size_t)last_footer - quantity); - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - heapIdx_insert(heap, last_header); - - heap->end_addr = newEnd; -} - -void* heap_alloc(struct heap *heap, size_t sz) { - size_t newsize = sz + sizeof(struct heap_header) + sizeof(struct heap_footer); - uint32_t iterator = 0; - - while (iterator < heap->idxused) { - if (heap->idx[iterator]->size >= newsize) break; - iterator++; - } - - if (iterator == heap->idxused) { //No hole is big enough - if (heap_expand(heap, (sz & 0xFFFFF000) + 0x1000) == 0) return 0; //FAILED - return heap_alloc(heap, sz); - } - - struct heap_header *loc = heap->idx[iterator]; - struct heap_footer *footer = (struct heap_footer*)((size_t)loc + loc->size - sizeof(struct heap_footer)); - loc->is_hole = 0; - heapIdx_remove(heap, loc); - - //If we have enough space to create a USEFUL new hole next to the allocated block, do it. - //If we do not, we might return a block that is a few bytes bigger than neede. - if (loc->size > (newsize + sizeof(struct heap_header) + sizeof(struct heap_footer))) { - loc->size = newsize; - - //Write footer for block we return - struct heap_footer *newfooter = (struct heap_footer*)((size_t)loc + newsize - sizeof(struct heap_footer)); - newfooter->header = loc; - newfooter->magic = HEAP_MAGIC; - - //Write header for new hole we create - struct heap_header *nextloc = (struct heap_header*)((size_t)loc + newsize); - nextloc->is_hole = 1; - nextloc->magic = HEAP_MAGIC; - nextloc->size = ((size_t)footer - (size_t)nextloc + sizeof(struct heap_footer)); - footer->header = nextloc; //Update footer - footer->magic = HEAP_MAGIC; - - heapIdx_insert(heap, nextloc); - } - - return (void*)((size_t)loc + sizeof(struct heap_header)); -} - -void heap_free(struct heap *heap, void* ptr) { - if (ptr == 0) return; - if ((size_t)ptr < heap->start_addr || (size_t)ptr > heap->end_addr) return; - - struct heap_header *header = (struct heap_header*)((size_t)ptr - sizeof(struct heap_header)); - struct heap_footer *footer = (struct heap_footer*)((size_t)header + header->size - sizeof(struct heap_footer)); - if (header->magic != HEAP_MAGIC || footer->magic != HEAP_MAGIC) return; - - //Unify left - struct heap_footer *prev_footer = (struct heap_footer*)((size_t)header - sizeof(struct heap_footer)); - if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) { - header = prev_footer->header; - heapIdx_remove(heap, header); - - footer->header = header; - header->size = ((size_t)footer - (size_t)header + sizeof(struct heap_footer)); - } - - //Unify right - struct heap_header *next_header = (struct heap_header*)((size_t)footer + sizeof(struct heap_footer)); - if (next_header->magic == HEAP_MAGIC && next_header->is_hole) { - heapIdx_remove(heap, next_header); - footer = (struct heap_footer*)((size_t)footer + next_header->size); - - footer->header = header; - header->size = ((size_t)footer - (size_t)header + sizeof(struct heap_footer)); - } - - header->is_hole = 1; - - heapIdx_insert(heap, header); - - if ((size_t)footer == (heap->end_addr - sizeof(struct heap_footer)) && - header->size >= 0x2000 && (heap->end_addr - heap->start_addr > HEAP_MIN_SIZE)) { - heap_contract(heap); - } -} diff --git a/src/library/gc/shm.c b/src/library/gc/shm.c deleted file mode 100644 index 7f8609a..0000000 --- a/src/library/gc/shm.c +++ /dev/null @@ -1,100 +0,0 @@ -#include <gc/shm.h> -#include <gc/mem.h> -#include <mutex.h> - -struct shm_block { - size_t start, size; - int is_hole; //1 : hole, 0 : used block - struct shm_block *prev, *next; -}; - -struct shm_block *blocks = 0; - -static uint32_t tMutex = MUTEX_UNLOCKED; - -static void shm_init() { - struct shm_block *b = malloc(sizeof(struct shm_block)); - b->start = 0x80000000; - b->size = 0xD0000000 - 0x80000000; - b->is_hole = 1; - b->prev = b->next = 0; - blocks = b; -} - -void* shm_alloc(size_t size) { - mutex_lock(&tMutex); - if (blocks == 0) shm_init(); - if (size & 0xFFF) size = (size & 0xFFFFF000) + 0x1000; - //go through all blocks, get the one with the closest size - struct shm_block *i = blocks, *block = 0; - while (i) { - if (i->size >= size && i->is_hole == 1 && (block == 0 || i->size < block->size)) block = i; - i = i->next; - } - if (block == 0) { - mutex_unlock(&tMutex); - return 0; - } - //if the block's size is bigger, reduce it and create a new one after - if (block->size > size) { - struct shm_block *newb = malloc(sizeof(struct shm_block)); - newb->start = block->start + size; - newb->size = block->size - size; - newb->is_hole = 1; - newb->prev = block; newb->next = block->next; - block->size = size; - if (block->next != 0) block->next->prev = newb; - block->next = newb; - } - //mark block as used - block->is_hole = 0; - //return block's address - mutex_unlock(&tMutex); - return (void*)block->start; -} - -static void unify (struct shm_block *b) { - if (b->next == 0 || b->is_hole == 0 || b->next->is_hole == 0) return; - struct shm_block *n = b->next; - b->size += n->size; - if (n->next != 0) n->next->prev = b; - b->next = n->next; - free(n); -} - -void shm_free(void* p) { - mutex_lock(&tMutex); - //find block - struct shm_block *bl = blocks; - while (bl) { - if (bl->start == (size_t)p) break; - bl = bl->next; - } - if (bl == 0) { - mutex_unlock(&tMutex); - return; - } - //mark it as a hole - bl->is_hole = 1; - //unify after if possible - if (bl->next != 0 && bl->next->is_hole == 1) unify(bl); - //unify before if possible - if (bl->prev != 0 && bl->prev->is_hole == 1) unify(bl->prev); - mutex_unlock(&tMutex); -} - -void* shm_allocNew(size_t size) { - if (size & 0xFFF) size = (size & 0xFFFFF000) + 0x1000; - - void* p = shm_alloc(size); - if (shm_create((size_t)p, size) != 0) { - shm_free(p); - return 0; - } - return p; -} - -void shm_freeDel(void *p) { - shm_delete((size_t)p); - shm_free(p); -} diff --git a/src/library/gc/syscall.c b/src/library/gc/syscall.c deleted file mode 100644 index 3100dd7..0000000 --- a/src/library/gc/syscall.c +++ /dev/null @@ -1,68 +0,0 @@ -#include <gc/syscall.h> -#include <gc/mem.h> - -static int call(unsigned a, unsigned b, unsigned c, unsigned d, unsigned e, unsigned f) { - unsigned ret; - asm volatile("int $64" : "=a"(ret) : "a"(a), "b"(b), "c"(c), "d"(d), "S"(e), "D"(f)); - return ret; -} - -void thread_exit() { - call(0, 0, 0, 0, 0, 0); -} - -void schedule() { - call(1, 0, 0,0, 0, 0); -} - -void thread_sleep(int time) { - call(2, time, 0, 0, 0, 0); -} - -void process_exit(int retval) { - call(3, retval, 0, 0, 0, 0); -} - -void printk(char* str) { - call(4, (unsigned)str, 0, 0, 0, 0); -} - -//THREAD CREATION -struct thread_start_data { - void (*entry)(void*); - void *data; - void *stack; -}; -void thread_start(void *data) { - struct thread_start_data *tsd = data; - tsd->entry(tsd->data); - free(tsd->stack); - thread_exit(); -} -void thread_new(void (*entry)(void*), void *data) { - struct thread_start_data *tsd = malloc(sizeof(struct thread_start_data)); - tsd->entry = entry; - tsd->data = data; - tsd->stack = malloc(NEW_STACK_SIZE); - call(5, (unsigned)thread_start, (unsigned)tsd, (unsigned)(tsd->stack + NEW_STACK_SIZE), 0, 0); -} - -void irq_wait(int number) { - call(6, number, 0, 0, 0, 0); -} - -int proc_priv() { - return call(7, 0, 0, 0, 0, 0); -} - -int proc_setheap(size_t start, size_t end) { - return call(8, start, end, 0, 0, 0); -} - -int shm_create(size_t offset, size_t length) { - return call(9, offset, length, 0, 0, 0); -} - -int shm_delete(size_t offset) { - return call(10, offset, 0, 0, 0, 0); -} |