shithub: front

Download patch

ref: 74aef0eac9330a485ec332ee49575d990a7bd41a
parent: 5f27ddcb3c11e75609d82091557381eda7ebbcdf
author: Jacob Moody <moody@posixcafe.org>
date: Mon Aug 4 10:15:12 EDT 2025

stats: not on my bitsy

Commit 6a78bb2e4f00581d85de1c5f9949782de3dd8933 attempted to
address an issue with the temperature and battery percentage
calls being expensive through ACPI by creating a floor for how
often they are refreshed, however commit 55e5418e6945ec3275d34e04047ad706f6eb8e68
then changed the assumption for acpi to be mounted at /mnt/pm. While it may have
been planned to change the default mountpoint of of aux/acpi to /mnt/pm this has
yet to be done.

Attempting to guess at what the source the devices come from, and changing the global
floor on refreshing the values is a bit fragile and can have unintended side effects if
used with multiple machines. Instead let us just set reasonable values and document that
this is a potential problem with specifically ACPI. So the decision was made to make
battery refresh floor be 10 seconds, but cputemp to be kept at 1 second globally.
While it is unlikely that the battery percentage changes within 10 seconds, the
temperature very well could be changing on a second by second basis.

Additionally, there was a weird edge case in the code for specifically the bisty which
seemed to have a maximum charge percent of 184. Due to the how the code worked, with the
default aux/acpi invocation we would instead hit this bitsy case resulting in fully charged
thinkpads displaying as only ~1/2 charged. Let's just get rid of this mess.

Perhaps we should change the default mountpoint of aux/acpi to /mnt/pm, but for now we should
work well with the default invocation and document this quirk, while maintaining consistency for
wherever this may be mounted in the namespace.

--- a/sys/man/8/stats
+++ b/sys/man/8/stats
@@ -114,6 +114,12 @@
 If the value of the parameter is too large for the visible range, its value is shown
 in decimal in the upper left corner of the graph.
 .PP
+On some hardware,
+remaining battery life and current temperature are retrieved through ACPI.
+This may be computationally expensive.
+To avoid excessive battery drain on laptops,
+the current battery levels are only updated every 10 seconds.
+.PP
 Upper-case options control details of the display.
 All graphs are affected; there is no mechanism to
 affect only one graph.
@@ -164,5 +170,7 @@
 .B #c/sysstat
 .SH SOURCE
 .B /sys/src/cmd/stats.c
+.SH SEE ALSO
+.IR acpi (8)
 .SH BUGS
 Some machines do not have TLB hardware.
--- a/sys/src/cmd/stats.c
+++ b/sys/src/cmd/stats.c
@@ -69,7 +69,6 @@
 	int		swapfd;
 	int		etherfd[10];
 	int		batteryfd;
-	int		bitsybatfd;
 	int		tempfd;
 	int		disable;
 
@@ -221,7 +220,7 @@
 int	logscale = 0;
 int	ylabels = 0;
 int	sleeptime = 1000;
-int	batteryperiod = 1000;
+int	batteryperiod = 10000;
 int	tempperiod = 1000;
 
 char	*procnames[NPROC] = {"main", "input"};
@@ -672,6 +671,11 @@
 	uvlong a[MAXNUM];
 	char *p, mpt[256], buf[256];
 	Dir *d;
+	static char *archplaces[] = {
+		"/dev",
+		"/mnt/pm",
+		"/mnt/apm",	/* battery only */
+	};
 
 	p = strchr(name, '!');
 	if(p)
@@ -744,33 +748,25 @@
 	while(n < nelem(m->etherfd))
 		m->etherfd[n++] = -1;
 
-	snprint(buf, sizeof buf, "%s/mnt/apm/battery", mpt);
-	m->batteryfd = open(buf, OREAD);
-	if(m->batteryfd < 0){
-		snprint(buf, sizeof buf, "%s/mnt/pm/battery", mpt);
+	for(i=0; i < nelem(archplaces); i++){
+		snprint(buf, sizeof buf, "%s/%s/battery", mpt, archplaces[i]);
 		m->batteryfd = open(buf, OREAD);
-	}
-	m->bitsybatfd = -1;
-	if(m->batteryfd >= 0){
-		batteryperiod = 10000;
+		if(m->batteryfd < 0)
+			continue;
 		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));
+		break;
 	}
-	snprint(buf, sizeof buf, "%s/dev/cputemp", mpt);
-	m->tempfd = open(buf, OREAD);
-	if(m->tempfd < 0){
-		tempperiod = 5000;
-		snprint(buf, sizeof buf, "%s/mnt/pm/cputemp", mpt);
+	for(i=0; i < nelem(archplaces); i++){
+		snprint(buf, sizeof buf, "%s/%s/cputemp", mpt, archplaces[i]);
 		m->tempfd = open(buf, OREAD);
+		if(m->tempfd < 0)
+			continue;
+		if(loadbuf(m, &m->tempfd))
+			for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
+				m->temp[n] = a[0];
+		break;
 	}
-	if(loadbuf(m, &m->tempfd))
-		for(n=0; n < nelem(m->temp) && readnums(m, 2, a, 0); n++)
-			 m->temp[n] = a[0];
 	return 1;
 }
 
@@ -886,8 +882,6 @@
 	if(needbattery(init)){
 		if(loadbuf(m, &m->batteryfd) && readnums(m, nelem(m->batterystats), a, 0))
 			memmove(m->batterystats, a, sizeof(m->batterystats));
-		else if(loadbuf(m, &m->bitsybatfd) && readnums(m, 1, a, 0))
-			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++)
@@ -1070,10 +1064,7 @@
 batteryval(Machine *m, uvlong *v, uvlong *vmax, int)
 {
 	*v = m->batterystats[0];
-	if(m->bitsybatfd >= 0)
-		*vmax = 184;		// at least on my bitsy...
-	else
-		*vmax = 100;
+	*vmax = 100;
 }
 
 void
--