Home
       alloc.c - scc - simple c99 compiler
  HTML 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 }