plan 9 kernel history: overview | file list | diff list

1997/0408/port/devkprof.c (diff list | history)

port/devkprof.c on 1990/0330
1990/0330    
#include	"u.h" 
1992/0321    
#include	"../port/lib.h" 
1990/0330    
#include	"mem.h" 
#include	"dat.h" 
#include	"fns.h" 
1992/0111    
#include	"../port/error.h" 
1990/03292    
 
 
1991/1006    
#define	LRES	3		/* log of PC resolution */ 
1992/0122    
#define	SZ	4		/* sizeof of count cell; well known as 4 */ 
1990/03292    
 
1991/1011    
struct 
{ 
1991/1006    
	int	minpc; 
	int	maxpc; 
	int	nbuf; 
	int	time; 
	ulong	*buf; 
}kprof; 
1990/03292    
 
enum{ 
	Kprofdirqid, 
	Kprofdataqid, 
1991/1006    
	Kprofctlqid, 
1990/03292    
}; 
1997/0327    
Dirtab kproftab[]={ 
1991/1006    
	"kpdata",	{Kprofdataqid},		0,	0600, 
	"kpctl",	{Kprofctlqid},		0,	0600, 
1990/03292    
}; 
 
1997/0327    
static void 
_kproftimer(ulong pc) 
1990/0330    
{ 
1997/0327    
	extern void spldone(void); 
 
	if(kprof.time == 0) 
		return; 
	/* 
	 *  if the pc is coming out of spllo or splx, 
	 *  use the pc saved when we went splhi. 
	 */ 
	if(pc>=(ulong)spllo && pc<=(ulong)spldone) 
		pc = m->splpc; 
 
	kprof.buf[0] += TK2MS(1); 
	if(kprof.minpc<=pc && pc<kprof.maxpc){ 
		pc -= kprof.minpc; 
		pc >>= LRES; 
		kprof.buf[pc] += TK2MS(1); 
	}else 
		kprof.buf[1] += TK2MS(1); 
1990/0330    
} 
 
1997/0327    
static void 
1990/03292    
kprofinit(void) 
{ 
1992/0814    
	if(SZ != sizeof kprof.buf[0]) 
		panic("kprof size"); 
1997/0327    
	kproftimer = _kproftimer; 
1990/03292    
} 
 
1997/0327    
static Chan* 
1990/03292    
kprofattach(char *spec) 
{ 
1992/0814    
	ulong n; 
 
	/* allocate when first used */ 
	kprof.minpc = KTZERO; 
	kprof.maxpc = (ulong)etext; 
	kprof.nbuf = (kprof.maxpc-kprof.minpc) >> LRES; 
	n = kprof.nbuf*SZ; 
	if(kprof.buf == 0) { 
		kprof.buf = xalloc(n); 
		if(kprof.buf == 0) 
			error(Enomem); 
	} 
	kproftab[0].length = n; 
1991/1006    
	return devattach('T', spec); 
1990/03292    
} 
 
1997/0327    
static int 
1990/03292    
kprofwalk(Chan *c, char *name) 
{ 
1997/0327    
	return devwalk(c, name, kproftab, nelem(kproftab), devgen); 
1990/03292    
} 
 
1997/0327    
static void 
1990/0330    
kprofstat(Chan *c, char *db) 
1990/03292    
{ 
1997/0327    
	devstat(c, db, kproftab, nelem(kproftab), devgen); 
1990/03292    
} 
 
1997/0327    
static Chan* 
1990/0330    
kprofopen(Chan *c, int omode) 
1990/03292    
{ 
1991/1006    
	if(c->qid.path == CHDIR){ 
1990/0330    
		if(omode != OREAD) 
1991/1006    
			error(Eperm); 
1990/0330    
	} 
	c->mode = openmode(omode); 
	c->flag |= COPEN; 
	c->offset = 0; 
1990/03292    
	return c; 
} 
 
1997/0327    
static void 
1995/0808    
kprofclose(Chan*) 
1990/03292    
{ 
} 
 
1997/0327    
static long 
1992/0122    
kprofread(Chan *c, void *va, long n, ulong offset) 
1990/03292    
{ 
1993/0501    
	ulong end; 
1992/0122    
	ulong w, *bp; 
	uchar *a, *ea; 
 
	switch(c->qid.path & ~CHDIR){ 
1990/03292    
	case Kprofdirqid: 
1997/0327    
		return devdirread(c, va, n, kproftab, nelem(kproftab), devgen); 
1992/0122    
 
1990/03292    
	case Kprofdataqid: 
1993/0501    
		end = kprof.nbuf*SZ; 
1992/0122    
		if(offset & (SZ-1)) 
			error(Ebadarg); 
1993/0501    
		if(offset >= end){ 
1990/0330    
			n = 0; 
1990/03292    
			break; 
		} 
1993/0501    
		if(offset+n > end) 
			n = end-offset; 
1992/0122    
		n &= ~(SZ-1); 
		a = va; 
		ea = a + n; 
		bp = kprof.buf + offset/SZ; 
		while(a < ea){ 
			w = *bp++; 
			*a++ = w>>24; 
			*a++ = w>>16; 
			*a++ = w>>8; 
			*a++ = w>>0; 
		} 
1990/03292    
		break; 
1992/0122    
 
1990/03292    
	default: 
1992/0122    
		n = 0; 
1990/03292    
		break; 
	} 
	return n; 
} 
 
1997/0327    
static long 
1995/0804    
kprofwrite(Chan *c, char *a, long n, ulong) 
1990/03292    
{ 
1991/1006    
	switch((int)(c->qid.path&~CHDIR)){ 
	case Kprofctlqid: 
		if(strncmp(a, "startclr", 8) == 0){ 
1992/0122    
			memset((char *)kprof.buf, 0, kprof.nbuf*SZ); 
1991/1006    
			kprof.time = 1; 
		}else if(strncmp(a, "start", 5) == 0) 
			kprof.time = 1; 
		else if(strncmp(a, "stop", 4) == 0) 
			kprof.time = 0; 
1990/03292    
		break; 
	default: 
1991/1006    
		error(Ebadusefd); 
1990/03292    
	} 
	return n; 
1995/0108    
} 
 
1997/0327    
Dev kprofdevtab = { 
1997/0408    
	'T', 
	"kprof", 
 
1997/0327    
	devreset, 
	kprofinit, 
	kprofattach, 
	devclone, 
	kprofwalk, 
	kprofstat, 
	kprofopen, 
	devcreate, 
	kprofclose, 
	kprofread, 
	devbread, 
	kprofwrite, 
	devbwrite, 
	devremove, 
	devwstat, 
}; 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)