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