1 /*
2 * allocate 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
10 #include <pool.h>
11
12 typedef struct Private Private;
13 struct Private {
14 Lock;
15 char msg[256];
16 char* cur;
17 };
18
19 static Private ucprivate;
20
21 static void
ucpoolpanic(Pool * p,char * fmt,...)22 ucpoolpanic(Pool* p, char* fmt, ...)
23 {
24 va_list v;
25 Private *pv;
26 char msg[sizeof pv->msg];
27
28 pv = p->private;
29 va_start(v, fmt);
30 vseprint(pv->cur, &pv->msg[sizeof pv->msg], fmt, v);
31 va_end(v);
32 memmove(msg, pv->msg, sizeof msg);
33 iunlock(pv);
34 panic("%s", msg);
35 }
36
37 static void
ucpoolprint(Pool * p,char * fmt,...)38 ucpoolprint(Pool* p, char* fmt, ...)
39 {
40 va_list v;
41 Private *pv;
42
43 pv = p->private;
44 va_start(v, fmt);
45 pv->cur = vseprint(pv->cur, &pv->msg[sizeof pv->msg], fmt, v);
46 va_end(v);
47 }
48
49 static void
ucpoolunlock(Pool * p)50 ucpoolunlock(Pool* p)
51 {
52 Private *pv;
53 char msg[sizeof pv->msg];
54
55 pv = p->private;
56 if(pv->cur == pv->msg){
57 iunlock(pv);
58 return;
59 }
60
61 memmove(msg, pv->msg, sizeof msg);
62 pv->cur = pv->msg;
63 iunlock(pv);
64
65 iprint("%.*s", sizeof pv->msg, msg);
66 }
67
68 static void
ucpoollock(Pool * p)69 ucpoollock(Pool* p)
70 {
71 Private *pv;
72
73 pv = p->private;
74 ilock(pv);
75 pv->pc = getcallerpc(&p);
76 pv->cur = pv->msg;
77 }
78
79 static void*
ucarena(usize size)80 ucarena(usize size)
81 {
82 void *uv, *v;
83
84 assert(size == 1*MiB);
85
86 mainmem->maxsize += 1*MiB;
87 if((v = mallocalign(1*MiB, 1*MiB, 0, 0)) == nil ||
88 (uv = mmuuncache(v, 1*MiB)) == nil){
89 free(v);
90 mainmem->maxsize -= 1*MiB;
91 return nil;
92 }
93 return uv;
94 }
95
96 static Pool ucpool = {
97 .name = "Uncached",
98 .maxsize = 4*MiB,
99 .minarena = 1*MiB-32,
100 .quantum = 32,
101 .alloc = ucarena,
102 .merge = nil,
103 .flags = /*POOL_TOLERANCE|POOL_ANTAGONISM|POOL_PARANOIA|*/0,
104
105 .lock = ucpoollock,
106 .unlock = ucpoolunlock,
107 .print = ucpoolprint,
108 .panic = ucpoolpanic,
109
110 .private = &ucprivate,
111 };
112
113 void
ucfree(void * v)114 ucfree(void* v)
115 {
116 if(v == nil)
117 return;
118 poolfree(&ucpool, v);
119 }
120
121 void*
ucallocalign(usize size,int align,int span)122 ucallocalign(usize size, int align, int span)
123 {
124 void *v;
125
126 assert(size < ucpool.minarena-128);
127 v = poolallocalign(&ucpool, size, align, 0, span);
128 if(v)
129 memset(v, 0, size);
130 return v;
131 }
132
133 void*
ucalloc(usize size)134 ucalloc(usize size)
135 {
136 return ucallocalign(size, 32, 0);
137 }
138