diff options
Diffstat (limited to 'Source/DOH/memory.c')
| -rw-r--r-- | Source/DOH/memory.c | 220 |
1 files changed, 220 insertions, 0 deletions
diff --git a/Source/DOH/memory.c b/Source/DOH/memory.c new file mode 100644 index 0000000..79ff21c --- /dev/null +++ b/Source/DOH/memory.c @@ -0,0 +1,220 @@ +/* ----------------------------------------------------------------------------- + * memory.c + * + * This file implements all of DOH's memory management including allocation + * of objects and checking of objects. + * + * Author(s) : David Beazley (beazley@cs.uchicago.edu) + * + * Copyright (C) 1999-2000. The University of Chicago + * See the file LICENSE for information on usage and redistribution. + * ----------------------------------------------------------------------------- */ + +char cvsroot_memory_c[] = "$Id: memory.c 9607 2006-12-05 22:11:40Z beazley $"; + +#include "dohint.h" + +#ifndef DOH_POOL_SIZE +#define DOH_POOL_SIZE 16384 +#endif + +static int PoolSize = DOH_POOL_SIZE; + +DOH *DohNone = 0; /* The DOH None object */ + +typedef struct pool { + DohBase *ptr; /* Start of pool */ + int len; /* Length of pool */ + int blen; /* Byte length of pool */ + int current; /* Current position for next allocation */ + char *pbeg; /* Beg of pool */ + char *pend; /* End of pool */ + struct pool *next; /* Next pool */ +} Pool; + +static DohBase *FreeList = 0; /* List of free objects */ +static Pool *Pools = 0; +static int pools_initialized = 0; + +/* ---------------------------------------------------------------------- + * CreatePool() - Create a new memory pool + * ---------------------------------------------------------------------- */ + +static void CreatePool() { + Pool *p = 0; + p = (Pool *) DohMalloc(sizeof(Pool)); + assert(p); + p->ptr = (DohBase *) DohMalloc(sizeof(DohBase) * PoolSize); + assert(p->ptr); + memset(p->ptr, 0, sizeof(DohBase) * PoolSize); + p->len = PoolSize; + p->blen = PoolSize * sizeof(DohBase); + p->current = 0; + p->pbeg = ((char *) p->ptr); + p->pend = p->pbeg + p->blen; + p->next = Pools; + Pools = p; +} + +/* ---------------------------------------------------------------------- + * InitPools() - Initialize the memory allocator + * ---------------------------------------------------------------------- */ + +static void InitPools() { + if (pools_initialized) + return; + CreatePool(); /* Create initial pool */ + pools_initialized = 1; + DohNone = NewVoid(0, 0); /* Create the None object */ + DohIntern(DohNone); +} + +/* ---------------------------------------------------------------------- + * DohCheck() + * + * Returns 1 if an arbitrary pointer is a DOH object. + * ---------------------------------------------------------------------- */ + +int DohCheck(const DOH *ptr) { + register Pool *p = Pools; + register char *cptr = (char *) ptr; + while (p) { + if ((cptr >= p->pbeg) && (cptr < p->pend)) + return 1; + /* + pptr = (char *) p->ptr; + if ((cptr >= pptr) && (cptr < (pptr+(p->current*sizeof(DohBase))))) return 1; */ + p = p->next; + } + return 0; +} + +/* ----------------------------------------------------------------------------- + * DohIntern() + * ----------------------------------------------------------------------------- */ + +void DohIntern(DOH *obj) { + DohBase *b = (DohBase *) obj; + b->flag_intern = 1; +} + +/* ---------------------------------------------------------------------- + * DohObjMalloc() + * + * Allocate memory for a new object. + * ---------------------------------------------------------------------- */ + +DOH *DohObjMalloc(DohObjInfo *type, void *data) { + DohBase *obj; + if (!pools_initialized) + InitPools(); + if (FreeList) { + obj = FreeList; + FreeList = (DohBase *) obj->data; + } else { + while (Pools->current == Pools->len) { + CreatePool(); + } + obj = Pools->ptr + Pools->current; + ++Pools->current; + } + obj->type = type; + obj->data = data; + obj->meta = 0; + obj->refcount = 1; + obj->flag_intern = 0; + obj->flag_marked = 0; + obj->flag_user = 0; + obj->flag_usermark = 0; + return (DOH *) obj; +} + +/* ---------------------------------------------------------------------- + * DohObjFree() - Free a DOH object + * ---------------------------------------------------------------------- */ + +void DohObjFree(DOH *ptr) { + DohBase *b, *meta; + b = (DohBase *) ptr; + if (b->flag_intern) + return; + meta = (DohBase *) b->meta; + b->data = (void *) FreeList; + b->meta = 0; + b->type = 0; + FreeList = b; + if (meta) { + Delete(meta); + } +} + +/* ---------------------------------------------------------------------- + * DohMemoryDebug() + * + * Display memory usage statistics + * ---------------------------------------------------------------------- */ + +void DohMemoryDebug(void) { + extern DohObjInfo DohStringType; + extern DohObjInfo DohListType; + extern DohObjInfo DohHashType; + + Pool *p; + int totsize = 0; + int totused = 0; + int totfree = 0; + + int numstring = 0; + int numlist = 0; + int numhash = 0; + + printf("Memory statistics:\n\n"); + printf("Pools:\n"); + + p = Pools; + while (p) { + /* Calculate number of used, free items */ + int i; + int nused = 0, nfree = 0; + for (i = 0; i < p->len; i++) { + if (p->ptr[i].refcount <= 0) + nfree++; + else { + nused++; + if (p->ptr[i].type == &DohStringType) + numstring++; + else if (p->ptr[i].type == &DohListType) + numlist++; + else if (p->ptr[i].type == &DohHashType) + numhash++; + } + } + printf(" Pool %8p: size = %10d. used = %10d. free = %10d\n", (void *) p, p->len, nused, nfree); + totsize += p->len; + totused += nused; + totfree += nfree; + p = p->next; + } + printf("\n Total: size = %10d, used = %10d, free = %10d\n", totsize, totused, totfree); + + printf("\nObject types\n"); + printf(" Strings : %d\n", numstring); + printf(" Lists : %d\n", numlist); + printf(" Hashes : %d\n", numhash); + +#if 0 + p = Pools; + while (p) { + int i; + for (i = 0; i < p->len; i++) { + if (p->ptr[i].refcount > 0) { + if (p->ptr[i].type == &DohStringType) { + Printf(stdout, "%s\n", p->ptr + i); + } + } + } + p = p->next; + } +#endif + +} |
