]> git.lizzy.rs Git - plan9front.git/blob - sys/src/libbin/bin.c
vt, ssh: don't send interrupts on window resize
[plan9front.git] / sys / src / libbin / bin.c
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         uintptr pos;
21         uintptr end;
22         uintptr 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 - (uintptr)bin->body;
42         b->pos = (uintptr)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         uintptr 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         uintptr p;
84
85         p = (uintptr)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 = (uintptr)last->body;
109                 free(last);
110         }
111 }