URI:
       tbin.c - plan9port - [fork] Plan 9 from user space
  HTML git clone git://src.adamsgaard.dk/plan9port
   DIR Log
   DIR Files
   DIR Refs
   DIR README
   DIR LICENSE
       ---
       tbin.c (1811B)
       ---
            1 #include <u.h>
            2 #include <libc.h>
            3 #include <bin.h>
            4 
            5 enum
            6 {
            7         StructAlign = sizeof(union {vlong vl; double d; ulong p; void *v;
            8                                 struct{vlong v;}vs; struct{double d;}ds; struct{ulong p;}ss; struct{void *v;}xs;})
            9 };
           10 
           11 enum
           12 {
           13         BinSize        = 8*1024
           14 };
           15 
           16 struct Bin
           17 {
           18         Bin        *next;
           19         ulong        total;                        /* total bytes allocated in can->next */
           20         ulong        pos;
           21         ulong        end;
           22         ulong        v;                        /* last value allocated */
           23         uchar        body[BinSize];
           24 };
           25 
           26 /*
           27  * allocator which allows an entire set to be freed at one time
           28  */
           29 static Bin*
           30 mkbin(Bin *bin, ulong size)
           31 {
           32         Bin *b;
           33 
           34         size = ((size << 1) + (BinSize - 1)) & ~(BinSize - 1);
           35         b = malloc(sizeof(Bin) + size - BinSize);
           36         if(b == nil)
           37                 return nil;
           38         b->next = bin;
           39         b->total = 0;
           40         if(bin != nil)
           41                 b->total = bin->total + bin->pos - (ulong)bin->body;
           42         b->pos = (ulong)b->body;
           43         b->end = b->pos + size;
           44         return b;
           45 }
           46 
           47 void*
           48 binalloc(Bin **bin, ulong size, int zero)
           49 {
           50         Bin *b;
           51         ulong p;
           52 
           53         if(size == 0)
           54                 size = 1;
           55         b = *bin;
           56         if(b == nil){
           57                 b = mkbin(nil, size);
           58                 if(b == nil)
           59                         return nil;
           60                 *bin = b;
           61         }
           62         p = b->pos;
           63         p = (p + (StructAlign - 1)) & ~(StructAlign - 1);
           64         if(p + size > b->end){
           65                 b = mkbin(b, size);
           66                 if(b == nil)
           67                         return nil;
           68                 *bin = b;
           69                 p = b->pos;
           70         }
           71         b->pos = p + size;
           72         b->v = p;
           73         if(zero)
           74                 memset((void*)p, 0, size);
           75         return (void*)p;
           76 }
           77 
           78 void*
           79 bingrow(Bin **bin, void *op, ulong osize, ulong size, int zero)
           80 {
           81         Bin *b;
           82         void *np;
           83         ulong p;
           84 
           85         p = (ulong)op;
           86         b = *bin;
           87         if(b != nil && p == b->v && p + size <= b->end){
           88                 b->pos = p + size;
           89                 if(zero)
           90                         memset((char*)p + osize, 0, size - osize);
           91                 return op;
           92         }
           93         np = binalloc(bin, size, zero);
           94         if(np == nil)
           95                 return nil;
           96         memmove(np, op, osize);
           97         return np;
           98 }
           99 
          100 void
          101 binfree(Bin **bin)
          102 {
          103         Bin *last;
          104 
          105         while(*bin != nil){
          106                 last = *bin;
          107                 *bin = (*bin)->next;
          108                 last->pos = (ulong)last->body;
          109                 free(last);
          110         }
          111 }