#ifndef WONKY_MALLOC_C
#define WONKY_MALLOC_C WONKY_MALLOC_C
#include <wonky_malloc.h>
static struct Memory wonky_memory;
void wonky_memory_init()
{
wonky_memory.map_nodes=
calloc_memory_segment(NULL,NUMBER_OF_MAP_NODES_IN_INCREMENTATION_OF_MAP_MEMORY_SEGMENT,sizeof(struct Map));
if(wonky_memory.map_nodes==NULL)
wonky_memfail();
wonky_memory.generic=get_memory_segment(NULL,0);
if(wonky_memory.generic==NULL)
{
delete_memory_segment(wonky_memory.map_nodes);
wonky_memfail();
}
wonky_memory.tokens=
calloc_memory_segment(NULL,NUMBER_OF_TOKENS_IN_INCREMENTATION_OF_TOKEN_MEMORY_SEGMENT,sizeof(struct token));
if(wonky_memory.tokens==NULL)
{
delete_memory_segment(wonky_memory.map_nodes);
delete_memory_segment(wonky_memory.generic);
wonky_memfail();
}
}
void wonky_memory_delete()
{
struct Memory_Segment *current_segment;
struct Memory_Segment *hold_previous_segment;
current_segment=wonky_memory.map_nodes;
while(current_segment!=NULL)
{
hold_previous_segment=current_segment->previous;
delete_memory_segment(current_segment);
current_segment=hold_previous_segment;
}
current_segment=wonky_memory.tokens;
while(current_segment!=NULL)
{
hold_previous_segment=current_segment->previous;
delete_memory_segment(current_segment);
current_segment=hold_previous_segment;
}
current_segment=wonky_memory.generic;
while(current_segment!=NULL)
{
hold_previous_segment=current_segment->previous;
delete_memory_segment(current_segment);
current_segment=hold_previous_segment;
}
}
void delete_memory_segment(struct Memory_Segment *segment)
{
free(segment->data);
free(segment);
}
void* wonky_malloc(size_t size)
{
if(wonky_memory.generic->capacity - wonky_memory.generic->size <= size)
wonky_memory.generic=get_memory_segment(wonky_memory.generic,size);
wonky_memory.generic->size+=size;
return wonky_memory.generic->data + wonky_memory.generic->size - size;
}
/*I know*/
void* wonky_calloc(size_t nmemb,size_t size)
{
if(wonky_memory.generic->capacity - wonky_memory.generic->size <= size*nmemb)
wonky_memory.generic=get_memory_segment(wonky_memory.generic,size*nmemb);
for(size_t i=0;i<size*nmemb;++i)
wonky_memory.generic->data[i+wonky_memory.generic->size]=0;
wonky_memory.generic->size+=nmemb*size;
return wonky_memory.generic->data + wonky_memory.generic->size - nmemb*size;
}
struct Map* wonky_malloc_map_node()
{
if(wonky_memory.map_nodes->size==wonky_memory.map_nodes->capacity)
wonky_memory.map_nodes=calloc_memory_segment(wonky_memory.map_nodes,NUMBER_OF_MAP_NODES_IN_INCREMENTATION_OF_MAP_MEMORY_SEGMENT,sizeof(struct Map));
++wonky_memory.map_nodes->size;
return (struct Map*) (wonky_memory.map_nodes->data + (wonky_memory.map_nodes->size-1)*sizeof(struct Map));
}
struct token* wonky_malloc_token()
{
if(wonky_memory.tokens->size==wonky_memory.tokens->capacity)
wonky_memory.tokens=calloc_memory_segment(wonky_memory.tokens,NUMBER_OF_TOKENS_IN_INCREMENTATION_OF_TOKEN_MEMORY_SEGMENT,sizeof(struct token));
++wonky_memory.tokens->size;
return (struct token*) (wonky_memory.tokens->data + wonky_memory.tokens->size*sizeof(struct token) - sizeof(struct token));
}
struct Memory_Segment* get_memory_segment(struct Memory_Segment *previous,size_t atleast_this_size)
{
struct Memory_Segment *ret;
if(previous==NULL)
{
ret=malloc(sizeof(struct Memory_Segment));
if(ret==NULL)
wonky_memfail();
ret->data=malloc(atleast_this_size+NUMBER_OF_BYTES_IN_INCREMENTATION_OF_GENERIC_MEMORY_SEGMENT);
if(ret->data==NULL)
wonky_memfail();
ret->capacity=atleast_this_size+NUMBER_OF_BYTES_IN_INCREMENTATION_OF_GENERIC_MEMORY_SEGMENT;
ret->size=0;
ret->previous=NULL;
}else
{
ret=malloc(sizeof(struct Memory_Segment));
if(ret==NULL)
wonky_memfail();
ret->data=malloc(atleast_this_size+NUMBER_OF_BYTES_IN_INCREMENTATION_OF_GENERIC_MEMORY_SEGMENT+previous->capacity);
if(ret->data==NULL)
wonky_memfail();
ret->capacity=atleast_this_size+NUMBER_OF_BYTES_IN_INCREMENTATION_OF_GENERIC_MEMORY_SEGMENT+previous->capacity;
ret->size=0;
ret->previous=previous;
}
return ret;
}
struct Memory_Segment* calloc_memory_segment(struct Memory_Segment *previous,size_t increment_size,size_t element_size)
{
struct Memory_Segment *ret;
if(previous==NULL)
{
ret=malloc(sizeof(struct Memory_Segment));
if(ret==NULL)
wonky_memfail();
ret->data=calloc(element_size,increment_size);
if(ret->data==NULL)
wonky_memfail();
ret->capacity=increment_size;
ret->size=0;
ret->previous=NULL;
}else
{
ret=malloc(sizeof(struct Memory_Segment));
if(ret==NULL)
wonky_memfail();
ret->data=calloc(element_size,increment_size+previous->capacity);
if(ret->data==NULL)
wonky_memfail();
ret->capacity=increment_size+previous->capacity;
ret->size=0;
ret->previous=previous;
}
return ret;
}
void* wonky_realloc(void *old_mem,size_t new_size)
{
void *ret;
#warning this should be made into a propper realloc!
ret=wonky_malloc(new_size);
#warning we are getting out of bound bytes from old_mem :-(
gmemmove(ret,old_mem,new_size);
return ret;
}
void wonky_memfail()
{
fprintf(stderr,"WONKY MEMFAIL");
abort();
}
#endif