From daabda7c8b4038ac24cdf5b9790932905eab7d8f Mon Sep 17 00:00:00 2001 From: Pixel Date: Tue, 17 Feb 2009 03:14:49 +0100 Subject: Improving stalloc by make it context-safe. --- mpq-fs.c | 17 ++++++-------- stalloc.c | 81 ++++++++++++++++++++++++++++++++++++++++----------------------- stalloc.h | 9 ++++--- 3 files changed, 65 insertions(+), 42 deletions(-) diff --git a/mpq-fs.c b/mpq-fs.c index 160fdcd..c055b17 100644 --- a/mpq-fs.c +++ b/mpq-fs.c @@ -28,6 +28,7 @@ static char * strnormalize(char * _str) { } htab * hash_table = 0; +struct st_alloc_t * st = 0; static void add_file(struct mpq_archive_t * mpq_a, char * fname) { int entry; @@ -36,13 +37,15 @@ static void add_file(struct mpq_archive_t * mpq_a, char * fname) { if ((entry = mpqlib_find_hash_entry_by_name(mpq_a, fname, 0, 0)) < 0) return; - if (!hash_table) + if (!hash_table) { hash_table = hcreate(INITIAL_HASH_SIZE); + st = st_init(); + } - nfname = strnormalize(st_strdup(fname)); + nfname = strnormalize(st_strdup(st, fname)); hadd(hash_table, (uint8_t *) nfname, strlen(nfname), NULL); if (!hstuff(hash_table)) { - hstuff(hash_table) = st_alloc(sizeof(hash_entry)); + hstuff(hash_table) = st_alloc(st, sizeof(hash_entry)); } ((hash_entry *) hstuff(hash_table))->mpq_a = mpq_a; ((hash_entry *) hstuff(hash_table))->entry = entry; @@ -155,14 +158,8 @@ int mpqlib_fs_filelist(char * buffer) { void mpqlib_fs_shutdown() { if (!hash_table) return; -/* - if (hfirst(hash_table)) do { - free(hstuff(hash_table)); - free(hkey(hash_table)); - } while (hnext(hash_table)); -*/ - st_shutdown(); + st_destroy(st); hdestroy(hash_table); hash_table = 0; } diff --git a/stalloc.c b/stalloc.c index 0b9530c..6a2eb7b 100644 --- a/stalloc.c +++ b/stalloc.c @@ -1,64 +1,87 @@ #include #include -static int nb_pools = 0; -static char ** mem_pools = 0; -static size_t * pools_size = 0; +#include "stalloc.h" + +struct st_alloc_t { + int nb_pools; + char ** mem_pools; + size_t * pools_size; +}; + +struct st_alloc_t * st_init() { + struct st_alloc_t * r = (struct st_alloc_t *) malloc(sizeof(struct st_alloc_t)); + + if (r) { + r->nb_pools = 0; + r->mem_pools = 0; + r->pools_size = 0; + } + + return r; +} #define POOL_SIZE 16384 -static int create_pool() { - nb_pools++; - mem_pools = (char **) realloc(mem_pools, sizeof(char *) * nb_pools); - pools_size = (size_t *) realloc(pools_size, sizeof(size_t) * nb_pools); - mem_pools[nb_pools - 1] = malloc(POOL_SIZE); - pools_size[nb_pools - 1] = 0; +static int create_pool(struct st_alloc_t * s) { + s->nb_pools++; + // No error checking, because it'd be a pain to handle. + s->mem_pools = (char **) realloc(s->mem_pools, sizeof(char *) * s->nb_pools); + s->pools_size = (size_t *) realloc(s->pools_size, sizeof(size_t) * s->nb_pools); + s->mem_pools[s->nb_pools - 1] = malloc(POOL_SIZE); + s->pools_size[s->nb_pools - 1] = 0; - return nb_pools - 1; + return s->nb_pools - 1; } -static int search_pool(size_t s) { +static int search_pool(struct st_alloc_t * s, size_t siz) { int i; // This algorithm could use a little bit more of cleverness, but... *shrug* // the whole purpose is to be used for small static strings, so... - for (i = 0; i < nb_pools; i++) { - if (s <= (POOL_SIZE - pools_size[i])) + for (i = 0; i < s->nb_pools; i++) { + if (siz <= (POOL_SIZE - s->pools_size[i])) return i; } return -1; } -void * st_alloc(size_t s) { +void * st_alloc(struct st_alloc_t * s, size_t siz) { int pool; - if (s > POOL_SIZE) - return malloc(s); + if (siz > POOL_SIZE) { + pool = create_pool(s); + s->mem_pools[pool] = realloc(s->mem_pools[pool], siz); + s->pools_size[pool] = siz; + return s->mem_pools[pool]; + } - pool = search_pool(s); + pool = search_pool(s, siz); if (pool < 0) - pool = create_pool(); + pool = create_pool(s); - pools_size[pool] += s; + s->pools_size[pool] += siz; - return mem_pools[pool] + pools_size[pool] - s; + return s->mem_pools[pool] + s->pools_size[pool] - siz; } -char * st_strdup(const char * src) { - int s = strlen(src) + 1; - char * r = (char *) st_alloc(s); - memcpy(r, src, s); +char * st_strdup(struct st_alloc_t * s, const char * src) { + int siz = strlen(src) + 1; + char * r = (char *) st_alloc(s, siz); + memcpy(r, src, siz); return r; } -void st_shutdown() { +void st_destroy(struct st_alloc_t * s) { int i; - for (i = 0; i < nb_pools; i++) { - free(mem_pools[i]); + for (i = 0; i < s->nb_pools; i++) { + free(s->mem_pools[i]); } - free(mem_pools); - free(pools_size); + free(s->mem_pools); + free(s->pools_size); + + free(s); } diff --git a/stalloc.h b/stalloc.h index 4d5cbce..892767e 100644 --- a/stalloc.h +++ b/stalloc.h @@ -1,8 +1,11 @@ #ifndef __STALLOC_H__ #define __STALLOC_H__ -void * st_alloc(size_t s); -char * st_strdup(const char * src); -void st_shutdown(); +struct st_alloc_t; + +struct st_alloc_t * st_init(); +void * st_alloc(struct st_alloc_t * s, size_t siz); +char * st_strdup(struct st_alloc_t * s, const char * src); +void st_destroy(struct st_alloc_t * s); #endif -- cgit v1.2.3