Blob


1 #include <u.h>
2 #include <libc.h>
3 #include <bin.h>
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 };
11 enum
12 {
13 BinSize = 8*1024
14 };
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 };
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;
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 void
101 binfree(Bin **bin)
103 Bin *last;
105 while(*bin != nil){
106 last = *bin;
107 *bin = (*bin)->next;
108 last->pos = (ulong)last->body;
109 free(last);