Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

alloc.c

Go to the documentation of this file.
00001 #include "c.h"
00002 struct block {
00003     struct block *next;
00004     char *limit;
00005     char *avail;
00006 };
00007 union align {
00008     long l;
00009     char *p;
00010     double d;
00011     int (*f)(void);
00012 };
00013 union header {
00014     struct block b;
00015     union align a;
00016 };
00017 #ifdef PURIFY
00018 union header *arena[3];
00019 
00020 void *allocate(unsigned long n, unsigned a) {
00021     union header *new = malloc(sizeof *new + n);
00022 
00023     assert(a < NELEMS(arena));
00024     if (new == NULL) {
00025         error("insufficient memory\n");
00026         exit(1);
00027     }
00028     new->b.next = (void *)arena[a];
00029     arena[a] = new;
00030     return new + 1;
00031 }
00032 
00033 void deallocate(unsigned a) {
00034     union header *p, *q;
00035 
00036     assert(a < NELEMS(arena));
00037     for (p = arena[a]; p; p = q) {
00038         q = (void *)p->b.next;
00039         free(p);
00040     }
00041     arena[a] = NULL;
00042 }
00043 
00044 void *newarray(unsigned long m, unsigned long n, unsigned a) {
00045     return allocate(m*n, a);
00046 }
00047 #else
00048 static struct block
00049      first[] = {  { NULL },  { NULL },  { NULL } },
00050     *arena[] = { &first[0], &first[1], &first[2] };
00051 static struct block *freeblocks;
00052 
00053 void *allocate(unsigned long n, unsigned a) {
00054     struct block *ap;
00055 
00056     assert(a < NELEMS(arena));
00057     assert(n > 0);
00058     ap = arena[a];
00059     n = roundup(n, sizeof (union align));
00060     while (n > ap->limit - ap->avail) {
00061         if ((ap->next = freeblocks) != NULL) {
00062             freeblocks = freeblocks->next;
00063             ap = ap->next;
00064         } else
00065             {
00066                 unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align));
00067                 ap->next = malloc(m);
00068                 ap = ap->next;
00069                 if (ap == NULL) {
00070                     error("insufficient memory\n");
00071                     exit(1);
00072                 }
00073                 ap->limit = (char *)ap + m;
00074             }
00075         ap->avail = (char *)((union header *)ap + 1);
00076         ap->next = NULL;
00077         arena[a] = ap;
00078 
00079     }
00080     ap->avail += n;
00081     return ap->avail - n;
00082 }
00083 
00084 void *newarray(unsigned long m, unsigned long n, unsigned a) {
00085     return allocate(m*n, a);
00086 }
00087 void deallocate(unsigned a) {
00088     assert(a < NELEMS(arena));
00089     arena[a]->next = freeblocks;
00090     freeblocks = first[a].next;
00091     first[a].next = NULL;
00092     arena[a] = &first[a];
00093 }
00094 #endif

Generated on Thu Aug 25 12:38:12 2005 for Quake III Arena by  doxygen 1.3.9.1