Ahmed KhanzadaInitial commit530bf497 years agoHistory
1417 lines · 28.6 KB · C
RawDownload
#include <u.h>#include <libc.h>#include <ctype.h>#include <draw.h>#include <event.h>#include <keyboard.h> #define	MAXNUM	10	/* maximum number of numbers on data line */ typedef struct Graph	Graph;typedef struct Machine	Machine; struct Graph{	int		colindex;	Rectangle	r;	int		*data;	int		ndata;	char		*label;	void		(*newvalue)(Machine*, uvlong*, uvlong*, int);	void		(*update)(Graph*, uvlong, uvlong);	Machine		*mach;	int		overflow;	Image		*overtmp;}; enum{	/* /dev/swap */	Mem		= 0,	Maxmem,	Swap,	Maxswap,	Reclaim,	Maxreclaim,	Kern,	Maxkern,	Draw,	Maxdraw, 	/* /dev/sysstats */	Procno	= 0,	Context,	Interrupt,	Syscall,	Fault,	TLBfault,	TLBpurge,	Load,	Idle,	InIntr, 	/* /net/ether0/stats */	In		= 0,	Link,	Out,	Err0,}; struct Machine{	char		*name;	char		*shortname;	int		remote;	int		statsfd;	int		swapfd;	int		etherfd;	int		ifstatsfd;	int		batteryfd;	int		bitsybatfd;	int		tempfd;	int		disable; 	uvlong		devswap[10];	uvlong		devsysstat[10];	uvlong		prevsysstat[10];	int		nproc;	int		lgproc;	uvlong		netetherstats[8];	uvlong		prevetherstats[8];	uvlong		batterystats[2];	uvlong		netetherifstats[2];	uvlong		temp[10]; 	/* big enough to hold /dev/sysstat even with many processors */	char		buf[8*1024];	char		*bufp;	char		*ebufp;}; enum{	Mainproc,	Inputproc,	NPROC,}; enum{	Ncolor		= 6,	Ysqueeze	= 2,	/* vertical squeezing of label text */	Labspace	= 2,	/* room around label */	Dot		= 2,	/* height of dot */	Opwid		= 5,	/* strlen("add  ") or strlen("drop ") */	Nlab		= 3,	/* max number of labels on y axis */	Lablen		= 16,	/* max length of label */	Lx		= 4,	/* label tick length */}; enum Menu2{	Mbattery,	Mcontext,	Mether,	Methererr,	Metherin,	Metherout,	Mfault,	Midle,	Minintr,	Mintr,	Mload,	Mmem,	Mswap,	Mreclaim,	Mkern,	Mdraw,	Msyscall,	Mtlbmiss,	Mtlbpurge,	Msignal,	Mtemp,	Nmenu2,}; char	*menu2str[Nmenu2+1] = {	"add  battery ",	"add  context ",	"add  ether   ",	"add  ethererr",	"add  etherin ",	"add  etherout",	"add  fault   ",	"add  idle    ",	"add  inintr  ",	"add  intr    ",	"add  load    ",	"add  mem     ",	"add  swap    ",	"add  reclaim ",	"add  kern    ",	"add  draw    ",	"add  syscall ",	"add  tlbmiss ",	"add  tlbpurge",	"add  802.11b ",	"add  temp    ",	nil,};  void	contextval(Machine*, uvlong*, uvlong*, int),	etherval(Machine*, uvlong*, uvlong*, int),	ethererrval(Machine*, uvlong*, uvlong*, int),	etherinval(Machine*, uvlong*, uvlong*, int),	etheroutval(Machine*, uvlong*, uvlong*, int),	faultval(Machine*, uvlong*, uvlong*, int),	intrval(Machine*, uvlong*, uvlong*, int),	inintrval(Machine*, uvlong*, uvlong*, int),	loadval(Machine*, uvlong*, uvlong*, int),	idleval(Machine*, uvlong*, uvlong*, int),	memval(Machine*, uvlong*, uvlong*, int),	swapval(Machine*, uvlong*, uvlong*, int),	reclaimval(Machine*, uvlong*, uvlong*, int),	kernval(Machine*, uvlong*, uvlong*, int),	drawval(Machine*, uvlong*, uvlong*, int),	syscallval(Machine*, uvlong*, uvlong*, int),	tlbmissval(Machine*, uvlong*, uvlong*, int),	tlbpurgeval(Machine*, uvlong*, uvlong*, int),	batteryval(Machine*, uvlong*, uvlong*, int),	signalval(Machine*, uvlong*, uvlong*, int),	tempval(Machine*, uvlong*, uvlong*, int); Menu	menu2 = {menu2str, nil};int	present[Nmenu2];void	(*newvaluefn[Nmenu2])(Machine*, uvlong*, uvlong*, int init) = {	batteryval,	contextval,	etherval,	ethererrval,	etherinval,	etheroutval,	faultval,	idleval,	inintrval,	intrval,	loadval,	memval,	swapval,	reclaimval,	kernval,	drawval,	syscallval,	tlbmissval,	tlbpurgeval,	signalval,	tempval,}; Image	*cols[Ncolor][3];Graph	*graph;Machine	*mach;char	*mysysname;char	argchars[] = "8bcdeEfiIkmlnprstwz";int	pids[NPROC];int 	parity;	/* toggled to avoid patterns in textured background */int	nmach;int	ngraph;	/* totaly number is ngraph*nmach */double	scale = 1.0;int	logscale = 0;int	ylabels = 0;int 	sleeptime = 1000; char	*procnames[NPROC] = {"main", "input"}; voidkillall(char *s){	int i, pid; 	pid = getpid();	for(i=0; i<NPROC; i++)		if(pids[i] && pids[i]!=pid)			postnote(PNPROC, pids[i], "kill");	exits(s);} void*emalloc(ulong sz){	void *v;	v = malloc(sz);	if(v == nil) {		fprint(2, "stats: out of memory allocating %ld: %r\n", sz);		killall("mem");	}	memset(v, 0, sz);	return v;} void*erealloc(void *v, ulong sz){	v = realloc(v, sz);	if(v == nil) {		fprint(2, "stats: out of memory reallocating %ld: %r\n", sz);		killall("mem");	}	return v;} char*estrdup(char *s){	char *t;	if((t = strdup(s)) == nil) {		fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s);		killall("mem");	}	return t;} voidmkcol(int i, int c0, int c1, int c2){	cols[i][0] = allocimagemix(display, c0, DBlack);	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);} voidcolinit(void){	/* Peach */	mkcol(0, 0xFFFFFFFF, 0x383838FF, 0xC8C8C8FF);	/* Aqua */	mkcol(1, 0xFFFFFFFF, 0x383838FF, 0xC8C8C8FF);	/* Yellow */	mkcol(2, 0xFFFFFFFF, 0x383838FF, 0xC8C8C8FF);	/* Green */	mkcol(3, 0xFFFFFFFF, 0x383838FF, 0xC8C8C8FF);	/* Blue */	mkcol(4, 0xFFFFFFFF, 0x383838FF, 0xC8C8C8FF);	/* 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);} intloadbuf(Machine *m, int *fd){	int n;  	if(*fd < 0)		return 0;	seek(*fd, 0, 0);	n = read(*fd, m->buf, sizeof m->buf-1);	if(n <= 0){		close(*fd);		*fd = -1;		return 0;	}	m->bufp = m->buf;	m->ebufp = m->buf+n;	m->buf[n] = 0;	return 1;} voidlabel(Point p, int dy, char *text){	char *s;	Rune r[2];	int w, maxw, maxy; 	p.x += Labspace;	maxy = p.y+dy;	maxw = 0;	r[1] = '\0';	for(s=text; *s; ){		if(p.y+font->height-Ysqueeze > maxy)			break;		w = chartorune(r, s);		s += w;		w = runestringwidth(font, r);		if(w > maxw)			maxw = w;		runestring(screen, p, display->black, ZP, font, r);		p.y += font->height-Ysqueeze;	}} Pointparitypt(int x){	return Pt(x+parity, 0);} Pointdatapoint(Graph *g, int x, uvlong v, uvlong vmax){	Point p;	double y; 	p.x = x;	y = ((double)v)/(vmax*scale);	if(logscale){		/*		 * Arrange scale to cover a factor of 1000.		 * vmax corresponds to the 100 mark.		 * 10*vmax is the top of the scale.		 */		if(y <= 0.)			y = 0;		else{			y = log10(y);			/* 1 now corresponds to the top; -2 to the bottom; rescale */			y = (y+2.)/3.;		}	}	if(y >= 1.)		y = 1;	if(y <= 0.)		y = 0;	p.y = g->r.max.y - Dy(g->r)*y - Dot;	if(p.y < g->r.min.y)		p.y = g->r.min.y;	if(p.y > g->r.max.y-Dot)		p.y = g->r.max.y-Dot;	return p;} voiddrawdatum(Graph *g, int x, uvlong prev, uvlong v, uvlong vmax){	int c;	Point p, q; 	c = g->colindex;	p = datapoint(g, x, v, vmax);	q = datapoint(g, x, prev, vmax);	if(p.y < q.y){		draw(screen, Rect(p.x, g->r.min.y, p.x+1, p.y), cols[c][0], nil, paritypt(p.x));		draw(screen, Rect(p.x, p.y, p.x+1, q.y+Dot), cols[c][2], nil, ZP);		draw(screen, Rect(p.x, q.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);	}else{		draw(screen, Rect(p.x, g->r.min.y, p.x+1, q.y), cols[c][0], nil, paritypt(p.x));		draw(screen, Rect(p.x, q.y, p.x+1, p.y+Dot), cols[c][2], nil, ZP);		draw(screen, Rect(p.x, p.y+Dot, p.x+1, g->r.max.y), cols[c][1], nil, ZP);	} } voidredraw(Graph *g, uvlong vmax){	int i, c; 	c = g->colindex;	draw(screen, g->r, cols[c][0], nil, paritypt(g->r.min.x));	for(i=1; i<Dx(g->r); i++)		drawdatum(g, g->r.max.x-i, g->data[i-1], g->data[i], vmax);	drawdatum(g, g->r.min.x, g->data[i], g->data[i], vmax);	g->overflow = 0;} voidupdate1(Graph *g, uvlong v, uvlong vmax){	char buf[48];	int overflow; 	if(g->overflow && g->overtmp!=nil)		draw(screen, g->overtmp->r, g->overtmp, nil, g->overtmp->r.min);	draw(screen, g->r, screen, nil, Pt(g->r.min.x+1, g->r.min.y));	drawdatum(g, g->r.max.x-1, g->data[0], v, vmax);	memmove(g->data+1, g->data, (g->ndata-1)*sizeof(g->data[0]));	g->data[0] = v;	g->overflow = 0;	if(logscale)		overflow = (v>10*vmax*scale);	else		overflow = (v>vmax*scale);	if(overflow && g->overtmp!=nil){		g->overflow = 1;		draw(g->overtmp, g->overtmp->r, screen, nil, g->overtmp->r.min);		sprint(buf, "%llud", v);		string(screen, g->overtmp->r.min, display->black, ZP, font, buf);	}} /* read one line of text from buffer and process integers */intreadnums(Machine *m, int n, uvlong *a, int spanlines){	int i;	char *p, *ep; 	if(spanlines)		ep = m->ebufp;	else		for(ep=m->bufp; ep<m->ebufp; ep++)			if(*ep == '\n')				break;	p = m->bufp;	for(i=0; i<n && p<ep; i++){		while(p<ep && (!isascii(*p) || !isdigit(*p)) && *p!='-')			p++;		if(p == ep)			break;		a[i] = strtoull(p, &p, 10);	}	if(ep < m->ebufp)		ep++;	m->bufp = ep;	return i == n;} intreadswap(Machine *m, uvlong *a){	static int xxx = 0; 	if(strstr(m->buf, "memory\n")){		/* new /dev/swap - skip first 3 numbers */		if(!readnums(m, 7, a, 1))			return 0; 		a[Mem] = a[3];		a[Maxmem] = a[4];		a[Swap] = a[5];		a[Maxswap] = a[6]; 		a[Reclaim] = 0;		a[Maxreclaim] = 0;		if(m->bufp = strstr(m->buf, "reclaim")){			while(m->bufp > m->buf && m->bufp[-1] != '\n')				m->bufp--;			a[Reclaim] = strtoull(m->bufp, &m->bufp, 10);			while(*m->bufp++ == '/')				a[Maxreclaim] = strtoull(m->bufp, &m->bufp, 10);		} 		a[Kern] = 0;		a[Maxkern] = 0;		if(m->bufp = strstr(m->buf, "kernel malloc")){			while(m->bufp > m->buf && m->bufp[-1] != '\n')				m->bufp--;

Lines 1–500 of 1417.