alloc.c - scc - simple c99 compiler
(HTM) git clone git://git.simple-cc.org/scc
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) Submodules
(DIR) README
(DIR) LICENSE
---
alloc.c (2075B)
---
1 #include <stdlib.h>
2 #include <scc/scc.h>
3
4 /*
5 * This is the most pedantic piece of code that I have written
6 * in my life. The next union is used to enforce the alignment
7 * of the address returned by new(). A union has the alignment
8 * of the field with the biggest alignment. This union has all
9 * the types that we use in scc, and we round all the addresses
10 * to the alignment of this struct, so we can be sure that any
11 * pointer using that address will be safe. The field ap is
12 * in the union to be sure that struct pointers are included
13 * in the list, although they will have the same alignment or
14 * smaller than void *, but I wanted to be pedantic.
15 */
16 union hdr {
17 union hdr *next;
18 struct arena *ap;
19 char c;
20 unsigned char uc;
21 int i;
22 short s;
23 long l;
24 long long ll;
25 float f;
26 double d;
27 long double ld;
28 void *vp;
29 };
30
31 struct arena {
32 struct arena *next;
33 union hdr *array;
34 };
35
36 struct alloc {
37 size_t size;
38 size_t nmemb;
39 size_t padding;
40 struct arena *arena;
41 union hdr *freep;
42 };
43
44 static void
45 newarena(Alloc *allocp)
46 {
47 struct arena *ap;
48 union hdr *bp, *lim;
49 size_t unit, n = allocp->nmemb;
50
51 unit = (allocp->size-1) / sizeof(union hdr) + 1;
52 ap = xmalloc(sizeof(struct arena));
53 ap->array = xmalloc(unit * sizeof(union hdr) * n);
54
55 bp = ap->array;
56 for (lim = &bp[unit * (n-1)]; bp < lim; bp += unit)
57 bp->next = bp + unit;
58 bp->next = NULL;
59
60 ap->next = allocp->arena;
61 allocp->arena = ap;
62 allocp->freep = ap->array;
63 }
64
65 Alloc *
66 alloc(size_t size, size_t nmemb)
67 {
68 Alloc *allocp = xmalloc(sizeof(*allocp));
69
70 allocp->size = size;
71 allocp->nmemb = nmemb;
72 allocp->arena = NULL;
73 allocp->freep = NULL;
74
75 return allocp;
76 }
77
78 void
79 dealloc(Alloc *allocp)
80 {
81 struct arena *ap, *next;
82
83 for (ap = allocp->arena; ap; ap = next) {
84 next = ap->next;
85 free(ap->array);
86 free(ap);
87 }
88 free(allocp);
89 }
90
91 void *
92 new(Alloc *allocp)
93 {
94 union hdr *bp;
95
96 if (!allocp->freep)
97 newarena(allocp);
98 bp = allocp->freep;
99 allocp->freep = bp->next;
100
101 return bp;
102 }
103
104 void
105 delete(Alloc *allocp, void *p)
106 {
107 union hdr *bp = p;
108
109 bp->next = allocp->freep;
110 allocp->freep = bp;
111 }