Hello,

At present, there is no middle between cool running and automatic adjustement 
mode.
I would suggest to add an "on demand" adjustement mode which set hw.setperf to
maximum when CPU idle is lesser then 10% and reduce it when CPU idle is greater 
than
30%. Also, when hw.setperf is at maximum, verification of CPU idle is slow down.

This is based on a previous suggestion of Laurence Tratt.

PS : please add me to recepient if you reply.

Index: apm-proto.h
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apm-proto.h,v
retrieving revision 1.9
diff -u -p -r1.9 apm-proto.h
--- apm-proto.h 26 Mar 2012 20:17:45 -0000      1.9
+++ apm-proto.h 2 Mar 2015 14:56:34 -0000
@@ -38,6 +38,7 @@ enum apm_action {
        SETPERF_LOW,
        SETPERF_HIGH,
        SETPERF_AUTO,
+       SETPERF_ONDEMAND,
        SETPERF_COOL
 };
 
@@ -52,6 +53,7 @@ enum apm_perfmode {
        PERF_NONE = -1,
        PERF_MANUAL,
        PERF_AUTO,
+       PERF_ONDEMAND,
        PERF_COOL
 };
 
Index: apmd.8
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apmd.8,v
retrieving revision 1.44
diff -u -p -r1.44 apmd.8
--- apmd.8      24 Jul 2014 01:04:58 -0000      1.44
+++ apmd.8      2 Mar 2015 14:56:34 -0000
@@ -77,6 +77,16 @@ level is low.
 BIOS-initiated suspend or standby requests are
 ignored if the system is connected to line current and not running from
 batteries (user requests are still honored).
+.It Fl O
+Start
+.Nm
+in on demand performance adjustement mode.
+Set
+.Va hw.setperf
+to maximum when CPU idle is lesser than 90%, reduce it if CPU idle is
+greater than 30%. When
+.Va hw.setperf
+is at maximum, verification of CPU idle is ten times slower.
 .It Fl C
 Start
 .Nm

Index: apmd.c
===================================================================
RCS file: /cvs/src/usr.sbin/apmd/apmd.c,v
retrieving revision 1.65
diff -u -p -r1.65 apmd.c
--- apmd.c      26 Jul 2014 10:48:59 -0000      1.65
+++ apmd.c      2 Mar 2015 14:56:34 -0000
@@ -76,7 +76,7 @@ int bind_socket(const char *sn);
 enum apm_state handle_client(int sock_fd, int ctl_fd);
 int  get_avg_idle_mp(int ncpu);
 int  get_avg_idle_up(void);
-void perf_status(struct apm_power_info *pinfo, int ncpu);
+long perf_status(struct apm_power_info *pinfo, int ncpu);
 void suspend(int ctl_fd);
 void stand_by(int ctl_fd);
 void hibernate(int ctl_fd);
@@ -301,13 +301,14 @@ get_avg_idle_up(void)
        return avg_idle;
 }
 
-void
+long
 perf_status(struct apm_power_info *pinfo, int ncpu)
 {
        int avg_idle;
        int hw_perf_mib[] = {CTL_HW, HW_SETPERF};
        int perf;
        int forcehi = 0;
+       long timeout = 1;
        size_t perf_sz = sizeof(perf);
 
        if (ncpu > 1) {
@@ -330,6 +331,7 @@ perf_status(struct apm_power_info *pinfo
                    pinfo->battery_state == APM_BATTERY_ABSENT)
                        forcehi = 1;            
                break;
+       case PERF_ONDEMAND:
        case PERF_COOL:
                forcehi = 0;
                break;
@@ -339,9 +341,13 @@ perf_status(struct apm_power_info *pinfo
                syslog(LOG_INFO, "cannot read hw.setperf");
 
        if (forcehi || (avg_idle < PERFINCTHRES && perf < PERFMAX)) {
-               perf += PERFINC;
-               if (perf > PERFMAX)
+               if (doperf == PERF_ONDEMAND) {
                        perf = PERFMAX;
+               } else {
+                       perf += PERFINC;
+                       if (perf > PERFMAX)
+                               perf = PERFMAX;
+               }
                setperf(perf);
        } else if (avg_idle > PERFDECTHRES && perf > PERFMIN) {
                perf -= PERFDEC;
@@ -349,6 +355,13 @@ perf_status(struct apm_power_info *pinfo
                        perf = PERFMIN;
                setperf(perf);
        }
+       if (doperf == PERF_ONDEMAND) {
+               if (perf == PERFMAX)
+                       timeout = 999999999;
+               else
+                       timeout = 100000000;
+       }
+       return timeout;
 }
 
 char socketname[MAXPATHLEN];
@@ -452,6 +465,11 @@ handle_client(int sock_fd, int ctl_fd)
                reply.newstate = NORMAL;
                syslog(LOG_NOTICE, "setting hw.setperf automatically");
                break;
+       case SETPERF_ONDEMAND:
+               doperf = PERF_ONDEMAND;
+               reply.newstate = NORMAL;
+               syslog(LOG_NOTICE, "setting hw.setperf on demand");
+               break;
        case SETPERF_COOL:
                doperf = PERF_COOL;
                reply.newstate = NORMAL;
@@ -525,7 +543,7 @@ main(int argc, char *argv[])
        int ncpu;
        size_t ncpu_sz = sizeof(ncpu);
 
-       while ((ch = getopt(argc, argv, "aACdHLsf:t:S:")) != -1)
+       while ((ch = getopt(argc, argv, "aAOCdHLsf:t:S:")) != -1)
                switch(ch) {
                case 'a':
                        noacsleep = 1;
@@ -552,6 +570,11 @@ main(int argc, char *argv[])
                                usage();
                        doperf = PERF_AUTO;
                        break;
+               case 'O':
+                       if (doperf != PERF_NONE)
+                               usage();
+                       doperf = PERF_ONDEMAND;
+                       break;
                case 'C':
                        if (doperf != PERF_NONE)
                                usage();
@@ -633,7 +656,8 @@ main(int argc, char *argv[])
        if (sysctl(ncpu_mib, 2, &ncpu, &ncpu_sz, NULL, 0) < 0)
                error("cannot read hw.ncpu", NULL);
 
-       if (doperf == PERF_AUTO || doperf == PERF_COOL) {
+       if (doperf == PERF_AUTO || doperf == PERF_COOL ||
+           doperf == PERF_ONDEMAND) {
                setperf(0);
                setperf(100);
        }
@@ -642,12 +666,16 @@ main(int argc, char *argv[])
 
                sts = ts;
 
-               if (doperf == PERF_AUTO || doperf == PERF_COOL) {
-                       sts.tv_sec = 1;
-                       perf_status(&pinfo, ncpu);
-               }
+               if (doperf == PERF_ONDEMAND) {
+                       sts.tv_sec = 0;
+                       sts.tv_nsec = perf_status(&pinfo, ncpu);
+                       apmtimeout += 1;
+               } else if (doperf == PERF_AUTO || doperf == PERF_COOL) {
+                       sts.tv_sec = perf_status(&pinfo, ncpu);
+                       apmtimeout += sts.tv_sec;
+               } else
+                       apmtimeout += sts.tv_sec;
 
-               apmtimeout += sts.tv_sec;
                if ((rv = kevent(kq, NULL, 0, ev, 1, &sts)) < 0)
                        break;

Index: apm.8
===================================================================
RCS file: /cvs/src/usr.sbin/apm/apm.8,v
retrieving revision 1.39
diff -u -p -r1.39 apm.8
--- apm.8       21 Jan 2014 03:15:46 -0000      1.39
+++ apm.8       2 Mar 2015 14:57:28 -0000
@@ -80,6 +80,16 @@ means connected, 2 means backup power so
 Display the battery status.
 0 means high, 1 means low, 2 means
 critical, 3 means charging, 4 means absent, and 255 means unknown.
+.It Fl O
+Set
+.Xr apmd 8
+to on demand performance adjustement mode.
+In this mode,
+.Va hw.setperf
+is set to maximum when CPU idle is lesser than 90% and is reduce 
+if CPU idle is greater than 30%. When
+.Va hw.setperf
+is at maximum, verification of CPU idle is ten times slower.
 .It Fl C
 Set
 .Xr apmd 8

Index: apm.c
===================================================================
RCS file: /cvs/src/usr.sbin/apm/apm.c,v
retrieving revision 1.27
diff -u -p -r1.27 apm.c
--- apm.c       11 Jul 2012 13:27:13 -0000      1.27
+++ apm.c       2 Mar 2015 14:57:28 -0000
@@ -158,7 +158,7 @@ main(int argc, char *argv[])
        int cpuspeed_mib[] = { CTL_HW, HW_CPUSPEED }, cpuspeed;
        size_t cpuspeed_sz = sizeof(cpuspeed);
 
-       while ((ch = getopt(argc, argv, "ACHLlmbvaPSzZf:")) != -1) {
+       while ((ch = getopt(argc, argv, "AOCHLlmbvaPSzZf:")) != -1) {
                switch (ch) {
                case 'v':
                        verbose = TRUE;
@@ -186,6 +186,11 @@ main(int argc, char *argv[])
                                usage();
                        action = SETPERF_AUTO;
                        break;
+               case 'O':
+                       if (action != NONE)
+                               usage();
+                       action = SETPERF_ONDEMAND;
+                       break;
                case 'C':
                        if (action != NONE)
                                usage();
@@ -267,6 +272,7 @@ main(int argc, char *argv[])
        case SETPERF_LOW:
        case SETPERF_HIGH:
        case SETPERF_AUTO:
+       case SETPERF_ONDEMAND:
        case SETPERF_COOL:
                if (fd == -1)
                        errx(1, "cannot connect to apmd, "


Reply via email to