On Wed, Feb 12 2020, Jeremie Courreges-Anglas <[email protected]> wrote:
> On Sat, Jan 25 2020, Jeremie Courreges-Anglas <[email protected]> wrote:
>> The diff below improves the way apmd -z/-Z may trigger.
>>
>> I think the current behavior is bogus, incrementing and checking
>> apmtimeout like this doesn't make much sense.
>>
>> Here's a proposal:
>> - on APM_POWER_CHANGE events, check the battery level and trigger
>> autoaction if needed. This should be enough to make autoaction just
>> work with drivers like acpibat(4).
>> - on kevent timeout (10mn by default now, maybe too long), also check
>> the battery level and suspend if needed. This should be useful only
>> if your battery driver doesn't send any APM_POWER_CHANGE event.
>>
>> While here I also tweaked the warning.
>
> This has been committed, thanks Ted.
>
>> Some more context:
>> - a subsequent diff would reorder the code to handle similarly the "!rv"
>> and "ev->ident == ctl_fd" paths
>
> Diff below.
>
>> - I think we want some throttling mechanism, like wait for 1mn after we
>> resume before autosuspending again. But I want to fix obvious
>> problems first.
On top of the previous diff, here's a diff to block autoaction for 60
seconds after:
- autoaction triggers; this prevents apmd from sending multiple suspend
requests before the system goes to sleep
- a resume happens; this gives you 60 seconds to fetch and plug your AC
cable if you notice you're low on power
A side effect is that apmd now ignores stale acpiac(4) data at resume
time, so it apmd doesn't suspend the system again when you resume with
a low battery and AC plugged.
cc'ing Scott since he has a thing for everything time-related. :)
ok?
Index: apmd.c
===================================================================
--- apmd.c.orig
+++ apmd.c
@@ -380,6 +380,7 @@ main(int argc, char *argv[])
int powerstatus = 0, powerbak = 0, powerchange = 0;
int noacsleep = 0;
struct timespec ts = {TIMO, 0}, sts = {0, 0};
+ struct timespec autoaction_timestamp = { 0, 0 };
struct apm_power_info pinfo;
const char *sockname = _PATH_APM_SOCKET;
const char *errstr;
@@ -566,6 +567,7 @@ main(int argc, char *argv[])
powerstatus = powerbak;
powerchange = 1;
}
+ clock_gettime(CLOCK_MONOTONIC, &autoaction_timestamp);
resumes++;
break;
case APM_POWER_CHANGE:
@@ -577,6 +579,8 @@ main(int argc, char *argv[])
if (!powerstatus && autoaction &&
autolimit > (int)pinfo.battery_life) {
+ struct timespec delay, now;
+
logmsg(LOG_NOTICE,
"estimated battery life %d%%"
" below configured limit %d%%",
@@ -584,10 +588,17 @@ main(int argc, char *argv[])
autolimit
);
- if (autoaction == AUTO_SUSPEND)
- suspends++;
- else
- hibernates++;
+ delay = autoaction_timestamp;
+ delay.tv_sec += 60;
+ clock_gettime(CLOCK_MONOTONIC, &now);
+ if (timespeccmp(&now, &delay, >)) {
+ if (autoaction == AUTO_SUSPEND)
+ suspends++;
+ else
+ hibernates++;
+ clock_gettime(CLOCK_MONOTONIC,
+ &autoaction_timestamp);
+ }
}
break;
default:
--
jca | PGP : 0x1524E7EE / 5135 92C1 AD36 5293 2BDF DDCC 0DFA 74AE 1524 E7EE