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
--
⑨