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, "