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

📄 trace.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <u.h>#include <tos.h>#include <libc.h>#include <thread.h>#include <ip.h>#include <bio.h>#include <draw.h>#include <mouse.h>#include <cursor.h>#include <keyboard.h>#include "trace.h"#pragma	varargck	type	"t"		vlong#pragma	varargck	type	"U"		uvlong#define NS(x)	((vlong)x)#define US(x)	(NS(x) * 1000ULL)#define MS(x)	(US(x) * 1000ULL)#define S(x)	(MS(x) * 1000ULL)#define numblocks(a, b)	(((a) + (b) - 1) / (b))#define roundup(a, b)	(numblocks((a), (b)) * (b))enum {	OneRound = MS(1)/2LL,	MilliRound = US(1)/2LL,};typedef struct Event	Event;typedef struct Task	Task;struct Event {	Traceevent;	vlong	etime;	/* length of block to draw */};struct Task {	int	pid;	char	*name;	int	nevents;		Event	*events;	vlong	tstart;	vlong	total;	vlong	runtime;	vlong	runmax;	vlong	runthis;	long	runs;	ulong	tevents[Nevent];};enum {	Nevents = 1024,	Ncolor = 6,	K = 1024,};vlong	now, prevts;int	newwin;int	Width = 1000;		int	Height = 100;		// Per taskint	topmargin = 8;int	bottommargin = 4;int	lineht = 12;int	wctlfd;int	nevents;Traceevent *eventbuf;Event	*event;void drawtrace(void);int schedparse(char*, char*, char*);int timeconv(Fmt*);char *schedstatename[] = {	[SAdmit] =	"Admit",	[SSleep] =	"Sleep",	[SDead] =	"Dead",	[SDeadline] =	"Deadline",	[SEdf] =	"Edf",	[SExpel] =	"Expel",	[SReady] =	"Ready",	[SRelease] =	"Release",	[SRun] =	"Run",	[SSlice] =	"Slice",	[SInts] =	"Ints",	[SInte] =	"Inte",	[SUser] = 	"User",	[SYield] =	"Yield",};struct {	vlong	scale;	vlong	bigtics;	vlong	littletics;	int	sleep;} scales[] = {	{	US(500),	US(100),	US(50),		  0},	{	US(1000),	US(500),	US(100),	  0},	{	US(2000),	US(1000),	US(200),	  0},	{	US(5000),	US(1000),	US(500),	  0},	{	MS(10),		MS(5),		MS(1),		 20},	{	MS(20),		MS(10),		MS(2),		 20},	{	MS(50),		MS(10),		MS(5),		 20},	{	MS(100),	MS(50),		MS(10),		 20},	/* starting scaleno */	{	MS(200),	MS(100),	MS(20),		 20},	{	MS(500),	MS(100),	MS(50),		 50},	{	MS(1000),	MS(500),	MS(100),	100},	{	MS(2000),	MS(1000),	MS(200),	100},	{	MS(5000),	MS(1000),	MS(500),	100},	{	S(10),		S(50),		S(1),		100},	{	S(20),		S(10),		S(2),		100},	{	S(50),		S(10),		S(5),		100},	{	S(100),		S(50),		S(10),		100},	{	S(200),		S(100),		S(20),		100},	{	S(500),		S(100),		S(50),		100},	{	S(1000),	S(500),		S(100),		100},};int ntasks, verbose, triggerproc, paused;Task *tasks;Image *cols[Ncolor][4];Font *mediumfont, *tinyfont;Image *grey, *red, *green, *blue, *bg, *fg;char*profdev = "/proc/trace";static voidusage(void){	fprint(2, "Usage: %s [-d profdev] [-w] [-v] [-t triggerproc] [processes]\n", argv0);	exits(nil);}voidthreadmain(int argc, char **argv){	int fd, i;	char fname[80];	fmtinstall('t', timeconv);	ARGBEGIN {	case 'd':		profdev = EARGF(usage());		break;	case 'v':		verbose = 1;		break;	case 'w':		newwin++;		break;	case 't':		triggerproc = (int)strtol(EARGF(usage()), nil, 0);		break;	default:		usage();	}	ARGEND;	fname[sizeof fname - 1] = 0;	for(i = 0; i < argc; i++){		snprint(fname, sizeof fname - 2, "/proc/%s/ctl", 					argv[i]);		if((fd = open(fname, OWRITE)) < 0){			fprint(2, "%s: cannot open %s: %r\n",						argv[0], fname);			continue;		}		if(fprint(fd, "trace 1") < 0)			fprint(2, "%s: cannot enable tracing on %s: %r\n",						argv[0], fname);		close(fd);	}	drawtrace();}static voidmkcol(int i, int c0, int c1, int c2){	cols[i][0] = allocimagemix(display, c0, DWhite);	cols[i][1] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, c1);	cols[i][2] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, c2);	cols[i][3] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, c0);}static voidcolinit(void){	mediumfont = openfont(display, "/lib/font/bit/lucidasans/unicode.10.font");	if(mediumfont == nil)		mediumfont = font;	tinyfont = openfont(display, "/lib/font/bit/lucidasans/unicode.7.font");	if(tinyfont == nil)		tinyfont = font;	topmargin = mediumfont->height+2;	bottommargin = tinyfont->height+2;	/* Peach */	mkcol(0, 0xFFAAAAFF, 0xFFAAAAFF, 0xBB5D5DFF);	/* Aqua */	mkcol(1, DPalebluegreen, DPalegreygreen, DPurpleblue);	/* Yellow */	mkcol(2, DPaleyellow, DDarkyellow, DYellowgreen);	/* Green */	mkcol(3, DPalegreen, DMedgreen, DDarkgreen);	/* Blue */	mkcol(4, 0x00AAFFFF, 0x00AAFFFF, 0x0088CCFF);	/* Grey */	cols[5][0] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xEEEEEEFF);	cols[5][1] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCFF);	cols[5][2] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x888888FF);	cols[5][3] = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xAAAAAAFF);	grey = cols[5][2];	red = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xFF0000FF);	green = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x00FF00FF);	blue = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0x0000FFFF);	bg = display->white;	fg = display->black;}static voidredraw(int scaleno){	int n, i, j, x;	char buf[256];	Point p, q;	Rectangle r, rtime;	Task *t;	vlong ts, oldestts, newestts, period, ppp, scale, s, ss;#	define time2x(t)	((int)(((t) - oldestts) / ppp))	scale = scales[scaleno].scale;	period = scale + scales[scaleno].littletics;	ppp = period / Width;	// period per pixel.	/* Round `now' to a nice number */	newestts = now - (now % scales[scaleno].bigtics) + 			(scales[scaleno].littletics>>1);	oldestts = newestts - period;//print("newestts %t, period %t, %d-%d\n", newestts, period, time2x(oldestts), time2x(newestts));	if (prevts < oldestts){		oldestts = newestts - period;		prevts = oldestts;		draw(screen, screen->r, bg, nil, ZP);	}else{		/* just white out time */		rtime = screen->r;		rtime.min.x = rtime.max.x - stringwidth(mediumfont, "00000000000.000s");		rtime.max.y = rtime.min.y + mediumfont->height;		draw(screen, rtime, bg, nil, ZP);	}	p = screen->r.min;	for (n = 0; n != ntasks; n++) {		t = &tasks[n];		/* p is upper left corner for this task */		rtime = Rpt(p, addpt(p, Pt(500, mediumfont->height)));		draw(screen, rtime, bg, nil, ZP);		snprint(buf, sizeof(buf), "%d %s", t->pid, t->name);		q = string(screen, p, fg, ZP, mediumfont, buf);		s = now - t->tstart;		if(t->tevents[SRelease])			snprint(buf, sizeof(buf), " per %t — avg: %t max: %t",				(vlong)(s/t->tevents[SRelease]),				(vlong)(t->runtime/t->tevents[SRelease]),				t->runmax);		else if((s /=1000000000LL) != 0)			snprint(buf, sizeof(buf), " per 1s — avg: %t total: %t",				t->total/s,				t->total);		else			snprint(buf, sizeof(buf), " total: %t", t->total);		string(screen, q, fg, ZP, tinyfont, buf);		p.y += Height;	}	x = time2x(prevts);	p = screen->r.min;	for (n = 0; n != ntasks; n++) {		t = &tasks[n];		/* p is upper left corner for this task */		/* Move part already drawn */		r = Rect(p.x, p.y + topmargin, p.x + x, p.y+Height);		draw(screen, r, screen, nil, Pt(p.x + Width - x, p.y + topmargin));		r.max.x = screen->r.max.x;		r.min.x += x;		draw(screen, r, bg, nil, ZP);		line(screen, addpt(p, Pt(x, Height - lineht)), Pt(screen->r.max.x, p.y + Height - lineht),			Endsquare, Endsquare, 0, cols[n % Ncolor][1], ZP);		for (i = 0; i < t->nevents-1; i++)			if (prevts < t->events[i + 1].time)				break;					if (i > 0) {			memmove(t->events, t->events + i, (t->nevents - i) * sizeof(Event));			t->nevents -= i;		}		for (i = 0; i != t->nevents; i++) {			Event *e = &t->events[i], *_e;			int sx, ex;			switch (e->etype & 0xffff) {			case SAdmit:				if (e->time > prevts && e->time <= newestts) {					sx = time2x(e->time);					line(screen, addpt(p, Pt(sx, topmargin)), 						addpt(p, Pt(sx, Height - bottommargin)), 						Endarrow, Endsquare, 1, green, ZP);				}				break;			case SExpel:				if (e->time > prevts && e->time <= newestts) {					sx = time2x(e->time);					line(screen, addpt(p, Pt(sx, topmargin)), 						addpt(p, Pt(sx, Height - bottommargin)), 						Endsquare, Endarrow, 1, red, ZP);				}				break;			case SRelease:				if (e->time > prevts && e->time <= newestts) {					sx = time2x(e->time);					line(screen, addpt(p, Pt(sx, topmargin)), 						addpt(p, Pt(sx, Height - bottommargin)), 						Endarrow, Endsquare, 1, fg, ZP);				}				break;			case SDeadline:				if (e->time > prevts && e->time <= newestts) {					sx = time2x(e->time);					line(screen, addpt(p, Pt(sx, topmargin)), 						addpt(p, Pt(sx, Height - bottommargin)), 						Endsquare, Endarrow, 1, fg, ZP);				}				break;			case SYield:			case SUser:				if (e->time > prevts && e->time <= newestts) {					sx = time2x(e->time);					line(screen, addpt(p, Pt(sx, topmargin)), 						addpt(p, Pt(sx, Height - bottommargin)), 						Endsquare, Endarrow, 0, 						(e->etype == SYield)? green: blue, ZP);				}				break;			case SSlice:				if (e->time > prevts && e->time <= newestts) {					sx = time2x(e->time);					line(screen, addpt(p, Pt(sx, topmargin)), 						addpt(p, Pt(sx, Height - bottommargin)), 						Endsquare, Endarrow, 0, red, ZP);				}				break;			case SRun:			case SEdf:				sx = time2x(e->time);				ex = time2x(e->etime);				if(ex == sx)					ex++;				r = Rect(sx, topmargin + 8, ex, Height - lineht);				r = rectaddpt(r, p);				draw(screen, r, cols[n % Ncolor][e->etype==SRun?1:3], nil, ZP);				if(t->pid == triggerproc && ex < Width)					paused ^= 1;				for(j = 0; j < t->nevents; j++){					_e = &t->events[j];					switch(_e->etype & 0xffff){

⌨️ 快捷键说明

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