diff options
Diffstat (limited to 'src/engine/e_memheap.cpp')
| -rw-r--r-- | src/engine/e_memheap.cpp | 102 |
1 files changed, 102 insertions, 0 deletions
diff --git a/src/engine/e_memheap.cpp b/src/engine/e_memheap.cpp new file mode 100644 index 00000000..fe157e86 --- /dev/null +++ b/src/engine/e_memheap.cpp @@ -0,0 +1,102 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include <base/system.h> + +struct CHUNK +{ + char *memory; + char *current; + char *end; + CHUNK *next; +}; + +struct HEAP +{ + CHUNK *current; +}; + +/* how large each chunk should be */ +static const int chunksize = 1024*64; + +/* allocates a new chunk to be used */ +static CHUNK *memheap_newchunk() +{ + CHUNK *chunk; + char *mem; + + /* allocate memory */ + mem = (char*)mem_alloc(sizeof(CHUNK)+chunksize, 1); + if(!mem) + return 0x0; + + /* the chunk structure is located in the begining of the chunk */ + /* init it and return the chunk */ + chunk = (CHUNK*)mem; + chunk->memory = (char*)(chunk+1); + chunk->current = chunk->memory; + chunk->end = chunk->memory + chunksize; + chunk->next = (CHUNK *)0x0; + return chunk; +} + +/******************/ +static void *memheap_allocate_from_chunk(CHUNK *chunk, unsigned int size) +{ + char *mem; + + /* check if we need can fit the allocation */ + if(chunk->current + size > chunk->end) + return (void*)0x0; + + /* get memory and move the pointer forward */ + mem = chunk->current; + chunk->current += size; + return mem; +} + +/* creates a heap */ +HEAP *memheap_create() +{ + CHUNK *chunk; + HEAP *heap; + + /* allocate a chunk and allocate the heap structure on that chunk */ + chunk = memheap_newchunk(); + heap = (HEAP *)memheap_allocate_from_chunk(chunk, sizeof(HEAP)); + heap->current = chunk; + return heap; +} + +/* destroys the heap */ +void memheap_destroy(HEAP *heap) +{ + CHUNK *chunk = heap->current; + CHUNK *next; + + while(chunk) + { + next = chunk->next; + mem_free(chunk); + chunk = next; + } +} + +/* */ +void *memheap_allocate(HEAP *heap, unsigned int size) +{ + char *mem; + + /* try to allocate from current chunk */ + mem = (char *)memheap_allocate_from_chunk(heap->current, size); + if(!mem) + { + /* allocate new chunk and add it to the heap */ + CHUNK *chunk = memheap_newchunk(); + chunk->next = heap->current; + heap->current = chunk; + + /* try to allocate again */ + mem = (char *)memheap_allocate_from_chunk(heap->current, size); + } + + return mem; +} |