]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/port/allocb.c
pc kernel: fix wrong simd exception mask (fixes go bootstrap)
[plan9front.git] / sys / src / 9 / port / allocb.c
1 #include        "u.h"
2 #include        "../port/lib.h"
3 #include        "mem.h"
4 #include        "dat.h"
5 #include        "fns.h"
6 #include        "error.h"
7
8 enum
9 {
10         Hdrspc          = 64,           /* leave room for high-level headers */
11         Tlrspc          = 16,           /* extra room at the end for pad/crc/mac */
12         Bdead           = 0x51494F42,   /* "QIOB" */
13 };
14
15 static Block*
16 _allocb(int size)
17 {
18         Block *b;
19         uintptr addr;
20
21         size += Tlrspc;
22         if((b = mallocz(sizeof(Block)+size+Hdrspc, 0)) == nil)
23                 return nil;
24
25         b->next = nil;
26         b->list = nil;
27         b->free = nil;
28         b->flag = 0;
29
30         /* align start of data portion by rounding up */
31         addr = (uintptr)b;
32         addr = ROUND(addr + sizeof(Block), BLOCKALIGN);
33         b->base = (uchar*)addr;
34
35         /* align end of data portion by rounding down */
36         b->lim = (uchar*)b + msize(b);
37         addr = (uintptr)b->lim;
38         addr &= ~(BLOCKALIGN-1);
39         b->lim = (uchar*)addr;
40
41         /* leave sluff at beginning for added headers */
42         b->rp = b->lim - ROUND(size, BLOCKALIGN);
43         if(b->rp < b->base)
44                 panic("_allocb");
45         b->wp = b->rp;
46
47         return b;
48 }
49
50 Block*
51 allocb(int size)
52 {
53         Block *b;
54
55         /*
56          * Check in a process and wait until successful.
57          */
58         if(up == nil)
59                 panic("allocb without up: %#p", getcallerpc(&size));
60         while((b = _allocb(size)) == nil){
61                 if(up->nlocks || m->ilockdepth || !islo()){
62                         xsummary();
63                         mallocsummary();
64                         panic("allocb: no memory for %d bytes", size);
65                 }
66                 if(!waserror()){
67                         resrcwait("no memory for allocb");
68                         poperror();
69                 }
70         }
71         setmalloctag(b, getcallerpc(&size));
72
73         return b;
74 }
75
76 Block*
77 iallocb(int size)
78 {
79         Block *b;
80
81         if((b = _allocb(size)) == nil){
82                 static ulong nerr;
83                 if((nerr++%10000)==0){
84                         if(nerr > 10000000){
85                                 xsummary();
86                                 mallocsummary();
87                                 panic("iallocb: out of memory");
88                         }
89                         iprint("iallocb: no memory for %d bytes\n", size);
90                 }
91                 return nil;
92         }
93         setmalloctag(b, getcallerpc(&size));
94         b->flag = BINTR;
95
96         return b;
97 }
98
99 void
100 freeb(Block *b)
101 {
102         void *dead = (void*)Bdead;
103
104         if(b == nil)
105                 return;
106
107         /*
108          * drivers which perform non cache coherent DMA manage their own buffer
109          * pool of uncached buffers and provide their own free routine.
110          */
111         if(b->free != nil) {
112                 b->free(b);
113                 return;
114         }
115
116         /* poison the block in case someone is still holding onto it */
117         b->next = dead;
118         b->rp = dead;
119         b->wp = dead;
120         b->lim = dead;
121         b->base = dead;
122
123         free(b);
124 }
125
126 void
127 checkb(Block *b, char *msg)
128 {
129         void *dead = (void*)Bdead;
130
131         if(b == dead)
132                 panic("checkb b %s %#p", msg, b);
133         if(b->base == dead || b->lim == dead || b->next == dead
134           || b->rp == dead || b->wp == dead){
135                 print("checkb: base %#p lim %#p next %#p\n",
136                         b->base, b->lim, b->next);
137                 print("checkb: rp %#p wp %#p\n", b->rp, b->wp);
138                 panic("checkb dead: %s", msg);
139         }
140
141         if(b->base > b->lim)
142                 panic("checkb 0 %s %#p %#p", msg, b->base, b->lim);
143         if(b->rp < b->base)
144                 panic("checkb 1 %s %#p %#p", msg, b->base, b->rp);
145         if(b->wp < b->base)
146                 panic("checkb 2 %s %#p %#p", msg, b->base, b->wp);
147         if(b->rp > b->lim)
148                 panic("checkb 3 %s %#p %#p", msg, b->rp, b->lim);
149         if(b->wp > b->lim)
150                 panic("checkb 4 %s %#p %#p", msg, b->wp, b->lim);
151 }