]> git.lizzy.rs Git - plan9front.git/blob - sys/lib/acid/pool
merge
[plan9front.git] / sys / lib / acid / pool
1 include("/sys/src/libc/port/pool.acid");
2
3 aggr Byte {
4         'b' 0 byte;
5 };
6
7 defn
8 byteat(addr)
9 {
10         local x;
11         complex Byte addr;
12         x = addr.byte;
13         return x\d;
14 }
15
16 defn
17 B2T(addr) {
18         complex Bhdr addr;
19         addr = addr+addr.size-sizeofBtail;
20         complex Btail addr;
21         return addr;
22 }
23
24 defn
25 B2D(addr) {
26         local x;
27         x = addr+sizeofBhdr;
28         return x\X;
29 }
30
31 defn
32 D2B(addr) {
33         local x;
34         x = addr-sizeofBhdr;
35         complex Bhdr x;
36         return x;
37 }
38
39 defn
40 B2NB(addr) {
41         complex Bhdr addr;
42         addr = addr+addr.size;
43         complex Bhdr addr;
44         return addr;
45 }
46
47 defn
48 A2TB(addr) {
49         local b;
50         complex Arena addr;
51         b = addr+addr.asize-sizeofBhdr;
52         complex Bhdr b;
53         return b;
54 }
55
56 defn
57 A2B(addr) {
58         return B2NB(addr);
59 }
60
61 defn
62 B2PT(addr) {
63         complex Bhdr addr;
64         addr = addr-sizeofBtail;
65         complex Btail addr;
66         return addr;
67 }
68
69 defn
70 SHORT(addr) {
71         local hi, lo;
72
73         hi = byteat(addr);
74         lo = byteat(addr+1);
75         return lo+hi*256;
76 }
77
78 defn
79 Btail(addr) {
80         complex Btail addr;
81         print(" magic0  ", addr.magic0, "\n");
82         print(" datadiff        ", SHORT(addr.datasize), "\n");
83         print(" magic1  ", addr.magic1, "\n");
84         print(" size    ", addr.size\X, "\n");
85         print(" hdr     ", addr+sizeofBtail-addr.size\X, "\n");
86 };
87
88 defn
89 Tail(addr)
90 {
91         print(" ", B2T(addr)\X, "\n");
92         Btail(B2T(addr));
93 }
94
95 defn
96 Magic(m)
97 {
98         if m == DEAD_MAGIC then
99                 return "dead";
100         if m == FREE_MAGIC then
101                 return "free";
102         if m == ALLOC_MAGIC then
103                 return "alloc";
104         if m == UNALLOC_MAGIC then
105                 return "unalloc";
106         if m == ARENA_MAGIC then
107                 return "arena";
108         if m == ARENATAIL_MAGIC then
109                 return "arenatail";
110         if m == ALIGN_MAGIC then
111                 return "align";
112         if m == FLOATING_MAGIC then
113                 return "floating";
114         return "unknown magic";
115 }
116
117 defn
118 Block(addr)
119 {
120         complex Bhdr addr;
121         print(" ", Magic(addr.magic), "\n");
122         print(" data ", B2D(addr), "\n");
123         print(" datasize ", getdsize(addr), "\n");
124         Bhdr(addr);
125         Tail(addr);
126 }
127
128 defn
129 getdsize(addr)
130 {
131         complex Bhdr addr;
132         local x;
133
134         x = addr.size\d;
135         x = x-SHORT(B2T(addr).datasize);
136         return x\d;
137 }
138
139 defn
140 datamagic(x)
141 {
142         x = x%4;
143         if x == 0 then return 0xFE;
144         if x == 1 then return 0xF1;
145         if x == 2 then return 0xF0;
146         if x == 3 then return 0xFA;
147 }
148
149 defn
150 checkblock(addr)
151 {
152         local badmagic, datamagic, a, b, t, q, n, dsize, taddr, checked;
153         complex Bhdr addr;
154         taddr = B2T(addr);
155         complex Btail taddr;
156
157         if addr.magic == FREE_MAGIC || addr.magic == UNALLOC_MAGIC then {
158                 if taddr.magic0 != TAIL_MAGIC0 || taddr.magic1 != TAIL_MAGIC1 then
159                         print(addr\X, " corrupt tail magic\n");
160                 if taddr.size != addr.size then
161                         print(addr\X, " corrupt tail header pointer\n");
162         }
163
164         if addr.magic == ARENA_MAGIC then {
165                 taddr = A2TB(addr);
166                 if taddr.magic != ARENATAIL_MAGIC then
167                         print(addr\X, " arena with bad tail block\n");
168                 else
169                         addr = taddr;
170         }
171
172         if addr.magic == ARENATAIL_MAGIC then {
173                 if addr.size != 0 then
174                         print(addr\X, " bad size in arena tail\n");
175         }
176
177         if addr.magic == ALLOC_MAGIC then {
178                 a = addr;
179                 complex Alloc a;
180                 if a.size > 1024*1024*1024 then 
181                         print(addr\X, " block ridiculously large\n");
182                 t = B2T(addr);
183                 if t.magic0 != TAIL_MAGIC0 || t.magic1 != TAIL_MAGIC1 then
184                         print(addr\X, " bad tail magic\n");
185                 if t.size != addr.size then
186                         print(addr\X, " bad tail pointer\n");
187                 dsize = getdsize(a);
188                 if dsize > a.size then
189                         print(addr\X, " too much data in block\n");
190                 q = B2D(a)\X+dsize;
191                 n = 4;
192                 if q+4 > t then
193                         n = t-q;
194                 badmagic = 0;
195                 loop 0,n-1 do {
196                         if byteat(q) != datamagic(q) then {
197                                 badmagic=1;
198                         }
199                         q = q+1;
200                 }
201                 if badmagic then
202                         print(addr\X, " size ", dsize, " user has overwritten boundary\n");
203         }
204 }
205
206 defn
207 checkarena(arena)
208 {
209         local atail, b;
210
211         atail = A2TB(arena);
212         complex Bhdr arena;
213         b = arena;
214         while b.magic != ARENATAIL_MAGIC && b < atail do {
215                 checkblock(b);
216                 if B2NB(b) == b then {
217                         print("B2NB(", b\X, ") = b\n");
218                         b = atail;      // end loop
219                 }
220                 b = B2NB(b);
221         }
222
223         checkblock(b);
224         if b != atail then
225                 print("found wrong tail to arena ", arena\X, "\n");
226 }
227
228 defn
229 checkpool(p)
230 {
231         complex Pool p;
232         local a;
233         a = p.arenalist;
234
235         while a != 0 do {
236                 complex Arena a;
237                 checkarena(a);
238                 a = a.down;
239         }
240 }
241
242 defn
243 gendumptree(f, in, s)
244 {
245         complex Free f;
246
247         loop 1,in do {print(" ");}
248         print(s, " size ", f.size\D, " left ", f.left\X, " right ", f.right\X, "\n");
249         if f.left != 0 then
250                 gendumptree(f.left, in+1, "l");
251         if f.right != 0 then
252                 gendumptree(f.right, in+1, "r");
253 }
254
255 defn
256 dumptree(f)
257 {
258         gendumptree(f, 0, "*");
259 }
260
261 defn
262 poolwhopointsat(p, addr)
263 {
264         complex Pool p;
265         local a;
266
267         a = p.arenalist;
268         while a != 0 do {
269                 complex Arena a;
270                 arenawhopointsat(a, addr);
271                 a = a.down;
272         }
273 }
274
275 defn 
276 arenawhopointsat(arena, addr)
277 {
278         local atail, b;
279
280         atail = A2TB(arena);
281         complex Bhdr arena;
282         b = arena;
283         while b < atail do {
284                 if *b == addr then 
285                         print(b\X, "\n");
286                 b = b+4;
287         }
288 }
289
290 defn
291 whopointsat(addr)
292 {
293         poolwhopointsat(*mainmem, addr);
294 }
295
296 defn
297 blockhdr(addr)
298 {
299         addr = addr & ~3;
300
301         while *addr != FREE_MAGIC 
302                 && *addr !=  ARENA_MAGIC
303                 && *addr != UNALLOC_MAGIC
304                 && *addr != ALLOC_MAGIC
305                 && *addr != ARENATAIL_MAGIC
306         do
307                 addr = addr-4;
308         return addr;
309 }
310