You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
128 lines
3.1 KiB
128 lines
3.1 KiB
/*
|
|
* alloc.c - a dynamic memory allocator. It allocates blocks of relatively
|
|
* small size, in a contiguous, compact manner. The most recent block can
|
|
* be released, but otherwise the blocks are kept for prosperity.
|
|
*
|
|
* Written by Shlomi Fish (shlomif@vipe.technion.ac.il), 2002
|
|
*
|
|
* This file is in the public domain (it's uncopyrighted).
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
|
|
#include "fcs_config.h"
|
|
|
|
#include "alloc.h"
|
|
|
|
#ifdef DMALLOC
|
|
#include "dmalloc.h"
|
|
#endif
|
|
|
|
#define ALLOCED_SIZE (8*1024-10*sizeof(char *))
|
|
|
|
fcs_compact_allocator_t *
|
|
freecell_solver_compact_allocator_new(void)
|
|
{
|
|
fcs_compact_allocator_t * allocator;
|
|
|
|
|
|
allocator = (fcs_compact_allocator_t *)malloc(sizeof(*allocator));
|
|
allocator->max_num_packs = IA_STATE_PACKS_GROW_BY;
|
|
allocator->packs = (char * *)malloc(sizeof(allocator->packs[0]) * allocator->max_num_packs);
|
|
allocator->num_packs = 1;
|
|
allocator->max_ptr =
|
|
(allocator->ptr =
|
|
allocator->rollback_ptr =
|
|
allocator->packs[0] =
|
|
malloc(ALLOCED_SIZE))
|
|
+ ALLOCED_SIZE;
|
|
|
|
return allocator;
|
|
}
|
|
|
|
void freecell_solver_compact_allocator_extend(
|
|
fcs_compact_allocator_t * allocator
|
|
)
|
|
{
|
|
/* Allocate a new pack */
|
|
if (allocator->num_packs == allocator->max_num_packs)
|
|
{
|
|
allocator->max_num_packs += IA_STATE_PACKS_GROW_BY;
|
|
allocator->packs = (char * *)realloc(allocator->packs, sizeof(allocator->packs[0]) * allocator->max_num_packs);
|
|
}
|
|
|
|
allocator->max_ptr =
|
|
(allocator->ptr =
|
|
allocator->rollback_ptr =
|
|
allocator->packs[allocator->num_packs++] =
|
|
malloc(ALLOCED_SIZE))
|
|
+ ALLOCED_SIZE;
|
|
}
|
|
|
|
#if 0
|
|
char *
|
|
freecell_solver_compact_allocator_alloc(
|
|
fcs_compact_allocator_t * allocator,
|
|
int how_much
|
|
)
|
|
{
|
|
if (allocator->max_ptr - allocator->ptr < how_much)
|
|
{
|
|
freecell_solver_compact_allocator_extend(allocator);
|
|
}
|
|
allocator->rollback_ptr = allocator->ptr;
|
|
allocator->ptr += (how_much+(4-(how_much&0x3)));
|
|
return allocator->rollback_ptr;
|
|
}
|
|
|
|
void freecell_solver_compact_allocator_release(fcs_compact_allocator_t * allocator)
|
|
{
|
|
allocator->ptr = allocator->rollback_ptr;
|
|
}
|
|
#endif
|
|
|
|
void freecell_solver_compact_allocator_finish(fcs_compact_allocator_t * allocator)
|
|
{
|
|
int a;
|
|
for(a=0;a<allocator->num_packs;a++)
|
|
{
|
|
free(allocator->packs[a]);
|
|
}
|
|
free(allocator->packs);
|
|
free(allocator);
|
|
}
|
|
|
|
void freecell_solver_compact_allocator_foreach(
|
|
fcs_compact_allocator_t * allocator,
|
|
int data_width,
|
|
void (*ptr_function)(void *, void *),
|
|
void * context
|
|
)
|
|
{
|
|
int pack;
|
|
char * ptr, * max_ptr;
|
|
for(pack=0;pack<allocator->num_packs-1;pack++)
|
|
{
|
|
ptr = allocator->packs[pack];
|
|
max_ptr = ptr + ALLOCED_SIZE - data_width;
|
|
while (ptr <= max_ptr)
|
|
{
|
|
ptr_function(ptr, context);
|
|
ptr += data_width;
|
|
}
|
|
}
|
|
/* Run the callback on the last pack */
|
|
ptr = allocator->packs[pack];
|
|
max_ptr = allocator->rollback_ptr;
|
|
while (ptr <= max_ptr)
|
|
{
|
|
ptr_function(ptr, context);
|
|
ptr += data_width;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|