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

📄 prof.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include <mach.h>typedef struct Data	Data;typedef struct Pc	Pc;typedef struct Acc	Acc;struct Data{	ushort	down;	ushort	right;	ulong	pc;	ulong	count;	ulong	time;};struct Pc{	Pc	*next;	ulong	pc;};struct Acc{	char	*name;	ulong	pc;	ulong	ms;	ulong	calls;};Data*	data;Acc*	acc;ulong	ms;long	nsym;long	ndata;int	dflag;int	rflag;Biobuf	bout;int	tabstop = 4;int	verbose;void	syms(char*);void	datas(char*);void	graph(int, ulong, Pc*);void	plot(void);char*	name(ulong);void	indent(int);char*	defaout(void);voidmain(int argc, char *argv[]){	char *s;	s = getenv("tabstop");	if(s!=nil && strtol(s,0,0)>0)		tabstop = strtol(s,0,0);	ARGBEGIN{	case 'v':		verbose = 1;		break;	case 'd':		dflag = 1;		break;	case 'r':		rflag = 1;		break;	default:		fprint(2, "usage: prof [-dr] [8.out] [prof.out]\n");		exits("usage");	}ARGEND	Binit(&bout, 1, OWRITE);	if(argc > 0)		syms(argv[0]);	else		syms(defaout());	if(argc > 1)		datas(argv[1]);	else		datas("prof.out");	if(ndata){		if(dflag)			graph(0, data[0].down, 0);		else			plot();	}	exits(0);}voidswapdata(Data *dp){	dp->down = beswab(dp->down);	dp->right = beswab(dp->right);	dp->pc = beswal(dp->pc);	dp->count = beswal(dp->count);	dp->time = beswal(dp->time);}intacmp(void *va, void *vb){	Acc *a, *b;	ulong ua, ub;	a = va;	b = vb;	ua = a->ms;	ub = b->ms;	if(ua > ub)		return 1;	if(ua < ub)		return -1;	return 0;}voidsyms(char *cout){	Fhdr f;	int fd;	if((fd = open(cout, 0)) < 0){		perror(cout);		exits("open");	}	if (!crackhdr(fd, &f)) {		fprint(2, "can't read text file header\n");		exits("read");	}	if (f.type == FNONE) {		fprint(2, "text file not an a.out\n");		exits("file type");	}	if (syminit(fd, &f) < 0) {		fprint(2, "syminit: %r\n");		exits("syms");	}	close(fd);}voiddatas(char *dout){	int fd;	Dir *d;	int i;	if((fd = open(dout, 0)) < 0){		perror(dout);		exits("open");	}	d = dirfstat(fd);	if(d == nil){		perror(dout);		exits("stat");	}	ndata = d->length/sizeof(data[0]);	data = malloc(ndata*sizeof(Data));	if(data == 0){		fprint(2, "prof: can't malloc data\n");		exits("data malloc");	}	if(read(fd, data, d->length) != d->length){		fprint(2, "prof: can't read data file\n");		exits("data read");	}	free(d);	close(fd);	for (i = 0; i < ndata; i++)		swapdata(data+i);}char*name(ulong pc){	Symbol s;	static char buf[16];	if (findsym(pc, CTEXT, &s))		return(s.name);	snprint(buf, sizeof(buf), "#%lux", pc);	return buf;}voidgraph(int ind, ulong i, Pc *pc){	long time, count, prgm;	Pc lpc;	if(i >= ndata){		fprint(2, "prof: index out of range %ld [max %ld]\n", i, ndata);		return;	}	count = data[i].count;	time = data[i].time;	prgm = data[i].pc;	if(time < 0)		time += data[0].time;	if(data[i].right != 0xFFFF)		graph(ind, data[i].right, pc);	indent(ind);	if(count == 1)		Bprint(&bout, "%s:%lud\n", name(prgm), time);	else		Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);	if(data[i].down == 0xFFFF)		return;	lpc.next = pc;	lpc.pc = prgm;	if(!rflag){		while(pc){			if(pc->pc == prgm){				indent(ind+1);				Bprint(&bout, "...\n");				return;			}			pc = pc->next;		}	}	graph(ind+1, data[i].down, &lpc);}/* *	assume acc is ordered by increasing text address. */longsymind(ulong pc){	int top, bot, mid;	bot = 0;	top = nsym;	for (mid = (bot+top)/2; mid < top; mid = (bot+top)/2) {		if (pc < acc[mid].pc)			top = mid;		else		if (mid != nsym-1 && pc >= acc[mid+1].pc)			bot = mid;		else			return mid;	}	return -1;}ulongsum(ulong i){	long j, dtime, time;	int k;	static indent;	if(i >= ndata){		fprint(2, "prof: index out of range %ld [max %ld]\n", i, ndata);		return 0;	}	j = symind(data[i].pc);	time = data[i].time;	if(time < 0)		time += data[0].time;	if (verbose){		for(k = 0; k < indent; k++)			print("	");		print("%lud: %ld/%lud", i, data[i].time, data[i].count);		if (j >= 0)			print("	%s\n", acc[j].name);		else			print("	0x%lux\n", data[i].pc);	}	dtime = 0;	if(data[i].down != 0xFFFF){		indent++;		dtime = sum(data[i].down);		indent--;	}	j = symind(data[i].pc);	if (j >= 0) {		acc[j].ms += time - dtime;		ms += time - dtime;		acc[j].calls += data[i].count;	}	if(data[i].right == 0xFFFF)		return time;	return time + sum(data[i].right);}voidplot(void){	Symbol s;	for (nsym = 0; textsym(&s, nsym); nsym++) {		acc = realloc(acc, (nsym+1)*sizeof(Acc));		if(acc == 0){			fprint(2, "prof: malloc fail\n");			exits("acc malloc");		}		acc[nsym].name = s.name;		acc[nsym].pc = s.value;		acc[nsym].calls = acc[nsym].ms = 0;	}	sum(data[0].down);	qsort(acc, nsym, sizeof(Acc), acmp);	Bprint(&bout, "  %%   Time\tCalls\tName\n");	if(ms == 0)		ms = 1;	while (--nsym >= 0) {		if(acc[nsym].calls)			Bprint(&bout, "%4.1f%8.3f %8lud\t%s\n",				(100.0*acc[nsym].ms)/ms,				acc[nsym].ms/1000.0,				acc[nsym].calls,				acc[nsym].name);	}}voidindent(int ind){	int j;	j = 2*ind;	while(j >= tabstop){		Bwrite(&bout, ".\t", 2);		j -= tabstop;	}	if(j)		Bwrite(&bout, ".                            ", j);}char*	trans[] ={	"386",		"8.out",	"68020",		"2.out",	"alpha",		"7.out",	"arm",		"5.out",	"mips",		"v.out",	"power",		"q.out",	"sparc",		"k.out",	"spim",		"0.out",	0,0};char*defaout(void){	char *p;	int i;	p = getenv("objtype");	if(p)	for(i=0; trans[i]; i+=2)		if(strcmp(p, trans[i]) == 0)			return trans[i+1];	return trans[1];}

⌨️ 快捷键说明

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