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

📄 stats.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
{	return init | present[Mmem] | present[Mswap];}intneedstat(int init){	return init | present[Mcontext]  | present[Mfault] | present[Mintr] | present[Mload] | present[Midle] |		present[Minintr] | present[Msyscall] | present[Mtlbmiss] | present[Mtlbpurge];}intneedether(int init){	return init | present[Mether] | present[Metherin] | present[Metherout] | present[Methererr];}intneedbattery(int init){	return init | present[Mbattery];}intneedsignal(int init){	return init | present[Msignal];}voidreadmach(Machine *m, int init){	int n, i;	ulong a[8];	char buf[32];	if(m->remote && (m->disable || setjmp(catchalarm))){		if (m->disable++ >= 5)			m->disable = 0; /* give it another chance */		memmove(m->devsysstat, m->prevsysstat, sizeof m->devsysstat);		memmove(m->netetherstats, m->prevetherstats, sizeof m->netetherstats);		return;	}	snprint(buf, sizeof buf, "%s", m->name);	if (strcmp(m->name, buf) != 0){		free(m->name);		m->name = estrdup(buf);		if(display != nil)	/* else we're still initializing */			eresized(0);	}	if(m->remote){		notify(alarmed);		alarm(5000);	}	if(needswap(init) && loadbuf(m, &m->swapfd) && readswap(m, a))		memmove(m->devswap, a, sizeof m->devswap);	if(needstat(init) && loadbuf(m, &m->statsfd)){		memmove(m->prevsysstat, m->devsysstat, sizeof m->devsysstat);		memset(m->devsysstat, 0, sizeof m->devsysstat);		for(n=0; n<m->nproc && readnums(m, nelem(m->devsysstat), a, 0); n++)			for(i=0; i<nelem(m->devsysstat); i++)				m->devsysstat[i] += a[i];	}	if(needether(init) && loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1)){		memmove(m->prevetherstats, m->netetherstats, sizeof m->netetherstats);		memmove(m->netetherstats, a, sizeof m->netetherstats);	}	if(needsignal(init) && loadbuf(m, &m->ifstatsfd) && strncmp(m->buf, "Signal: ", 8)==0 && readnums(m, nelem(m->netetherifstats), a, 1)){		memmove(m->netetherifstats, a, sizeof m->netetherifstats);	}	if(needbattery(init) && loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))		memmove(m->batterystats, a, sizeof(m->batterystats));	if(needbattery(init) && loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0))		memmove(m->batterystats, a, sizeof(m->batterystats));	if(m->remote){		alarm(0);		notify(nil);	}}voidmemval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devswap[Mem];	*vmax = m->devswap[Maxmem];}voidswapval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devswap[Swap];	*vmax = m->devswap[Maxswap];}voidcontextval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Context]-m->prevsysstat[Context];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidintrval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Interrupt]-m->prevsysstat[Interrupt];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidsyscallval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Syscall]-m->prevsysstat[Syscall];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidfaultval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Fault]-m->prevsysstat[Fault];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidtlbmissval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[TLBfault]-m->prevsysstat[TLBfault];	*vmax = (sleeptime/1000)*10*m->nproc;	if(init)		*vmax = (sleeptime/1000)*10;}voidtlbpurgeval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[TLBpurge]-m->prevsysstat[TLBpurge];	*vmax = (sleeptime/1000)*10*m->nproc;	if(init)		*vmax = (sleeptime/1000)*10;}voidloadval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->devsysstat[Load];	*vmax = 1000*m->nproc;	if(init)		*vmax = 1000;}voididleval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devsysstat[Idle]/m->nproc;	*vmax = 100;}voidinintrval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->devsysstat[InIntr]/m->nproc;	*vmax = 100;}voidetherval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->netetherstats[In]-m->prevetherstats[In] + m->netetherstats[Out]-m->prevetherstats[Out];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidetherinval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->netetherstats[In]-m->prevetherstats[In];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidetheroutval(Machine *m, ulong *v, ulong *vmax, int init){	*v = m->netetherstats[Out]-m->prevetherstats[Out];	*vmax = sleeptime*m->nproc;	if(init)		*vmax = sleeptime;}voidethererrval(Machine *m, ulong *v, ulong *vmax, int init){	int i;	*v = 0;	for(i=Err0; i<nelem(m->netetherstats); i++)		*v += m->netetherstats[i];	*vmax = (sleeptime/1000)*10*m->nproc;	if(init)		*vmax = (sleeptime/1000)*10;}voidbatteryval(Machine *m, ulong *v, ulong *vmax, int){	*v = m->batterystats[0];	if(m->bitsybatfd >= 0)		*vmax = 184;		// at least on my bitsy...	else		*vmax = 100;}voidsignalval(Machine *m, ulong *v, ulong *vmax, int){	ulong l;	*vmax = sleeptime;	l = m->netetherifstats[0];	/*	 * Range is seen to be from about -45 (strong) to -95 (weak); rescale	 */	if(l == 0){	/* probably not present */		*v = 0;		return;	}	*v = 20*(l+95);}voidusage(void){	fprint(2, "usage: stats [-O] [-S scale] [-LY] [-%s] [machine...]\n", argchars);	exits("usage");}voidaddgraph(int n){	Graph *g, *ograph;	int i, j;	static int nadd;	if(n > nelem(menu2str))		abort();	/* avoid two adjacent graphs of same color */	if(ngraph>0 && graph[ngraph-1].colindex==nadd%Ncolor)		nadd++;	ograph = graph;	graph = emalloc(nmach*(ngraph+1)*sizeof(Graph));	for(i=0; i<nmach; i++)		for(j=0; j<ngraph; j++)			graph[i*(ngraph+1)+j] = ograph[i*ngraph+j];	free(ograph);	ngraph++;	for(i=0; i<nmach; i++){		g = &graph[i*ngraph+(ngraph-1)];		memset(g, 0, sizeof(Graph));		g->label = menu2str[n]+Opwid;		g->newvalue = newvaluefn[n];		g->update = update1;	/* no other update functions yet */		g->mach = &mach[i];		g->colindex = nadd%Ncolor;	}	present[n] = 1;	nadd++;}voiddropgraph(int which){	Graph *ograph;	int i, j, n;	if(which > nelem(menu2str))		abort();	/* convert n to index in graph table */	n = -1;	for(i=0; i<ngraph; i++)		if(strcmp(menu2str[which]+Opwid, graph[i].label) == 0){			n = i;			break;		}	if(n < 0){		fprint(2, "stats: internal error can't drop graph\n");		killall("error");	}	ograph = graph;	graph = emalloc(nmach*(ngraph-1)*sizeof(Graph));	for(i=0; i<nmach; i++){		for(j=0; j<n; j++)			graph[i*(ngraph-1)+j] = ograph[i*ngraph+j];		free(ograph[i*ngraph+j].data);		freeimage(ograph[i*ngraph+j].overtmp);		for(j++; j<ngraph; j++)			graph[i*(ngraph-1)+j-1] = ograph[i*ngraph+j];	}	free(ograph);	ngraph--;	present[which] = 0;}intaddmachine(char *name){	if(ngraph > 0){		fprint(2, "stats: internal error: ngraph>0 in addmachine()\n");		usage();	}	if(mach == nil)		nmach = 0;	/* a little dance to get us started with local machine by default */	mach = erealloc(mach, (nmach+1)*sizeof(Machine));	memset(mach+nmach, 0, sizeof(Machine));	if (initmach(mach+nmach, name)){		nmach++;		return 1;	} else		return 0;}voidlabelstrs(Graph *g, char strs[Nlab][Lablen], int *np){	int j;	ulong v, vmax;	g->newvalue(g->mach, &v, &vmax, 1);	if(logscale){		for(j=1; j<=2; j++)			sprint(strs[j-1], "%g", scale*pow(10., j)*(double)vmax/100.);		*np = 2;	}else{		for(j=1; j<=3; j++)			sprint(strs[j-1], "%g", scale*(double)j*(double)vmax/4.0);		*np = 3;	}}intlabelwidth(void){	int i, j, n, w, maxw;	char strs[Nlab][Lablen];	maxw = 0;	for(i=0; i<ngraph; i++){		/* choose value for rightmost graph */		labelstrs(&graph[ngraph*(nmach-1)+i], strs, &n);		for(j=0; j<n; j++){			w = stringwidth(mediumfont, strs[j]);			if(w > maxw)				maxw = w;		}	}	return maxw;}voidresize(void){	int i, j, k, n, startx, starty, x, y, dx, dy, ly, ondata, maxx, wid, nlab;	Graph *g;	Rectangle machr, r;	ulong v, vmax;	char buf[128], labs[Nlab][Lablen];	draw(screen, screen->r, display->white, nil, ZP);	/* label left edge */	x = screen->r.min.x;	y = screen->r.min.y + Labspace+mediumfont->height+Labspace;	dy = (screen->r.max.y - y)/ngraph;	dx = Labspace+stringwidth(mediumfont, "0")+Labspace;	startx = x+dx+1;	starty = y;	for(i=0; i<ngraph; i++,y+=dy){		draw(screen, Rect(x, y-1, screen->r.max.x, y), display->black, nil, ZP);		draw(screen, Rect(x, y, x+dx, screen->r.max.y), cols[graph[i].colindex][0], nil, paritypt(x));		label(Pt(x, y), dy, graph[i].label);		draw(screen, Rect(x+dx, y, x+dx+1, screen->r.max.y), cols[graph[i].colindex][2], nil, ZP);	}	/* label top edge */	dx = (screen->r.max.x - startx)/nmach;	for(x=startx, i=0; i<nmach; i++,x+=dx){		draw(screen, Rect(x-1, starty-1, x, screen->r.max.y), display->black, nil, ZP);		j = dx/stringwidth(mediumfont, "0");		n = mach[i].nproc;		if(n>1 && j>=1+3+(n>10)+(n>100)){	/* first char of name + (n) */			j -= 3+(n>10)+(n>100);			if(j <= 0)				j = 1;			snprint(buf, sizeof buf, "%.*s(%d)", j, mach[i].name, n);		}else			snprint(buf, sizeof buf, "%.*s", j, mach[i].name);		string(screen, Pt(x+Labspace, screen->r.min.y + Labspace), display->black, ZP, mediumfont, buf);	}	maxx = screen->r.max.x;	/* label right, if requested */	if(ylabels && dy>Nlab*(mediumfont->height+1)){		wid = labelwidth();		if(wid < (maxx-startx)-30){			/* else there's not enough room */			maxx -= 1+Lx+wid;			draw(screen, Rect(maxx, starty, maxx+1, screen->r.max.y), display->black, nil, ZP);			y = starty;			for(j=0; j<ngraph; j++, y+=dy){				/* choose value for rightmost graph */				g = &graph[ngraph*(nmach-1)+j];				labelstrs(g, labs, &nlab);				r = Rect(maxx+1, y, screen->r.max.x, y+dy-1);				if(j == ngraph-1)					r.max.y = screen->r.max.y;				draw(screen, r, cols[g->colindex][0], nil, paritypt(r.min.x));				for(k=0; k<nlab; k++){					ly = y + (dy*(nlab-k)/(nlab+1));					draw(screen, Rect(maxx+1, ly, maxx+1+Lx, ly+1), display->black, nil, ZP);					ly -= mediumfont->height/2;					string(screen, Pt(maxx+1+Lx, ly), display->black, ZP, mediumfont, labs[k]);				}			}		}	}	/* create graphs */	for(i=0; i<nmach; i++){		machr = Rect(startx+i*dx, starty, maxx, screen->r.max.y);		if(i < nmach-1)			machr.max.x = startx+(i+1)*dx - 1;		y = starty;		for(j=0; j<ngraph; j++, y+=dy){			g = &graph[i*ngraph+j];			/* allocate data */			ondata = g->ndata;			g->ndata = Dx(machr)+1;	/* may be too many if label will be drawn here; so what? */			g->data = erealloc(g->data, g->ndata*sizeof(ulong));			if(g->ndata > ondata)				memset(g->data+ondata, 0, (g->ndata-ondata)*sizeof(ulong));			/* set geometry */			g->r = machr;			g->r.min.y = y;			g->r.max.y = y+dy - 1;			if(j == ngraph-1)				g->r.max.y = screen->r.max.y;			draw(screen, g->r, cols[g->colindex][0], nil, paritypt(g->r.min.x));			g->overflow = 0;			r = g->r;			r.max.y = r.min.y+mediumfont->height;			r.max.x = r.min.x+stringwidth(mediumfont, "999999999999");			freeimage(g->overtmp);			g->overtmp = nil;			if(r.max.x <= g->r.max.x)				g->overtmp = allocimage(display, r, screen->chan, 0, -1);			g->newvalue(g->mach, &v, &vmax, 0);			redraw(g, vmax);		}	}	flushimage(display, 1);}voideresized(int new){	lockdisplay(display);	if(new && getwindow(display, Refnone) < 0) {		fprint(2, "stats: can't reattach to window\n");		killall("reattach");	}	resize();	unlockdisplay(display);}voidmouseproc(void){	Mouse mouse;	int i;	for(;;){		mouse = emouse();		if(mouse.buttons == 4){			lockdisplay(display);			for(i=0; i<Nmenu2; i++)				if(present[i])					memmove(menu2str[i], "drop ", Opwid);				else					memmove(menu2str[i], "add  ", Opwid);			i = emenuhit(3, &mouse, &menu2);			if(i >= 0){				if(!present[i])					addgraph(i);				else if(ngraph > 1)					dropgraph(i);				resize();			}			unlockdisplay(display);		}	}}voidstartproc(void (*f)(void), int index){	int pid;	switch(pid = rfork(RFPROC|RFMEM|RFNOWAIT)){	case -1:		fprint(2, "stats: fork failed: %r\n");		killall("fork failed");	case 0:		f();		fprint(2, "stats: %s process exits\n", procnames[index]);		if(index >= 0)			killall("process died");		exits(nil);	}	if(index >= 0)		pids[index] = pid;}voidmain(int argc, char *argv[]){	int i, j;	double secs;	ulong v, vmax, nargs;	char args[100];	nmach = 1;	mysysname = getenv("sysname");	if(mysysname == nil){		fprint(2, "stats: can't find $sysname: %r\n");		exits("sysname");	}	mysysname = estrdup(mysysname);	nargs = 0;	ARGBEGIN{	case 'T':		secs = atof(EARGF(usage()));		if(secs > 0)			sleeptime = 1000*secs;		break;	case 'S':		scale = atof(EARGF(usage()));		if(scale <= 0)			usage();		break;	case 'L':		logscale++;		break;	case 'Y':		ylabels++;		break;	case 'O':		oldsystem = 1;		break;	default:		if(nargs>=sizeof args || strchr(argchars, ARGC())==nil)			usage();		args[nargs++] = ARGC();	}ARGEND	if(argc == 0){		mach = emalloc(nmach*sizeof(Machine));		initmach(&mach[0], mysysname);		readmach(&mach[0], 1);	}else{		for(i=j=0; i<argc; i++){			if (addmachine(argv[i]))				readmach(&mach[j++], 1);		}		if (j == 0)			exits("connect");	}	for(i=0; i<nargs; i++)	switch(args[i]){	default:		fprint(2, "stats: internal error: unknown arg %c\n", args[i]);		usage();	case 'b':		addgraph(Mbattery);		break;	case 'c':		addgraph(Mcontext);		break;	case 'e':		addgraph(Mether);		break;	case 'E':		addgraph(Metherin);		addgraph(Metherout);		break;	case 'f':		addgraph(Mfault);		break;	case 'i':		addgraph(Mintr);		break;	case 'I':		addgraph(Mload);		addgraph(Midle);		addgraph(Minintr);		break;	case 'l':		addgraph(Mload);		break;	case 'm':		addgraph(Mmem);		break;	case 'n':		addgraph(Metherin);		addgraph(Metherout);		addgraph(Methererr);		break;	case 'p':		addgraph(Mtlbpurge);		break;	case 's':		addgraph(Msyscall);		break;	case 't':		addgraph(Mtlbmiss);		addgraph(Mtlbpurge);		break;	case '8':		addgraph(Msignal);		break;	case 'w':		addgraph(Mswap);		break;	}	if(ngraph == 0)		addgraph(Mload);	for(i=0; i<nmach; i++)		for(j=0; j<ngraph; j++)			graph[i*ngraph+j].mach = &mach[i];	if(initdraw(nil, nil, "stats") < 0){		fprint(2, "stats: initdraw failed: %r\n");		exits("initdraw");	}	colinit();	einit(Emouse);	notify(nil);	startproc(mouseproc, Mouseproc);	pids[Mainproc] = getpid();	display->locking = 1;	/* tell library we're using the display lock */	resize();	unlockdisplay(display); /* display is still locked from initdraw() */	for(;;){		for(i=0; i<nmach; i++)			readmach(&mach[i], 0);		lockdisplay(display);		parity = 1-parity;		for(i=0; i<nmach*ngraph; i++){			graph[i].newvalue(graph[i].mach, &v, &vmax, 0);			graph[i].update(&graph[i], v, vmax);		}		flushimage(display, 1);		unlockdisplay(display);		sleep(sleeptime);	}}

⌨️ 快捷键说明

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