⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alloc.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
字号:
#include	"u.h"#include	"../port/lib.h"#include	"mem.h"#include	"dat.h"#include	"fns.h"#include	"error.h"#include	<pool.h>static void poolprint(Pool*, char*, ...);static void ppanic(Pool*, char*, ...);static void plock(Pool*);static void punlock(Pool*);typedef struct Private	Private;struct Private {	Lock		lk;	char		msg[256];	/* a rock for messages to be printed at unlock */};static Private pmainpriv;static Pool pmainmem = {	.name=	"Main",	.maxsize=	4*1024*1024,	.minarena=	128*1024,	.quantum=	32,	.alloc=	xalloc,	.merge=	xmerge,	.flags=	POOL_TOLERANCE,	.lock=	plock,	.unlock=	punlock,	.print=	poolprint,	.panic=	ppanic,	.private=	&pmainpriv,};static Private pimagpriv;static Pool pimagmem = {	.name=	"Image",	.maxsize=	16*1024*1024,	.minarena=	2*1024*1024,	.quantum=	32,	.alloc=	xalloc,	.merge=	xmerge,	.flags=	0,	.lock=	plock,	.unlock=	punlock,	.print=	poolprint,	.panic=	ppanic,	.private=	&pimagpriv,};Pool*	mainmem = &pmainmem;Pool*	imagmem = &pimagmem;/* * because we can't print while we're holding the locks,  * we have the save the message and print it once we let go. */static voidpoolprint(Pool *p, char *fmt, ...){	va_list v;	Private *pv;	pv = p->private;	va_start(v, fmt);	doprint(pv->msg+strlen(pv->msg), pv->msg+sizeof pv->msg, fmt, v);	va_end(v);}static voidppanic(Pool *p, char *fmt, ...){	va_list v;	Private *pv;	char msg[sizeof pv->msg];	pv = p->private;	va_start(v, fmt);	doprint(pv->msg+strlen(pv->msg), pv->msg+sizeof pv->msg, fmt, v);	va_end(v);	memmove(msg, pv->msg, sizeof msg);	iunlock(&pv->lk);	panic("%s", msg);}static voidplock(Pool *p){	Private *pv;	pv = p->private;	ilock(&pv->lk);	pv->msg[0] = 0;}static voidpunlock(Pool *p){	Private *pv;	char msg[sizeof pv->msg];	pv = p->private;	if(pv->msg[0] == 0){		iunlock(&pv->lk);		return;	}	memmove(msg, pv->msg, sizeof msg);	iunlock(&pv->lk);	print("%.*s", sizeof pv->msg, msg);}voidpoolsummary(Pool *p){	print("%s max %lud cur %lud free %lud alloc %lud\n", p->name,		p->maxsize, p->cursize, p->curfree, p->curalloc);}voidmallocsummary(void){	poolsummary(mainmem);	poolsummary(imagmem);}/* everything from here down should be the same in libc, libdebugmalloc, and the kernel *//* - except the code for malloc(), which alternately doesn't clear or does. *//* - except the code for smalloc(), which lives only in the kernel. *//* * Npadlong is the number of 32-bit longs to leave at the beginning of  * each allocated buffer for our own bookkeeping.  We return to the callers * a pointer that points immediately after our bookkeeping area.  Incoming pointers * must be decremented by that much, and outgoing pointers incremented. * The malloc tag is stored at MallocOffset from the beginning of the block, * and the realloc tag at ReallocOffset.  The offsets are from the true beginning * of the block, not the beginning the caller sees. * * The extra if(Npadlong != 0) in various places is a hint for the compiler to * compile out function calls that would otherwise be no-ops. *//*	non tracing *enum {	Npadlong	= 0,	MallocOffset = 0,	ReallocOffset = 0,}; * *//* tracing */enum {	Npadlong	= 2,	MallocOffset = 0,	ReallocOffset = 1};void*smalloc(ulong size){	void *v;	for(;;) {		v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));		if(v != nil)			break;		tsleep(&up->sleep, return0, 0, 100);	}	if(Npadlong){		v = (ulong*)v+Npadlong;		setmalloctag(v, getcallerpc(&size));	}	memset(v, 0, size);	return v;}void*malloc(ulong size){	void *v;	v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));	if(Npadlong && v != nil) {		v = (ulong*)v+Npadlong;		setmalloctag(v, getcallerpc(&size));		setrealloctag(v, 0);		memset(v, 0, size);	}	return v;}void*mallocz(ulong size, int clr){	void *v;	v = poolalloc(mainmem, size+Npadlong*sizeof(ulong));	if(Npadlong && v != nil){		v = (ulong*)v+Npadlong;		setmalloctag(v, getcallerpc(&size));		setrealloctag(v, 0);	}	if(clr && v != nil)		memset(v, 0, size);	return v;}voidfree(void *v){	if(v != nil)		poolfree(mainmem, (ulong*)v-Npadlong);}void*realloc(void *v, ulong size){	void *nv;	if(v != nil)		v = (ulong*)v-Npadlong;	if(Npadlong !=0 && size != 0)		size += Npadlong*sizeof(ulong);	if(nv = poolrealloc(mainmem, v, size)){		nv = (ulong*)nv+Npadlong;		setrealloctag(nv, getcallerpc(&v));		if(v == nil)			setmalloctag(nv, getcallerpc(&v));	}			return nv;}ulongmsize(void *v){	return poolmsize(mainmem, (ulong*)v-Npadlong)-Npadlong*sizeof(ulong);}void*calloc(ulong n, ulong szelem){	void *v;	if(v = mallocz(n*szelem, 1))		setmalloctag(v, getcallerpc(&n));	return v;}voidsetmalloctag(void *v, ulong pc){	ulong *u;	USED(v, pc);	if(Npadlong <= MallocOffset || v == nil)		return;	u = v;	u[-Npadlong+MallocOffset] = pc;}voidsetrealloctag(void *v, ulong pc){	ulong *u;	USED(v, pc);	if(Npadlong <= ReallocOffset || v == nil)		return;	u = v;	u[-Npadlong+ReallocOffset] = pc;}ulonggetmalloctag(void *v){	USED(v);	if(Npadlong <= MallocOffset)		return ~0;	return ((ulong*)v)[-Npadlong+MallocOffset];}ulonggetrealloctag(void *v){	USED(v);	if(Npadlong <= ReallocOffset)		return ((ulong*)v)[-Npadlong+ReallocOffset];	return ~0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -