diff options
Diffstat (limited to 'src/library/gc/shm.c')
-rw-r--r-- | src/library/gc/shm.c | 100 |
1 files changed, 0 insertions, 100 deletions
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); -} |