2007-11-25 19:42:40 +00:00
|
|
|
/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
|
2007-12-15 10:24:49 +00:00
|
|
|
#include "e_system.h"
|
2007-09-27 23:55:59 +00:00
|
|
|
|
|
|
|
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 */
|
2007-10-02 14:14:58 +00:00
|
|
|
mem = (char*)mem_alloc(sizeof(CHUNK)+chunksize, 1);
|
2007-09-27 23:55:59 +00:00
|
|
|
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, 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, 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;
|
|
|
|
}
|