]> git.lizzy.rs Git - plan9front.git/blob - sys/src/9/omap/ucallocb.c
93a07d336b05ea4c46080f7e30eb6d4b7b141f70
[plan9front.git] / sys / src / 9 / omap / ucallocb.c
1 /*
2  * allocate Blocks from uncached memory
3  */
4 #include        "u.h"
5 #include        "../port/lib.h"
6 #include        "mem.h"
7 #include        "dat.h"
8 #include        "fns.h"
9 #include        "error.h"
10
11 enum
12 {
13         Hdrspc          = 64,           /* leave room for high-level headers */
14         Bdead           = 0x51494F42,   /* "QIOB" */
15 };
16
17 struct
18 {
19         Lock;
20         ulong   bytes;
21 } ucialloc;
22
23 static Block*
24 _ucallocb(int size)
25 {
26         Block *b;
27         ulong addr;
28
29         if((b = ucalloc(sizeof(Block)+size+Hdrspc)) == nil)
30                 return nil;
31
32         b->next = nil;
33         b->list = nil;
34         b->free = 0;
35         b->flag = 0;
36
37         /* align start of data portion by rounding up */
38         addr = (ulong)b;
39         addr = ROUND(addr + sizeof(Block), BLOCKALIGN);
40         b->base = (uchar*)addr;
41
42         /* align end of data portion by rounding down */
43         b->lim = ((uchar*)b) + msize(b);
44         addr = (ulong)(b->lim);
45         addr = addr & ~(BLOCKALIGN-1);
46         b->lim = (uchar*)addr;
47
48         /* leave sluff at beginning for added headers */
49         b->rp = b->lim - ROUND(size, BLOCKALIGN);
50         if(b->rp < b->base)
51                 panic("_ucallocb");
52         b->wp = b->rp;
53
54         return b;
55 }
56
57 Block*
58 ucallocb(int size)
59 {
60         Block *b;
61
62         /*
63          * Check in a process and wait until successful.
64          * Can still error out of here, though.
65          */
66         if(up == nil)
67                 panic("ucallocb without up: %#p", getcallerpc(&size));
68         if((b = _ucallocb(size)) == nil)
69                 panic("ucallocb: no memory for %d bytes", size);
70         setmalloctag(b, getcallerpc(&size));
71
72         return b;
73 }
74
75 Block*
76 uciallocb(int size)
77 {
78         Block *b;
79         static int m1, m2, mp;
80
81         if(0 && ucialloc.bytes > conf.ialloc){
82                 if((m1++%10000)==0){
83                         if(mp++ > 1000){
84                                 active.exiting = 1;
85                                 exit(0);
86                         }
87                         iprint("uciallocb: limited %lud/%lud\n",
88                                 ucialloc.bytes, conf.ialloc);
89                 }
90                 return nil;
91         }
92
93         if((b = _ucallocb(size)) == nil){
94                 if(0 && (m2++%10000)==0){
95                         if(mp++ > 1000){
96                                 active.exiting = 1;
97                                 exit(0);
98                         }
99                         iprint("uciallocb: no memory %lud/%lud\n",
100                                 ucialloc.bytes, conf.ialloc);
101                 }
102                 return nil;
103         }
104         setmalloctag(b, getcallerpc(&size));
105         b->flag = BINTR;
106
107         ilock(&ucialloc);
108         ucialloc.bytes += b->lim - b->base;
109         iunlock(&ucialloc);
110
111         return b;
112 }
113
114 void
115 ucfreeb(Block *b)
116 {
117         void *dead = (void*)Bdead;
118
119         if(b == nil)
120                 return;
121
122         /*
123          * drivers which perform non cache coherent DMA manage their own buffer
124          * pool of uncached buffers and provide their own free routine.
125          */
126         if(b->free) {
127                 b->free(b);
128                 return;
129         }
130         if(b->flag & BINTR) {
131                 ilock(&ucialloc);
132                 ucialloc.bytes -= b->lim - b->base;
133                 iunlock(&ucialloc);
134         }
135
136         /* poison the block in case someone is still holding onto it */
137         b->next = dead;
138         b->rp = dead;
139         b->wp = dead;
140         b->lim = dead;
141         b->base = dead;
142
143         ucfree(b);
144 }