Added Pools

git-svn-id: https://swig.svn.sourceforge.net/svnroot/swig/trunk/SWIG@7 626c5289-ae23-0410-ae9c-e8d60b6d4f22
This commit is contained in:
Dave Beazley 1999-08-05 22:44:02 +00:00
commit e57db77e74
8 changed files with 265 additions and 60 deletions

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
/* -----------------------------------------------------------------------------

View file

@ -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);
}
/* -----------------------------------------------------------------------------

194
Source/DOH/Doh/memory.c Normal file
View file

@ -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;
}

View file

@ -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;

View file

@ -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; \