home *** CD-ROM | disk | FTP | other *** search
- #include "c.h"
- #define ALLOCSIZE 64*1024
- struct block {
- struct block *next;
- char *limit;
- char *avail;
- };
- union align {
- long l;
- char *p;
- double d;
- int (*f) ARGS((void));
- };
- union header {
- struct block b;
- union align a;
- };
- #ifdef PURIFY
- union header *arena[4];
-
- void *allocate(n, a) unsigned long n, a; {
- union header *new = malloc(sizeof *new + n);
-
- assert(a < NELEMS(arena));
- if (new == NULL) {
- error("insufficient memory\n");
- exit(1);
- }
- new->b.next = (void *)arena[a];
- arena[a] = new;
- return new + 1;
- }
-
- void deallocate(a) unsigned a; {
- union header *p, *q;
-
- assert(a < NELEMS(arena));
- for (p = arena[a]; p; p = q) {
- q = (void *)p->b.next;
- free(p);
- }
- arena[a] = NULL;
- }
-
- void *newarray(m, n, a) unsigned long m, n; unsigned a; {
- return allocate(m*n, a);
- }
- #else
- #ifndef ASM_LIB
- static
- #endif
- struct block
- first[] = { { NULL }, { NULL }, { NULL },{NULL},{NULL} },
- *arena[] = { &first[0], &first[1], &first[2],&first[3],&first[4]};
- static struct block *freeblocks;
- int memused=0;
- void *allocateslow(register unsigned long n, unsigned a);
- #ifndef ASM_LIB
- void *allocate(unsigned long n,unsigned a)
- {
- struct block *ap;
- void *r=NULL;
- ap = arena[a];
- n = roundup(n, sizeof (union align));
- if (ap->avail + n <= ap->limit) {
- r = ap->avail;
- ap->avail += n;
- return r;
- }
- else
- return allocateslow(n,a);
- }
- #else
- extern void *allocate(unsigned long n,unsigned a);
- #endif
- extern void * _stdcall GlobalAlloc(unsigned int,unsigned long);
-
- void *allocateslow(register unsigned long n, unsigned a)
- {
- register struct block *ap;
-
- // assert(a < NELEMS(arena));
- // assert(n > 0);
- ap = arena[a];
- // n = roundup(n, sizeof (union align));
- while (ap->avail + n > ap->limit) {
- if ((ap->next = freeblocks) != NULL) {
- freeblocks = freeblocks->next;
- ap = ap->next;
- } else
- {
- ap->next = GlobalAlloc(0,ALLOCSIZE);
- ap = ap->next;
- if (ap == NULL) {
- error("insufficient memory\n");
- exit(1);
- }
- ap->limit = (char *)ap + ALLOCSIZE;
- memused += ALLOCSIZE;
- }
- ap->avail = (char *)((union header *)ap + 1);
- ap->next = NULL;
- arena[a] = ap;
-
- }
- ap->avail += n;
- return ap->avail - n;
- }
-
- void *newarray(unsigned long m,unsigned long n,unsigned a)
- {
- return allocate(m*n, a);
- }
- void deallocate(unsigned a)
- {
- assert(a < NELEMS(arena));
- arena[a]->next = freeblocks;
- freeblocks = first[a].next;
- first[a].next = NULL;
- arena[a] = &first[a];
- }
- #endif
-