bin.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 }