9front - general discussion about 9front
 help / color / mirror / Atom feed
* multi-battery, multi-ethernet stats
@ 2019-12-01 23:55 ori
  0 siblings, 0 replies; only message in thread
From: ori @ 2019-12-01 23:55 UTC (permalink / raw)
  To: 9front

My laptop (Thinkpad X260) has 2 batteries, and 2 ethernet
cards. This change to stats improves reporting by aggregating
all batteries listed in the battery file, and up to 8 ethernet
card stats.

It also gets rid of the multiple battery FDs, replacing it with
a battery type and field count.

diff -r 94226ee6784b sys/src/cmd/stats.c
--- a/sys/src/cmd/stats.c	Sun Dec 01 17:57:14 2019 +0100
+++ b/sys/src/cmd/stats.c	Sun Dec 01 15:54:29 2019 -0800
@@ -26,6 +26,13 @@
 
 enum
 {
+	ApmBat,
+	AcpiBat,
+	BitsyBat,
+};
+
+enum
+{
 	/* /dev/swap */
 	Mem		= 0,
 	Maxmem,
@@ -51,6 +58,7 @@
 	InIntr,
 
 	/* /net/ether0/stats */
+	Maxether	= 8,
 	In		= 0,
 	Link,
 	Out,
@@ -64,10 +72,12 @@
 	int		remote;
 	int		statsfd;
 	int		swapfd;
-	int		etherfd;
-	int		ifstatsfd;
+	/* -1 terminated */
+	int		etherfd[Maxether + 1];
+	int		ifstatsfd[Maxether + 1];
 	int		batteryfd;
-	int		bitsybatfd;
+	int		batteryfields;
+	int		batterytype;
 	int		tempfd;
 	int		disable;
 
@@ -78,7 +88,7 @@
 	int		lgproc;
 	uvlong		netetherstats[8];
 	uvlong		prevetherstats[8];
-	uvlong		batterystats[2];
+	uvlong		batterystats[3];
 	uvlong		netetherifstats[2];
 	uvlong		temp[10];
 
@@ -443,11 +453,13 @@
 
 /* read one line of text from buffer and process integers */
 int
-readnums(Machine *m, int n, uvlong *a, int spanlines)
+scanln(Machine *m, int n, uvlong *a, int spanlines, int clear)
 {
 	int i;
 	char *p, *ep;
 
+	if(clear)
+		memset(a, 0, n*sizeof(*a));
 	if(spanlines)
 		ep = m->ebufp;
 	else
@@ -460,7 +472,7 @@
 			p++;
 		if(p == ep)
 			break;
-		a[i] = strtoull(p, &p, 10);
+		a[i] += strtoull(p, &p, 10);
 	}
 	if(ep < m->ebufp)
 		ep++;
@@ -469,6 +481,50 @@
 }
 
 int
+sumnumlns(Machine *m, int n, uvlong *a)
+{
+	int r;
+	
+	r = 0;
+	memset(a, 0, n*sizeof(*a));
+	while(1)
+		if(scanln(m, n, a, 0, 0))
+			r = 1;
+		else
+			break;
+	return r;
+}
+
+int
+readnums(Machine *m, int n, uvlong *a, int spanlines)
+{
+	return scanln(m, n, a, spanlines, 1);
+}
+
+int
+aggrnums(Machine *m, int n, uvlong *a, int spanlines)
+{
+	return scanln(m, n, a, spanlines, 0);
+}
+
+int
+readether(Machine *m, int *fd, int na, uvlong *a)
+{
+	int i;
+
+	memset(a, 0, na*sizeof(*a));
+	for(i = 0; fd[i] != -1; i++){
+		if(fd[i] == -1)
+			break;
+		if(!loadbuf(m, &fd[i]))
+			return 0;
+		if(!aggrnums(m, na, a, 1))
+			return 0;
+	}
+	return 1;
+}
+
+int
 readswap(Machine *m, uvlong *a)
 {
 	static int xxx = 0;
@@ -551,7 +607,7 @@
 int
 initmach(Machine *m, char *name)
 {
-	int n;
+	int n, i, j;
 	uvlong a[MAXNUM];
 	char *p, mpt[256], buf[256];
 
@@ -604,35 +660,58 @@
 		m->nproc = 1;
 	m->lgproc = ilog10(m->nproc);
 
-	snprint(buf, sizeof buf, "%s/net/ether0/stats", mpt);
-	m->etherfd = open(buf, OREAD);
-	if(loadbuf(m, &m->etherfd) && readnums(m, nelem(m->netetherstats), a, 1))
+	for(i = 0, j = 0; i < Maxether; i++){
+		snprint(buf, sizeof buf, "%s/net/ether%d/stats", mpt, i);
+		if((m->etherfd[j] = open(buf, OREAD)) != -1)
+			j++;
+	}
+	m->etherfd[j] = -1;
+	if(readether(m, m->etherfd, nelem(m->netetherstats), a))
 		memmove(m->netetherstats, a, sizeof m->netetherstats);
 
-	snprint(buf, sizeof buf, "%s/net/ether0/ifstats", mpt);
-	m->ifstatsfd = open(buf, OREAD);
-	if(loadbuf(m, &m->ifstatsfd)){
+	for(i = 0, j = 0; i < Maxether; i++){
+		snprint(buf, sizeof buf, "%s/net/ether%d/ifstats", mpt, i);
+		if((m->ifstatsfd[j] = open(buf, OREAD)) == -1)
+			continue;
+		if(!loadbuf(m, &m->ifstatsfd[j]))
+			continue;
 		/* need to check that this is a wavelan interface */
-		if(strncmp(m->buf, "Signal: ", 8) == 0 && readnums(m, nelem(m->netetherifstats), a, 1))
-			memmove(m->netetherifstats, a, sizeof m->netetherifstats);
+		if(strncmp(m->buf, "Signal: ", 8) != 0){
+			close(m->ifstatsfd[j]);
+			m->ifstatsfd[j] = -1;
+			continue;
+		}
+		j++;
 	}
+	m->ifstatsfd[j] = -1;
+	if(readether(m, m->ifstatsfd, nelem(m->netetherifstats), a))
+		memmove(m->netetherifstats, a, sizeof m->netetherifstats);
 
 	snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt);
 	m->batteryfd = open(buf, OREAD);
-	if(m->batteryfd < 0){
-		snprint(buf, sizeof buf, "%s/mnt/acpi/battery", mpt);
-		m->batteryfd = open(buf, OREAD);
+	if(m->batteryfd >= 0){
+		m->batterytype = ApmBat;
+		m->batteryfields = 2;
+		goto gotbattery;
 	}
-	m->bitsybatfd = -1;
+
+	snprint(buf, sizeof buf, "%s/mnt/acpi/battery", mpt);
+	m->batteryfd = open(buf, OREAD);
 	if(m->batteryfd >= 0){
-		if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))
-			memmove(m->batterystats, a, sizeof(m->batterystats));
-	}else{
-		snprint(buf, sizeof buf, "%s/dev/battery", mpt);
-		m->bitsybatfd = open(buf, OREAD);
-		if(loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0))
-			memmove(m->batterystats, a, sizeof(m->batterystats));
+		m->batterytype = AcpiBat;
+		m->batteryfields = 3;
+		goto gotbattery;
 	}
+	snprint(buf, sizeof buf, "%s/dev/battery", mpt);
+	m->batteryfd = open(buf, OREAD);
+	if(m->batteryfd >= 0){
+		m->batterytype = BitsyBat;
+		m->batteryfields = 2;
+		goto gotbattery;
+	}
+gotbattery:
+	if(loadbuf(m, &m->batteryfd) && sumnumlns(m, m->batteryfields, a))
+		memmove(m->batterystats, a, sizeof(m->batterystats));
 	snprint(buf, sizeof buf, "%s/dev/cputemp", mpt);
 	m->tempfd = open(buf, OREAD);
 	if(m->tempfd < 0){
@@ -730,16 +809,14 @@
 			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)){
+	if(needether(init) && readether(m, m->etherfd, nelem(m->netetherstats), a)){
 		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)){
+	if(needsignal(init) && readether(m, m->ifstatsfd, nelem(m->netetherifstats), a)){
 		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))
+	if(needbattery(init) && loadbuf(m, &m->batteryfd) && sumnumlns(m, m->batteryfields, a))
 		memmove(m->batterystats, a, sizeof(m->batterystats));
 	if(needtemp(init) && loadbuf(m, &m->tempfd))
 		for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
@@ -910,11 +987,23 @@
 void
 batteryval(Machine *m, uvlong *v, uvlong *vmax, int)
 {
-	*v = m->batterystats[0];
-	if(m->bitsybatfd >= 0)
+	switch(m->batterytype){
+	case ApmBat:
+		/* percentage */
+		*v = m->batterystats[0];
+		*vmax = 100;
+		break;
+	case BitsyBat:
+		/* whatever bitsy does */
+		*v = m->batterystats[0];
 		*vmax = 184;		// at least on my bitsy...
-	else
-		*vmax = 100;
+		break;
+	case AcpiBat:
+		/* capacity, max capacity: works better with summing batteries. */
+		*v = m->batterystats[1];
+		*vmax = m->batterystats[2];
+		break;
+	}
 }
 
 void



^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2019-12-01 23:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-01 23:55 multi-battery, multi-ethernet stats ori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).