From 89d7365595f26c5a341618934ff49dbdef2abbe4 Mon Sep 17 00:00:00 2001 From: Dave Beazley Date: Thu, 5 Aug 1999 22:44:02 +0000 Subject: [PATCH] Added Pools git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk@7 626c5289-ae23-0410-ae9c-e8d60b6d4f22 --- SWIG/Source/DOH/Doh/Makefile | 4 +- SWIG/Source/DOH/Doh/base.c | 54 ++++------ SWIG/Source/DOH/Doh/file.c | 25 +++-- SWIG/Source/DOH/Doh/hash.c | 10 +- SWIG/Source/DOH/Doh/list.c | 10 +- SWIG/Source/DOH/Doh/memory.c | 194 ++++++++++++++++++++++++++++++++++ SWIG/Source/DOH/Doh/string.c | 10 +- SWIG/Source/DOH/Include/doh.h | 18 ++-- 8 files changed, 265 insertions(+), 60 deletions(-) create mode 100644 SWIG/Source/DOH/Doh/memory.c diff --git a/SWIG/Source/DOH/Doh/Makefile b/SWIG/Source/DOH/Doh/Makefile index 56e8cca00..02c18a994 100644 --- a/SWIG/Source/DOH/Doh/Makefile +++ b/SWIG/Source/DOH/Doh/Makefile @@ -24,9 +24,9 @@ AR = ar # Normally, you shouldn't have to change anything below this point # ######################################################################## -LIBOBJS = base.o file.o list.o hash.o string.o +LIBOBJS = memory.o base.o file.o list.o hash.o string.o -LIBSRCS = base.c file.c list.c hash.c string.c +LIBSRCS = memory.c base.c file.c list.c hash.c string.c LIBHEADERS = ../Include/doh.h LIB = ../libdoh.a diff --git a/SWIG/Source/DOH/Doh/base.c b/SWIG/Source/DOH/Doh/base.c index a9c5f4fb2..7c6d2e404 100644 --- a/SWIG/Source/DOH/Doh/base.c +++ b/SWIG/Source/DOH/Doh/base.c @@ -24,34 +24,30 @@ #include "doh.h" static DohObjInfo DohBaseType = { - "Base", /* objname */ - 0, /* objsize */ - 0, /* doh_del */ - 0, /* doh_copy */ - 0, /* doh_clear */ - 0, /* doh_str */ - 0, /* doh_data */ - 0, /* doh_len */ - 0, /* doh_hash */ - 0, /* doh_cmp */ - 0, /* doh_mapping */ - 0, /* doh_sequence */ - 0, /* doh_file */ - 0, /* reserved2 */ - 0, /* reserved3 */ - 0, /* reserved4 */ - { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, + "Base", /* objname */ + sizeof(DohBase), /* objsize */ + 0, /* doh_del */ + 0, /* doh_copy */ + 0, /* doh_clear */ + 0, /* doh_str */ + 0, /* doh_data */ + 0, /* doh_len */ + 0, /* doh_hash */ + 0, /* doh_cmp */ + 0, /* doh_mapping */ + 0, /* doh_sequence */ + 0, /* doh_file */ + 0, /* reserved2 */ + 0, /* reserved3 */ + 0, /* reserved4 */ + 0, /* reserved5 */ + 0, /* reserved6 */ + 0, /* user1 */ + 0, /* user2 */ + 0, /* user3 */ + 0, /* user4 */ }; -/* Check if a Doh object */ -int DohCheck(DOH *obj) { - DohBase *b = (DohBase *) obj; - if (!b) return 0; - if (b->magic != DOH_MAGIC) return 0; - if (!b->objinfo) return 0; - return 1; -} - /* ----------------------------------------------------------------------------- String objects @@ -183,7 +179,7 @@ void *DohData(DOH *obj) { DohBase *b = (DohBase *) obj; c = (char *) obj; if (!c) return 0; - if (*c == DOH_MAGIC) { + if (DohCheck(c)) { if (b->objinfo) { if (b->objinfo->doh_data) { return (b->objinfo->doh_data)(obj); @@ -648,10 +644,6 @@ void DohInit(DOH *b) { DohBase *bs = (DohBase *) b; bs->refcount =0; bs->objinfo = &DohBaseType; - bs->magic = DOH_MAGIC; - bs->moremagic[0] = 0; - bs->moremagic[1] = 0; - bs->moremagic[2] = 0; bs->line = 0; bs->file = 0; } diff --git a/SWIG/Source/DOH/Doh/file.c b/SWIG/Source/DOH/Doh/file.c index d39583c28..1d93bf1df 100644 --- a/SWIG/Source/DOH/Doh/file.c +++ b/SWIG/Source/DOH/Doh/file.c @@ -25,6 +25,7 @@ typedef struct File { DOHCOMMON; FILE *filep; + int closeondel; } File; /* Forward references */ @@ -46,7 +47,7 @@ static DohFileMethods FileFileMethods = { static DohObjInfo FileType = { "File", /* objname */ - 0, + sizeof(File), /* objsize */ DelFile, /* sm_del */ 0, /* sm_copy */ 0, /* sm_clear */ @@ -79,26 +80,32 @@ NewFile(char *filename, char *mode) file = fopen(filename,mode); if (!file) return 0; - f = (File *) malloc(sizeof(File)); + f = (File *) DohMalloc(sizeof(File)); + if (!f) { + fclose(file); + return 0; + } DohInit(f); f->objinfo = &FileType; f->filep = file; + f->closeondel = 1; return (DOH *) f; } /* ----------------------------------------------------------------------------- * NewFileFromFile(FILE *f) - * * ----------------------------------------------------------------------------- */ DOH * NewFileFromFile(FILE *file) { File *f; - f = (File *) malloc(sizeof(File)); + f = (File *) DohMalloc(sizeof(File)); + if (!f) return 0; DohInit(f); f->objinfo = &FileType; f->filep = file; + f->closeondel = 0; return (DOH *) f; } @@ -109,8 +116,9 @@ void DelFile(DOH *so) { File *f = (File *) so; assert(f->refcount <= 0); - fclose(f->filep); - free(f); + if (f->closeondel) + fclose(f->filep); + DohFree(f); } /* ----------------------------------------------------------------------------- @@ -119,6 +127,11 @@ DelFile(DOH *so) { int File_check(DOH *f) { + File *df; + if (!DohCheck(f)) return 0; + + df = (File *) f; + if (df->objinfo == &FileType) return 1; return 0; } diff --git a/SWIG/Source/DOH/Doh/hash.c b/SWIG/Source/DOH/Doh/hash.c index 702b3b152..ab1176cea 100644 --- a/SWIG/Source/DOH/Doh/hash.c +++ b/SWIG/Source/DOH/Doh/hash.c @@ -83,7 +83,7 @@ static DohMappingMethods HashMappingMethods = { static DohObjInfo HashType = { "Hash", /* objname */ - 0, + sizeof(Hash), /* size */ DelHash, /* sm_del */ CopyHash, /* sm_copy */ Hash_clear, /* sm_clear */ @@ -108,7 +108,7 @@ DohObjInfo *Hash_type() { int Hash_check(DOH *so) { Hash *h = (Hash *) so; if (!h) return 0; - if (h->magic != DOH_MAGIC) return 0; + if (!DohCheck(so)) return 0; if (h->objinfo != &HashType) return 0; return 1; } @@ -120,7 +120,7 @@ int Hash_check(DOH *so) { DOH *NewHash() { Hash *h; int i; - h = (Hash *) malloc(sizeof(Hash)); + h = (Hash *) DohMalloc(sizeof(Hash)); DohInit(h); h->hashsize = HASH_INIT_SIZE; h->hashtable = (HashNode **) malloc(h->hashsize*sizeof(HashNode *)); @@ -145,7 +145,7 @@ DOH *CopyHash(DOH *ho) { DOH *key; h = (Hash *) ho; - nh = (Hash *) malloc(sizeof(Hash)); + nh = (Hash *) DohMalloc(sizeof(Hash)); DohInit(nh); nh->hashsize = h->hashsize; @@ -190,7 +190,7 @@ void DelHash(DOH *ho) } } free(h->hashtable); - free(h); + DohFree(h); } /* ----------------------------------------------------------------------------- diff --git a/SWIG/Source/DOH/Doh/list.c b/SWIG/Source/DOH/Doh/list.c index 655203994..14e9841ae 100644 --- a/SWIG/Source/DOH/Doh/list.c +++ b/SWIG/Source/DOH/Doh/list.c @@ -59,7 +59,7 @@ static DohSequenceMethods ListSeqMethods = { static DohObjInfo ListType = { "List", /* objname */ - 0, + sizeof(List), /* List size */ DelList, /* sm_del */ CopyList, /* sm_copy */ List_clear, /* sm_clear */ @@ -107,7 +107,7 @@ int List_check(DOH *lo) { List *l = (List *) lo; if (!l) return 0; - if (l->magic != DOH_MAGIC) return 0; + if (!DohCheck(lo)) return 0; if (l->objinfo != &ListType) return 0; return 1; } @@ -120,7 +120,7 @@ DOH * NewList() { List *l; int i; - l = (List *) malloc(sizeof(List)); + l = (List *) DohMalloc(sizeof(List)); DohInit(l); l->objinfo = &ListType; l->nitems = 0; @@ -142,7 +142,7 @@ CopyList(DOH *lo) { List *l,*nl; int i; l = (List *) lo; - nl = (List *) malloc(sizeof(List)); + nl = (List *) DohMalloc(sizeof(List)); DohInit(nl); nl->objinfo = l->objinfo; nl->nitems = l->nitems; @@ -172,7 +172,7 @@ DelList(DOH *lo) { Delete(l->items[i]); } free(l->items); - free(l); + DohFree(l); } /* ----------------------------------------------------------------------------- diff --git a/SWIG/Source/DOH/Doh/memory.c b/SWIG/Source/DOH/Doh/memory.c new file mode 100644 index 000000000..bdb1c3112 --- /dev/null +++ b/SWIG/Source/DOH/Doh/memory.c @@ -0,0 +1,194 @@ +/**************************************************************************** + * DOH (Dynamic Object Hack) + * + * Author : David Beazley + * + * Department of Computer Science + * University of Chicago + * 1100 E 58th Street + * Chicago, IL 60637 + * beazley@cs.uchicago.edu + * + * Please read the file LICENSE for the copyright and terms by which SWIG + * can be used and distributed. + ****************************************************************************/ + +#include "doh.h" + +#ifndef DOH_POOL_SIZE +#define DOH_POOL_SIZE 65536 +#endif + +#ifndef DOH_MAX_FRAG +#define DOH_MAX_FRAG 1024 +#endif + +/* ----------------------------------------------------------------------------- + * memory.c + * + * Doh memory manager. Keeps pools of memory around for allocating objects. + * Pools are used to determine if an object is really a Doh object or not. + * ----------------------------------------------------------------------------- */ + +typedef struct fragment { + char *ptr; /* Pointer to fragment */ + int len; /* Length of fragment */ + struct fragment *next; /* Next fragment */ +} Fragment; + +static Fragment *FreeFragments[DOH_MAX_FRAG]; + +typedef struct pool { + char *ptr; /* Start of pool */ + int len; /* Length of pool */ + int current; /* Current position for next allocation */ + struct pool *next; /* Next pool */ +} Pool; + +static Pool *Pools = 0; +static int pools_initialized = 0; + +/* ---------------------------------------------------------------------- + * Pool *CreatePool(int size) + * + * Create a new pool + * ---------------------------------------------------------------------- */ + +Pool *CreatePool(int size) +{ + Pool *p = 0; + char *c; + c = (char *) malloc(size); + if (!c) return 0; + + p = (Pool *) malloc(sizeof(Pool)); + p->ptr = c; + p->len = size; + p->current = 0; + p->next = 0; + printf("Created pool : %x, %d\n", p->ptr, size); + return p; +} + +/* ---------------------------------------------------------------------- + * void InitPools() + * + * Initialize the memory allocator + * ---------------------------------------------------------------------- */ + +static void InitPools() { + int i; + if (pools_initialized) return; + for (i = 0; i < 1024; i++) { + FreeFragments[i] = 0; + } + Pools = CreatePool(DOH_POOL_SIZE); /* Create initial pool */ + pools_initialized = 1; +} + +/* ---------------------------------------------------------------------- + * int DohCheck(DOH *ptr) + * + * Check if ptr is an object we created. + * ---------------------------------------------------------------------- */ + +int DohCheck(DOH *ptr) { + Pool *p = Pools; + char *cptr = (char *) ptr; + while (p) { + if ((cptr >= p->ptr) && (cptr < p->ptr+p->current)) return 1; + p = p->next; + } + return 0; +} + +/* ---------------------------------------------------------------------- + * int DohFreeCheck(DOH *ptr) + * + * Check if ptr is an object that has been deleted. + * ---------------------------------------------------------------------- */ + +int DohFreeCheck(DOH *ptr) { + int i; + Fragment *f; + char *cptr = (char *) ptr; + for (i = 0; i < DOH_MAX_FRAG; i++) { + f = FreeFragments[i]; + while (f) { + if (f->ptr == cptr) return 1; + f = f->next; + } + } + return 0; +} + +/* ---------------------------------------------------------------------- + * void *DohMalloc(int size) + * + * Allocate an object + * ---------------------------------------------------------------------- */ + +void *DohMalloc(int size) { + Pool *p; + Fragment *f; + void *ptr; + + if (size > DOH_MAX_FRAG) return 0; + if (!pools_initialized) InitPools(); + + p = Pools; + f = FreeFragments[size]; + if (f) { + ptr = (void *) f->ptr; + FreeFragments[size] = f->next; + free(f); + return ptr; + } + + /* No free fragments. See if the pool is large enough */ + + if (size < (p->len - p->current)) { + ptr = (void *) (p->ptr + p->current); + p->current = (p->current + size + 7) & ~0x3; + return ptr; + } + + /* Pool is not large enough. Create a new pool */ + + if (p->len - p->current > 0) { + f = (Fragment *) malloc(sizeof(Fragment)); + f->ptr = (p->ptr + p->current); + f->len = (p->len - p->current); + f->next = FreeFragments[f->len]; + FreeFragments[f->len] = f; + } + p = CreatePool(DOH_POOL_SIZE); + p->next = Pools; + Pools = p; + return DohMalloc(size); +} + +/* ---------------------------------------------------------------------- + * void DohFree(DOH *ptr) + * + * Free a DOH object. Important! It must be a properly allocated + * DOH object. Not something else. + * ---------------------------------------------------------------------- */ + +void DohFree(DOH *ptr) { + DohBase *b; + Fragment *f; + if (!DohCheck(ptr)) { + return; /* Oh well. Guess we're leaky */ + } + b = (DohBase *) ptr; + if (!b->objinfo) return; /* Improperly initialized object. leak some more */ + f = (Fragment *) malloc(sizeof(Fragment)); + f->ptr = (char *) ptr; + f->len = b->objinfo->objsize; + f->next = FreeFragments[f->len]; + FreeFragments[f->len] = f; +} + + + diff --git a/SWIG/Source/DOH/Doh/string.c b/SWIG/Source/DOH/Doh/string.c index 22e1c84b8..7bf62ed9e 100644 --- a/SWIG/Source/DOH/Doh/string.c +++ b/SWIG/Source/DOH/Doh/string.c @@ -75,7 +75,7 @@ static DohFileMethods StringFileMethods = { static DohObjInfo StringType = { "String", /* objname */ - 0, + sizeof(String), /* objsize */ DelString, /* sm_del */ CopyString, /* sm_copy */ String_clear, /* sm_clear */ @@ -114,7 +114,7 @@ NewString(char *s) { int l, max; String *str; - str = (String *) malloc(sizeof(String)); + str = (String *) DohMalloc(sizeof(String)); DohInit(str); str->objinfo = &StringType; str->hashkey = -1; @@ -147,7 +147,7 @@ CopyString(DOH *so) { int l, max; String *str; s = (String *) so; - str = (String *) malloc(sizeof(String)); + str = (String *) DohMalloc(sizeof(String)); DohInit(str); str->objinfo = &StringType; str->hashkey = -1; @@ -171,7 +171,7 @@ DelString(DOH *so) { s = (String *) so; assert(s->refcount <= 0); free(s->str); - free(s); + DohFree(s); } /* ----------------------------------------------------------------------------- @@ -182,7 +182,7 @@ String_check(DOH *s) { char *c = (char *) s; if (!s) return 0; - if (*c == DOH_MAGIC) { + if (DohCheck(s)) { if (((String *) c)->objinfo == &StringType) return 1; return 0; diff --git a/SWIG/Source/DOH/Include/doh.h b/SWIG/Source/DOH/Include/doh.h index 2011122d7..db5816e42 100644 --- a/SWIG/Source/DOH/Include/doh.h +++ b/SWIG/Source/DOH/Include/doh.h @@ -32,8 +32,6 @@ typedef void DOH; #define DOH_END -2 #define DOH_CUR -3 -#define DOH_MAGIC 0x04 - /* ----------------------------------------------------------------------------- * Object classes * ----------------------------------------------------------------------------- */ @@ -101,9 +99,20 @@ typedef struct DohObjInfo { void *reserved2; /* Number methods */ void *reserved3; void *reserved4; - void *user[16]; /* User extensions */ + void *reserved5; + void *reserved6; + void *user1; + void *user2; + void *user3; + void *user4; } DohObjInfo; +/* Memory management */ +extern void *DohMalloc(int size); +extern void DohFree(DOH *ptr); +extern int DohCheck(DOH *ptr); +extern int DohFreeCheck(DOH *ptr); + /* Low-level doh methods. Do not call directly (well, unless you want to). */ extern void DohDestroy(DOH *obj); @@ -135,7 +144,6 @@ extern int DohGetline(DOH *obj); extern void DohSetline(DOH *obj, int line); extern DOH *DohGetfile(DOH *obj); extern void DohSetfile(DOH *obj, DOH *file); -extern int DohCheck(DOH *obj); extern void DohInit(DOH *obj); /* File methods */ @@ -201,8 +209,6 @@ extern int DohvScanf(DOH *obj, char *format, va_list ap); * ----------------------------------------------------------------------------- */ #define DOHCOMMON \ - char magic; \ - char moremagic[3]; \ DohObjInfo *objinfo; \ int refcount; \ int line; \