146 lines · 2.4 KB · C
RawDownload
/*  * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ /* * 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 voiducpoolpanic(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 voiducpoolprint(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 voiducpoolunlock(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 voiducpoollock(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,}; voiducfree(void* v){	if(v == nil)		return;	poolfree(&ucpool, v);} void*ucallocalign(usize size, int align, int 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);}