On Wed, Feb 12 2020, Jeremie Courreges-Anglas <j...@wxcvbn.org> wrote: > On Sat, Jan 25 2020, Jeremie Courreges-Anglas <j...@wxcvbn.org> 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