> I seem to have the same issue with your patch as I do with my own
> though.  When I run apmd with "-A -t 10 -z 10", it suspends again after
> immediate resume.  Like Mark suggested, maybe it's better to register
> another kevent?

The problem with the system suspending immediately upon resume appears to
be caused by the timeout having expired while the machine was suspended and
the autoaction being triggered before apmd has handled the APM_*_RESUME
events? (see lines 552-578) I've had some luck working around this.

Please forgive the somewhat unusual diff. I'm not an OpenBSD developer and
this machine isn't really set up for development; I'm working from the 6.2
amd64 src. Hopefully you can see what's going on.

The diff also uses an EVFILT_TIMER kevent. The "ignoreautoaction" bits
should work without the EVFILT_TIMER changes.

Take it with a grain of salt, but it works for me (obviously it needs more
testing ;-))

All the best,

Mark

--- apmd.c~ Mon Aug 28 18:16:58 2017
+++ apmd.c Wed Oct 25 00:18:52 2017
@@ -353,6 +353,7 @@ main(int argc, char *argv[])
  int ctl_fd, sock_fd, ch, suspends, standbys, hibernates, resumes;
  int autoaction = 0;
  int autolimit = 0;
+ int ignoreautoaction = 0;
  int statonly = 0;
  int powerstatus = 0, powerbak = 0, powerchange = 0;
  int noacsleep = 0;
@@ -362,7 +363,7 @@ main(int argc, char *argv[])
  const char *sockname = sockfile;
  const char *errstr;
  int kq, nchanges;
- struct kevent ev[2];
+ struct kevent ev[3];
  int ncpu_mib[2] = { CTL_HW, HW_NCPU };
  int ncpu;
  size_t ncpu_sz = sizeof(ncpu);
@@ -467,16 +468,19 @@ main(int argc, char *argv[])
  if (kq <= 0)
  error("kqueue", NULL);

- EV_SET(&ev[0], sock_fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR,
+ nchanges = 0;
+ EV_SET(&ev[nchanges], sock_fd, EVFILT_READ, EV_ADD | EV_CLEAR,
      0, 0, NULL);
- if (ctl_fd == -1)
- nchanges = 1;
- else {
- EV_SET(&ev[1], ctl_fd, EVFILT_READ, EV_ADD | EV_ENABLE |
-     EV_CLEAR, 0, 0, NULL);
- nchanges = 2;
+ nchanges += 1;
+ if (ctl_fd != -1) {
+ EV_SET(&ev[nchanges], ctl_fd, EVFILT_READ, EV_ADD |
+     EV_ENABLE | EV_CLEAR, 0, 0, NULL);
+ nchanges += 1;
  }
- if (kevent(kq, ev, nchanges, NULL, 0, &sts) < 0)
+ EV_SET(&ev[nchanges], 1, EVFILT_TIMER, EV_ADD |
+     EV_ENABLE | EV_CLEAR, 0, ts.tv_sec * 1000, NULL);
+ nchanges += 1;
+ if (kevent(kq, ev, nchanges, NULL, 0, NULL) < 0)
  error("kevent", NULL);

  if (sysctl(ncpu_mib, 2, &ncpu, &ncpu_sz, NULL, 0) < 0)
@@ -485,15 +489,10 @@ main(int argc, char *argv[])
  for (;;) {
  int rv;

- sts = ts;
-
- apmtimeout += 1;
- if ((rv = kevent(kq, NULL, 0, ev, 1, &sts)) < 0)
+ if ((rv = kevent(kq, NULL, 0, ev, 1, NULL)) < 0)
  break;

- if (apmtimeout >= ts.tv_sec) {
- apmtimeout = 0;
-
+ if (ev->filter == EVFILT_TIMER) {
  /* wakeup for timeout: take status */
  powerbak = power_status(ctl_fd, 0, &pinfo);
  if (powerstatus != powerbak) {
@@ -501,7 +500,8 @@ main(int argc, char *argv[])
  powerchange = 1;
  }

- if (!powerstatus && autoaction &&
+ if (!ignoreautoaction &&
+     !powerstatus && autoaction &&
      autolimit > (int)pinfo.battery_life) {
  syslog(LOG_NOTICE,
      "estimated battery life %d%%, "
@@ -510,11 +510,15 @@ main(int argc, char *argv[])
      autolimit
  );

+ ignoreautoaction = 1;
+
  if (autoaction == AUTO_SUSPEND)
  suspend(ctl_fd);
  else
  hibernate(ctl_fd);
  }
+
+ continue;
  }

  if (!rv)
@@ -576,6 +580,7 @@ main(int argc, char *argv[])
  else if (hibernates)
  hibernate(ctl_fd);
  else if (resumes) {
+ ignoreautoaction = 0;
  do_etc_file(_PATH_APM_ETC_RESUME);
  syslog(LOG_NOTICE,
      "system resumed from sleep");


On Mon, 23 Oct 2017 at 13:02 Jesper Wallin <[email protected]> wrote:

> On Mon, Oct 23, 2017 at 10:42:37AM +0200, Anton Lindqvist wrote:
> > How about using the monotonic clock instead. I don't use the feature
> > myself but tested once with the default poll interval. It did suspend
> > and upon immediate resume, it took approximately another poll interval
> > (10 minutes) before a second suspend was triggered.
> >
>
> I seem to have the same issue with your patch as I do with my own
> though.  When I run apmd with "-A -t 10 -z 10", it suspends again after
> immediate resume.  Like Mark suggested, maybe it's better to register
> another kevent?
>

Reply via email to