git: 9front

Download patch

ref: 9bbbcfdac66a4ba54d62e10d6ddd682313823664
parent: 1f96ebf54b0755013e81ddcc13b150113c6521de
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Fri Jan 2 19:50:38 EST 2026

stats: run readmach() for each machine in its own process

Get rid of the alarm() timeouts and just run
each machine's sampling function in its own
process.

This way, if there are networking issues,
the graph just stops ticking for that machine but
other graphs continue normally.

The drawing is serialised with display lock.

Handle the shutdown of the processes with atexit()
handler.

--- a/sys/src/cmd/stats.c
+++ b/sys/src/cmd/stats.c
@@ -64,13 +64,13 @@
 {
 	char		*name;
 	char		*shortname;
-	int		remote;
+
+	int		pid;
 	int		statsfd;
 	int		swapfd;
 	int		etherfd[10];
 	int		batteryfd;
 	int		tempfd;
-	int		disable;
 
 	uvlong		devswap[10];
 	uvlong		devsysstat[10];
@@ -90,13 +90,6 @@
 
 enum
 {
-	Mainproc,
-	Inputproc,
-	NPROC,
-};
-
-enum
-{
 	Ncolor		= 6,
 	Ysqueeze	= 2,	/* vertical squeezing of label text */
 	Labspace	= 2,	/* room around label */
@@ -212,7 +205,6 @@
 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 */
@@ -223,18 +215,18 @@
 int	batteryperiod = 10000;
 int	tempperiod = 1000;
 
-char	*procnames[NPROC] = {"main", "input"};
-
 void
-killall(char *s)
+killall(void)
 {
-	int i, pid;
+	int i;
 
-	pid = getpid();
-	for(i=0; i<NPROC; i++)
-		if(pids[i] && pids[i]!=pid)
-			postnote(PNPROC, pids[i], "kill");
-	exits(s);
+	if(mach == nil)
+		return;
+	for(i=0; i<nmach; i++){
+		if(mach[i].pid <= 0)
+			continue;
+		postnote(PNPROC, mach[i].pid, "kill");
+	}
 }
 
 void*
@@ -242,10 +234,8 @@
 {
 	void *v;
 	v = malloc(sz);
-	if(v == nil) {
-		fprint(2, "stats: out of memory allocating %ld: %r\n", sz);
-		killall("mem");
-	}
+	if(v == nil)
+		sysfatal("out of memory allocating %ld: %r", sz);
 	memset(v, 0, sz);
 	return v;
 }
@@ -254,10 +244,8 @@
 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");
-	}
+	if(v == nil)
+		sysfatal("out of memory reallocating %ld: %r", sz);
 	return v;
 }
 
@@ -265,10 +253,8 @@
 estrdup(char *s)
 {
 	char *t;
-	if((t = strdup(s)) == nil) {
-		fprint(2, "stats: out of memory in strdup(%.10s): %r\n", s);
-		killall("mem");
-	}
+	if((t = strdup(s)) == nil)
+		sysfatal("out of memory in strdup(%.10s): %r", s);
 	return t;
 }
 
@@ -684,8 +670,7 @@
 		p = name;
 	m->name = estrdup(p);
 	m->shortname = shortname(p);
-	m->remote = (strcmp(p, mysysname) != 0);
-	if(m->remote == 0)
+	if(strcmp(p, mysysname) == 0)
 		strcpy(mpt, "");
 	else{
 		Waitmsg *w;
@@ -770,17 +755,7 @@
 	return 1;
 }
 
-jmp_buf catchalarm;
-
 int
-alarmed(void *a, char *s)
-{
-	if(strcmp(s, "alarm") == 0)
-		notejmp(a, catchalarm, 1);
-	return 0;
-}
-
-int
 needswap(int init)
 {
 	return init | present[Mmem] | present[Mswap] | present[Mreclaim] | present[Mkern] | present[Mdraw];
@@ -839,30 +814,9 @@
 void
 readmach(Machine *m, int init)
 {
-	int n;
 	uvlong a[nelem(m->devsysstat)];
-	char buf[32];
+	int n;
 
-	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);
-		free(m->shortname);
-		m->shortname = shortname(buf);
-		if(display != nil)	/* else we're still initializing */
-			eresized(0);
-	}
-	if(m->remote){
-		atnotify(alarmed, 1);
-		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)){
@@ -886,9 +840,22 @@
 	if(needtemp(init) && loadbuf(m, &m->tempfd))
 		for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
 			 m->temp[n] = a[0];
-	if(m->remote){
-		alarm(0);
-		atnotify(alarmed, 0);
+}
+
+void
+updatemach(Machine *m)
+{
+	uvlong v, vmax;
+	Graph *g, *e;
+
+	for(g = &graph[ngraph*(m-mach)], e = g+ngraph; g < e; g++){
+		if(g->mach != m)
+			continue;
+		g->newvalue(m, &v, &vmax, 0);
+		if(vmax == 0)
+			vmax = 1;
+		vmax = roundvmax(vmax);
+		g->update(g, v, vmax);
 	}
 }
 
@@ -1134,10 +1101,8 @@
 			n = i;
 			break;
 		}
-	if(n < 0){
-		fprint(2, "stats: internal error can't drop graph\n");
-		killall("error");
-	}
+	if(n < 0)
+		sysfatal("internal error can't drop graph");
 	ograph = graph;
 	graph = emalloc(nmach*(ngraph-1)*sizeof(Graph));
 	for(i=0; i<nmach; i++){
@@ -1153,22 +1118,13 @@
 	present[which] = 0;
 }
 
-int
+void
 addmachine(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)){
+	if (initmach(mach+nmach, name))
 		nmach++;
-		return 1;
-	} else
-		return 0;
 }
 
 void
@@ -1262,80 +1218,23 @@
 eresized(int new)
 {
 	lockdisplay(display);
-	if(new && getwindow(display, Refnone) < 0) {
-		fprint(2, "stats: can't reattach to window\n");
-		killall("reattach");
-	}
+	if(new && getwindow(display, Refnone) < 0)
+		sysfatal("can't reattach to window: %r");
 	resize();
 	unlockdisplay(display);
 }
 
 void
-inputproc(void)
-{
-	Event e;
-	int i;
-
-	for(;;){
-		switch(eread(Emouse|Ekeyboard, &e)){
-		case Emouse:
-			if(e.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, &e.mouse, &menu2);
-				if(i >= 0){
-					if(!present[i])
-						addgraph(i);
-					else if(ngraph > 1)
-						dropgraph(i);
-					resize();
-				}
-				unlockdisplay(display);
-			}
-			break;
-		case Ekeyboard:
-			if(e.kbdc==Kdel || e.kbdc=='q')
-				killall(nil);
-			break;
-		}
-	}
-}
-
-void
-startproc(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;
-}
-
-void
 main(int argc, char *argv[])
 {
+	Event e;
 	int i, j;
 	double secs;
-	uvlong v, vmax, nargs;
 	char args[100];
+	int nargs;
 
 	quotefmtinstall();
 
-	nmach = 1;
 	mysysname = getenv("sysname");
 	if(mysysname == nil){
 		fprint(2, "stats: can't find $sysname: %r\n");
@@ -1369,17 +1268,11 @@
 	}ARGEND
 
 	if(argc == 0){
-		mach = emalloc(nmach*sizeof(Machine));
-		initmach(&mach[0], mysysname);
-		readmach(&mach[0], 1);
+		addmachine(mysysname);
 	}else{
 		rfork(RFNAMEG);
-		for(i=j=0; i<argc; i++){
-			if (addmachine(argv[i]))
-				readmach(&mach[j++], 1);
-		}
-		if (j == 0)
-			exits("connect");
+		for(i=0; i<argc; i++)
+			addmachine(argv[i]);
 	}
 
 	for(i=0; i<nargs; i++)
@@ -1453,37 +1346,61 @@
 	if(ngraph == 0)
 		addgraph(Mload);
 
-	for(i=0; i<nmach; i++)
+	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");
 	}
-	display->locking = 1;	/* tell library we're using the display lock */
+
+	if(initdraw(nil, nil, "stats") < 0)
+		sysfatal("initdraw failed: %r");
 	colinit();
 	einit(Emouse|Ekeyboard);
-	startproc(inputproc, Inputproc);
-	pids[Mainproc] = getpid();
-
 	resize();
+	unlockdisplay(display);
 
-	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);
-			if(vmax == 0)
-				vmax = 1;
-			vmax = roundvmax(vmax);
-			graph[i].update(&graph[i], v, vmax);
+	atexit(killall);
+	for(i=0; i<nmach; i++){
+		if((j = rfork(RFPROC|RFMEM)) == 0){
+			procsetname("%s", mach[i].shortname);
+			readmach(&mach[i], 1);
+			for(;;) {
+				lockdisplay(display);
+				parity = j++ & 1;
+				updatemach(&mach[i]);
+				flushimage(display, 1);
+				unlockdisplay(display);
+
+				sleep(sleeptime);
+				readmach(&mach[i], 0);
+			}
 		}
-		flushimage(display, 1);
-		unlockdisplay(display);
-		sleep(sleeptime);
+		mach[i].pid = j;
 	}
+
+	for(;;)
+		switch(eread(Emouse|Ekeyboard, &e)){
+		case Emouse:
+			if(e.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, &e.mouse, &menu2);
+				if(i >= 0){
+					if(!present[i])
+						addgraph(i);
+					else if(ngraph > 1)
+						dropgraph(i);
+					resize();
+				}
+				unlockdisplay(display);
+			}
+			break;
+		case Ekeyboard:
+			if(e.kbdc==Kdel || e.kbdc=='q')
+				exits(nil);
+			break;
+		}
 }
--