xref: /plan9/sys/src/9/port/ucalloc.c (revision afe147c3d2695726595a8d244cde0015ee42d661)
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