Blob
1 #include <u.h>2 #include <libc.h>3 #include <bin.h>5 enum6 {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 };11 enum12 {13 BinSize = 8*102414 };16 struct Bin17 {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 };26 /*27 * allocator which allows an entire set to be freed at one time28 */29 static Bin*30 mkbin(Bin *bin, ulong size)31 {32 Bin *b;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 }47 void*48 binalloc(Bin **bin, ulong size, int zero)49 {50 Bin *b;51 ulong p;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 }78 void*79 bingrow(Bin **bin, void *op, ulong osize, ulong size, int zero)80 {81 Bin *b;82 void *np;83 ulong p;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 }100 void101 binfree(Bin **bin)102 {103 Bin *last;105 while(*bin != nil){106 last = *bin;107 *bin = (*bin)->next;108 last->pos = (ulong)last->body;109 free(last);110 }111 }