Index: powerd.c =================================================================== RCS file: /home/ncvs/src/usr.sbin/powerd/powerd.c,v retrieving revision 1.20 diff -u -p -r1.20 powerd.c --- powerd.c 19 Feb 2006 00:40:28 -0000 1.20 +++ powerd.c 3 May 2006 20:36:21 -0000 @@ -50,8 +50,8 @@ __FBSDID("$FreeBSD: src/usr.sbin/powerd/ #include #endif -#define DEFAULT_ACTIVE_PERCENT 65 -#define DEFAULT_IDLE_PERCENT 90 +#define DEFAULT_ACTIVE_PERCENT 50 +#define DEFAULT_IDLE_PERCENT 70 #define DEFAULT_POLL_INTERVAL 500 /* Poll interval in milliseconds */ typedef enum { @@ -369,8 +369,8 @@ main(int argc, char * argv[]) int nfds; struct pidfh *pfh = NULL; const char *pidfile = NULL; - long idle, total; - int curfreq, *freqs, i, *mwatts, numfreqs; + long excess, idle, next_excess, old_excess, total; + int curfreq, freq, *freqs, i, *mwatts, numfreqs; int ch, mode, mode_ac, mode_battery, mode_none; uint64_t mjoules_used; size_t len; @@ -484,6 +484,8 @@ main(int argc, char * argv[]) signal(SIGTERM, handle_sigs); /* Main loop. */ + old_excess = 0; + for (;;) { FD_ZERO(&fdset); if (devd_pipe >= 0) { @@ -585,38 +587,67 @@ main(int argc, char * argv[]) } /* - * If we're idle less than the active mark, bump up two levels. - * If we're idle more than the idle mark, drop down one level. + * XXX describe PAST. */ for (i = 0; i < numfreqs - 1; i++) { if (freqs[i] == curfreq) break; } - if (idle < (total * cpu_running_mark) / 100 && - curfreq < freqs[0]) { - i -= 2; - if (i < 0) - i = 0; - if (vflag) { - printf("idle time < %d%%, increasing clock" - " speed from %d MHz to %d MHz\n", - cpu_running_mark, curfreq, freqs[i]); - } - if (set_freq(freqs[i])) - err(1, "error setting CPU frequency %d", - freqs[i]); - } else if (idle > (total * cpu_idle_mark) / 100 && - curfreq > freqs[numfreqs - 1]) { - i++; - if (vflag) { - printf("idle time > %d%%, decreasing clock" - " speed from %d MHz to %d MHz\n", - cpu_idle_mark, curfreq, freqs[i]); - } - if (set_freq(freqs[i]) != 0) - warn("error setting CPU frequency %d", - freqs[i]); + next_excess = (total - idle) - (total * curfreq) / freqs[0]; + excess = old_excess; + old_excess = next_excess; + + if (excess < 0) + excess = 0; + total += excess; + + if (curfreq < freqs[0]) { + if (excess > idle) { + if (vflag) + printf("excess > idle, setting to max frequency %d\n", freqs[0]); + if (set_freq(freqs[0]) != 0) { + warn("error setting CPU freq %d", + freqs[0]); + } + continue; + } + if (idle < (total * cpu_running_mark) / 100) { + freq = curfreq - + ((cpu_running_mark - cpu_idle_mark) * + freqs[0]) / 100; + for (i = 0; i < numfreqs; i++) { + if (freqs[i] <= freq) + break; + } + if (freq == freqs[i]) + i--; + if (i == 0) + i = 1; + if (vflag) + printf("idle < threshold, increasing clock speed %d\n", freqs[i]); + if (set_freq(freqs[i])) + warn("error setting CPU frequency %d", + freqs[i]); + continue; + } + } + + if (curfreq <= freqs[numfreqs - 1]) + continue; + + if (idle > (total * cpu_idle_mark) / 100) { + freq = curfreq - (((cpu_running_mark + cpu_idle_mark)/2 - (100 * (total - idle) / total)) * freqs[0]) / 100; + for (i = 0; i < numfreqs; i++) { + if (freqs[i] <= freq) + break; + } + if (vflag) + printf("idle > threshold, decreasing clock speed from %d to %d (actually %d)\n", curfreq, freq, freqs[i - 1]); + if (set_freq(freqs[i - 1]) != 0) + warn("error setting CPU freq %d", + freqs[i - 1]); } + } free(freqs); free(mwatts);