about summary refs log tree commit diff
path: root/src/engine/e_memheap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/e_memheap.cpp')
-rw-r--r--src/engine/e_memheap.cpp102
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;
+}