alloc.c (1866B)
1 #include "c.h" 2 struct block { 3 struct block *next; 4 char *limit; 5 char *avail; 6 }; 7 union align { 8 long l; 9 char *p; 10 double d; 11 int (*f)(void); 12 }; 13 union header { 14 struct block b; 15 union align a; 16 }; 17 #ifdef PURIFY 18 union header *arena[3]; 19 20 void *allocate(unsigned long n, unsigned a) { 21 union header *new = malloc(sizeof *new + n); 22 23 assert(a < NELEMS(arena)); 24 if (new == NULL) { 25 error("insufficient memory\n"); 26 exit(1); 27 } 28 new->b.next = (void *)arena[a]; 29 arena[a] = new; 30 return new + 1; 31 } 32 33 void deallocate(unsigned a) { 34 union header *p, *q; 35 36 assert(a < NELEMS(arena)); 37 for (p = arena[a]; p; p = q) { 38 q = (void *)p->b.next; 39 free(p); 40 } 41 arena[a] = NULL; 42 } 43 44 void *newarray(unsigned long m, unsigned long n, unsigned a) { 45 return allocate(m*n, a); 46 } 47 #else 48 static struct block 49 first[] = { { NULL }, { NULL }, { NULL } }, 50 *arena[] = { &first[0], &first[1], &first[2] }; 51 static struct block *freeblocks; 52 53 void *allocate(unsigned long n, unsigned a) { 54 struct block *ap; 55 56 assert(a < NELEMS(arena)); 57 assert(n > 0); 58 ap = arena[a]; 59 n = roundup(n, sizeof (union align)); 60 while (n > ap->limit - ap->avail) { 61 if ((ap->next = freeblocks) != NULL) { 62 freeblocks = freeblocks->next; 63 ap = ap->next; 64 } else 65 { 66 unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align)); 67 ap->next = malloc(m); 68 ap = ap->next; 69 if (ap == NULL) { 70 error("insufficient memory\n"); 71 exit(1); 72 } 73 ap->limit = (char *)ap + m; 74 } 75 ap->avail = (char *)((union header *)ap + 1); 76 ap->next = NULL; 77 arena[a] = ap; 78 79 } 80 ap->avail += n; 81 return ap->avail - n; 82 } 83 84 void *newarray(unsigned long m, unsigned long n, unsigned a) { 85 return allocate(m*n, a); 86 } 87 void deallocate(unsigned a) { 88 assert(a < NELEMS(arena)); 89 arena[a]->next = freeblocks; 90 freeblocks = first[a].next; 91 first[a].next = NULL; 92 arena[a] = &first[a]; 93 } 94 #endif