diff options
Diffstat (limited to 'kpat/freecell-solver/alloc.c')
-rw-r--r-- | kpat/freecell-solver/alloc.c | 127 |
1 files changed, 127 insertions, 0 deletions
diff --git a/kpat/freecell-solver/alloc.c b/kpat/freecell-solver/alloc.c new file mode 100644 index 00000000..81abdcc5 --- /dev/null +++ b/kpat/freecell-solver/alloc.c @@ -0,0 +1,127 @@ +/* + * 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; + } +} + + + + |