ref: a5db044fd3ccb8f021d4deb07b3dc732ed41d699
dir: /sys/src/9/port/ucalloc.c/
/* * allocate uncached memory */ #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include <pool.h> typedef struct Private Private; struct Private { Lock; char msg[256]; char* cur; }; static Private ucprivate; static void ucpoolpanic(Pool* p, char* fmt, ...) { va_list v; Private *pv; char msg[sizeof pv->msg]; pv = p->private; va_start(v, fmt); vseprint(pv->cur, &pv->msg[sizeof pv->msg], fmt, v); va_end(v); memmove(msg, pv->msg, sizeof msg); iunlock(pv); panic("%s", msg); } static void ucpoolprint(Pool* p, char* fmt, ...) { va_list v; Private *pv; pv = p->private; va_start(v, fmt); pv->cur = vseprint(pv->cur, &pv->msg[sizeof pv->msg], fmt, v); va_end(v); } static void ucpoolunlock(Pool* p) { Private *pv; char msg[sizeof pv->msg]; pv = p->private; if(pv->cur == pv->msg){ iunlock(pv); return; } memmove(msg, pv->msg, sizeof msg); pv->cur = pv->msg; iunlock(pv); iprint("%.*s", sizeof pv->msg, msg); } static void ucpoollock(Pool* p) { Private *pv; pv = p->private; ilock(pv); pv->pc = getcallerpc(&p); pv->cur = pv->msg; } static void* ucarena(usize size) { void *uv, *v; assert(size == 1*MiB); mainmem->maxsize += 1*MiB; if((v = mallocalign(1*MiB, 1*MiB, 0, 0)) == nil || (uv = mmuuncache(v, 1*MiB)) == nil){ free(v); mainmem->maxsize -= 1*MiB; return nil; } return uv; } static Pool ucpool = { .name = "Uncached", .maxsize = 4*MiB, .minarena = 1*MiB-32, .quantum = 32, .alloc = ucarena, .merge = nil, .flags = /*POOL_TOLERANCE|POOL_ANTAGONISM|POOL_PARANOIA|*/0, .lock = ucpoollock, .unlock = ucpoolunlock, .print = ucpoolprint, .panic = ucpoolpanic, .private = &ucprivate, }; void ucfree(void* v) { if(v == nil) return; poolfree(&ucpool, v); } void* ucallocalign(usize size, int align, usize span) { void *v; assert(size < ucpool.minarena-128); v = poolallocalign(&ucpool, size, align, 0, span); if(v) memset(v, 0, size); return v; } void* ucalloc(usize size) { return ucallocalign(size, 32, 0); }