ddnet/src/engine/e_memheap.c

103 lines
2 KiB
C

/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
#include <base/system.h>
typedef struct CHUNK_t
{
char *memory;
char *current;
char *end;
struct CHUNK_t *next;
} CHUNK;
typedef struct
{
CHUNK *current;
} HEAP;
/* 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;
}