diff options
Diffstat (limited to 'lcc/src/alloc.c')
-rwxr-xr-x | lcc/src/alloc.c | 188 |
1 files changed, 94 insertions, 94 deletions
diff --git a/lcc/src/alloc.c b/lcc/src/alloc.c index 698da4f..e0566df 100755 --- a/lcc/src/alloc.c +++ b/lcc/src/alloc.c @@ -1,94 +1,94 @@ -#include "c.h"
-struct block {
- struct block *next;
- char *limit;
- char *avail;
-};
-union align {
- long l;
- char *p;
- double d;
- int (*f)(void);
-};
-union header {
- struct block b;
- union align a;
-};
-#ifdef PURIFY
-union header *arena[3];
-
-void *allocate(unsigned long n, unsigned 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(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(unsigned long m, unsigned long n, unsigned a) {
- return allocate(m*n, a);
-}
-#else
-static struct block
- first[] = { { NULL }, { NULL }, { NULL } },
- *arena[] = { &first[0], &first[1], &first[2] };
-static struct block *freeblocks;
-
-void *allocate(unsigned long n, unsigned a) {
- struct block *ap;
-
- assert(a < NELEMS(arena));
- assert(n > 0);
- ap = arena[a];
- n = roundup(n, sizeof (union align));
- while (n > ap->limit - ap->avail) {
- if ((ap->next = freeblocks) != NULL) {
- freeblocks = freeblocks->next;
- ap = ap->next;
- } else
- {
- unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align));
- ap->next = malloc(m);
- ap = ap->next;
- if (ap == NULL) {
- error("insufficient memory\n");
- exit(1);
- }
- ap->limit = (char *)ap + m;
- }
- 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
+#include "c.h" +struct block { + struct block *next; + char *limit; + char *avail; +}; +union align { + long l; + char *p; + double d; + int (*f)(void); +}; +union header { + struct block b; + union align a; +}; +#ifdef PURIFY +union header *arena[3]; + +void *allocate(unsigned long n, unsigned 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(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(unsigned long m, unsigned long n, unsigned a) { + return allocate(m*n, a); +} +#else +static struct block + first[] = { { NULL }, { NULL }, { NULL } }, + *arena[] = { &first[0], &first[1], &first[2] }; +static struct block *freeblocks; + +void *allocate(unsigned long n, unsigned a) { + struct block *ap; + + assert(a < NELEMS(arena)); + assert(n > 0); + ap = arena[a]; + n = roundup(n, sizeof (union align)); + while (n > ap->limit - ap->avail) { + if ((ap->next = freeblocks) != NULL) { + freeblocks = freeblocks->next; + ap = ap->next; + } else + { + unsigned m = sizeof (union header) + n + roundup(10*1024, sizeof (union align)); + ap->next = malloc(m); + ap = ap->next; + if (ap == NULL) { + error("insufficient memory\n"); + exit(1); + } + ap->limit = (char *)ap + m; + } + 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 |