2 #include "../port/lib.h"
9 static void poolprint(Pool*, char*, ...);
10 static void ppanic(Pool*, char*, ...);
11 static void plock(Pool*);
12 static void punlock(Pool*);
14 typedef struct Private Private;
17 char msg[256]; /* a rock for messages to be printed at unlock */
20 static Private pmainpriv;
21 static Pool pmainmem = {
23 .maxsize= 4*1024*1024,
28 .flags= POOL_TOLERANCE,
38 static Private pimagpriv;
39 static Pool pimagmem = {
41 .maxsize= 16*1024*1024,
42 .minarena= 2*1024*1024,
56 static Private psecrpriv;
57 static Pool psecrmem = {
59 .maxsize= 16*1024*1024,
64 .flags= POOL_ANTAGONISM,
74 Pool* mainmem = &pmainmem;
75 Pool* imagmem = &pimagmem;
76 Pool* secrmem = &psecrmem;
79 * because we can't print while we're holding the locks,
80 * we have the save the message and print it once we let go.
83 poolprint(Pool *p, char *fmt, ...)
90 vseprint(pv->msg+strlen(pv->msg), pv->msg+sizeof pv->msg, fmt, v);
95 ppanic(Pool *p, char *fmt, ...)
99 char msg[sizeof pv->msg];
103 vseprint(pv->msg+strlen(pv->msg), pv->msg+sizeof pv->msg, fmt, v);
105 memmove(msg, pv->msg, sizeof msg);
117 pv->lk.pc = getcallerpc(&p);
125 char msg[sizeof pv->msg];
133 memmove(msg, pv->msg, sizeof msg);
135 iprint("%.*s", sizeof pv->msg, msg);
141 print("%s max %llud cur %llud free %llud alloc %llud\n", p->name,
142 (uvlong)p->maxsize, (uvlong)p->cursize,
143 (uvlong)p->curfree, (uvlong)p->curalloc);
149 poolsummary(mainmem);
150 poolsummary(imagmem);
151 poolsummary(secrmem);
154 /* everything from here down should be the same in libc, libdebugmalloc, and the kernel */
155 /* - except the code for malloc(), which alternately doesn't clear or does. */
156 /* - except the code for smalloc(), which lives only in the kernel. */
159 * Npadlong is the number of ulong's to leave at the beginning of
160 * each allocated buffer for our own bookkeeping. We return to the callers
161 * a pointer that points immediately after our bookkeeping area. Incoming pointers
162 * must be decremented by that much, and outgoing pointers incremented.
163 * The malloc tag is stored at MallocOffset from the beginning of the block,
164 * and the realloc tag at ReallocOffset. The offsets are from the true beginning
165 * of the block, not the beginning the caller sees.
167 * The extra if(Npadlong != 0) in various places is a hint for the compiler to
168 * compile out function calls that would otherwise be no-ops.
194 while((v = poolalloc(mainmem, size+Npadlong*sizeof(ulong))) == nil){
201 v = (ulong*)v+Npadlong;
202 setmalloctag(v, getcallerpc(&size));
213 v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
217 v = (ulong*)v+Npadlong;
218 setmalloctag(v, getcallerpc(&size));
226 mallocz(ulong size, int clr)
230 v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));
231 if(Npadlong && v != nil){
232 v = (ulong*)v+Npadlong;
233 setmalloctag(v, getcallerpc(&size));
242 mallocalign(ulong size, ulong align, long offset, ulong span)
246 v = poolallocalign(mainmem, size+Npadlong*sizeof(ulong), align, offset-Npadlong*sizeof(ulong), span);
247 if(Npadlong && v != nil){
248 v = (ulong*)v+Npadlong;
249 setmalloctag(v, getcallerpc(&size));
261 poolfree(mainmem, (ulong*)v-Npadlong);
265 realloc(void *v, ulong size)
270 v = (ulong*)v-Npadlong;
271 if(Npadlong !=0 && size != 0)
272 size += Npadlong*sizeof(ulong);
274 if(nv = poolrealloc(mainmem, v, size)){
275 nv = (ulong*)nv+Npadlong;
276 setrealloctag(nv, getcallerpc(&v));
278 setmalloctag(nv, getcallerpc(&v));
286 return poolmsize(mainmem, (ulong*)v-Npadlong)-Npadlong*sizeof(ulong);
289 /* secret memory, used to back cryptographic keys and cipher states */
295 while((v = poolalloc(secrmem, size+Npadlong*sizeof(ulong))) == nil){
302 v = (ulong*)v+Npadlong;
303 setmalloctag(v, getcallerpc(&size));
314 poolfree(secrmem, (ulong*)v-Npadlong);
318 setmalloctag(void *v, uintptr pc)
321 if(Npadlong <= MallocOffset || v == nil)
323 ((ulong*)v)[-Npadlong+MallocOffset] = (ulong)pc;
327 setrealloctag(void *v, uintptr pc)
330 if(Npadlong <= ReallocOffset || v == nil)
332 ((ulong*)v)[-Npadlong+ReallocOffset] = (ulong)pc;
336 getmalloctag(void *v)
339 if(Npadlong <= MallocOffset)
341 return (int)((ulong*)v)[-Npadlong+MallocOffset];
345 getrealloctag(void *v)
348 if(Npadlong <= ReallocOffset)
350 return (int)((ulong*)v)[-Npadlong+ReallocOffset];