diff options
author | Ted Unangst <tedu@cvs.openbsd.org> | 2009-02-26 00:29:40 +0000 |
---|---|---|
committer | Ted Unangst <tedu@cvs.openbsd.org> | 2009-02-26 00:29:40 +0000 |
commit | fd52a3376654d450037c34c8af858ce75ab7ad9d (patch) | |
tree | dbd5c5111aae82dd0db5a3cd22a6946d5ba4a1c8 | |
parent | aa1d4eafd7065fbaf07c64c3ccd116f157bf7541 (diff) |
revert 1.50 and 1.51. kettenis discovered they don't let his sparcle go slow enough
-rw-r--r-- | usr.sbin/apmd/apmd.c | 138 |
1 files changed, 95 insertions, 43 deletions
diff --git a/usr.sbin/apmd/apmd.c b/usr.sbin/apmd/apmd.c index dd4608704f6..11a3b67b8ca 100644 --- a/usr.sbin/apmd/apmd.c +++ b/usr.sbin/apmd/apmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apmd.c,v 1.51 2009/02/04 05:22:58 tedu Exp $ */ +/* $OpenBSD: apmd.c,v 1.52 2009/02/26 00:29:39 tedu Exp $ */ /* * Copyright (c) 1995, 1996 John T. Kohl @@ -61,15 +61,12 @@ const char sockfile[] = _PATH_APM_SOCKET; int debug = 0; int doperf = PERF_NONE; -#define PERFINC 15 -#define PERFDEC 15 +#define PERFINC 50 +#define PERFDEC 20 #define PERFMIN 0 #define PERFMAX 100 #define PERFINCTHRES 10 #define PERFDECTHRES 30 -#define PERFTIMEOUTERR 999999999 -#define PERFTIMEOUTFAST 10000000 -#define PERFTIMEOUTSLOW 25000000 extern char *__progname; @@ -77,8 +74,9 @@ void usage(void); int power_status(int fd, int force, struct apm_power_info *pinfo); int bind_socket(const char *sn); enum apm_state handle_client(int sock_fd, int ctl_fd); -int get_min_idle_mp(int ncpu); -useconds_t perf_status(struct apm_power_info *pinfo, int ncpu); +int get_avg_idle_mp(int ncpu); +int get_avg_idle_up(void); +void perf_status(struct apm_power_info *pinfo, int ncpu); void suspend(int ctl_fd); void stand_by(int ctl_fd); void setperf(int new_perf); @@ -197,12 +195,13 @@ power_status(int fd, int force, struct apm_power_info *pinfo) /* multi- and uni-processor case */ int -get_min_idle_mp(int ncpu) +get_avg_idle_mp(int ncpu) { static int64_t **cp_time_old; static int64_t **cp_time; + static int *avg_idle; int64_t change, sum, idle; - int i, cpu, min_idle; + int i, cpu, min_avg_idle; size_t cp_time_sz = CPUSTATES * sizeof(int64_t); if (!cp_time_old) @@ -213,7 +212,11 @@ get_min_idle_mp(int ncpu) if ((cp_time = calloc(sizeof(int64_t *), ncpu)) == NULL) return -1; - min_idle = 100; + if (!avg_idle) + if ((avg_idle = calloc(sizeof(int), ncpu)) == NULL) + return -1; + + min_avg_idle = 0; for (cpu = 0; cpu < ncpu; cpu++) { int cp_time_mib[] = {CTL_KERN, KERN_CPTIME2, cpu}; @@ -227,14 +230,14 @@ get_min_idle_mp(int ncpu) calloc(sizeof(int64_t), CPUSTATES)) == NULL) return -1; - if (sysctl(cp_time_mib, 3, cp_time[cpu], &cp_time_sz, NULL, 0)) + if (sysctl(cp_time_mib, 3, cp_time[cpu], &cp_time_sz, NULL, 0) + < 0) syslog(LOG_INFO, "cannot read kern.cp_time2"); sum = 0; - idle = 100; for (i = 0; i < CPUSTATES; i++) { - change = cp_time[cpu][i] - cp_time_old[cpu][i]; - if (change < 0) { + if ((change = cp_time[cpu][i] - cp_time_old[cpu][i]) + < 0) { /* counter wrapped */ change = ((uint64_t)cp_time[cpu][i] - (uint64_t)cp_time_old[cpu][i]); @@ -246,52 +249,101 @@ get_min_idle_mp(int ncpu) if (sum == 0) sum = 1; - if ((100 * idle) / sum < min_idle) - min_idle = (100 * idle) / sum; + /* smooth data */ + avg_idle[cpu] = (avg_idle[cpu] + (100 * idle) / sum) / 2; + + if (cpu == 0) + min_avg_idle = avg_idle[cpu]; + + if (avg_idle[cpu] < min_avg_idle) + min_avg_idle = avg_idle[cpu]; memcpy(cp_time_old[cpu], cp_time[cpu], cp_time_sz); } - return min_idle; + return min_avg_idle; +} + +int +get_avg_idle_up(void) +{ + static long cp_time_old[CPUSTATES]; + static int avg_idle; + long change, cp_time[CPUSTATES]; + int cp_time_mib[] = {CTL_KERN, KERN_CPTIME}; + size_t cp_time_sz = sizeof(cp_time); + int i, idle, sum = 0; + + if (sysctl(cp_time_mib, 2, &cp_time, &cp_time_sz, NULL, 0) < 0) + syslog(LOG_INFO, "cannot read kern.cp_time"); + + for (i = 0; i < CPUSTATES; i++) { + if ((change = cp_time[i] - cp_time_old[i]) < 0) { + /* counter wrapped */ + change = ((unsigned long)cp_time[i] - + (unsigned long)cp_time_old[i]); + } + sum += change; + if (i == CP_IDLE) + idle = change; + } + if (sum == 0) + sum = 1; + + /* smooth data */ + avg_idle = (avg_idle + (100 * idle) / sum) / 2; + + memcpy(cp_time_old, cp_time, sizeof(cp_time_old)); + + return avg_idle; } -useconds_t +void perf_status(struct apm_power_info *pinfo, int ncpu) { - int avg_idle, min_idle; + int avg_idle; int hw_perf_mib[] = {CTL_HW, HW_SETPERF}; int perf; int forcehi = 0; size_t perf_sz = sizeof(perf); - if (avg_idle == -1) - return PERFTIMEOUTERR; + if (ncpu > 1) { + avg_idle = get_avg_idle_mp(ncpu); + } else { + avg_idle = get_avg_idle_up(); + } - if (sysctl(hw_perf_mib, 2, &perf, &perf_sz, NULL, 0) < 0) - syslog(LOG_INFO, "cannot read hw.setperf"); + if (avg_idle == -1) + return; switch (doperf) { case PERF_AUTO: + /* + * force setperf towards the max if we are connected to AC + * power and have a battery life greater than 15% + */ if (pinfo->ac_state == APM_AC_ON && pinfo->battery_life > 15) - forcehi = 1; + forcehi = 1; + break; case PERF_COOL: - min_idle = get_min_idle_mp(ncpu); - if (forcehi || (min_idle < PERFINCTHRES && perf < PERFMAX)) { - perf += PERFINC; - if (perf > PERFMAX) - perf = PERFMAX; - setperf(perf); - return PERFTIMEOUTFAST; - } else if (min_idle > PERFDECTHRES && perf > PERFMIN) { - perf -= PERFDEC; - if (perf < PERFMIN) - perf = PERFMIN; - setperf(perf); - return PERFTIMEOUTSLOW; - } else - return PERFTIMEOUTSLOW; + forcehi = 0; + break; + } + + if (sysctl(hw_perf_mib, 2, &perf, &perf_sz, NULL, 0) < 0) + syslog(LOG_INFO, "cannot read hw.setperf"); + + if (forcehi || (avg_idle < PERFINCTHRES && perf < PERFMAX)) { + perf += PERFINC; + if (perf > PERFMAX) + perf = PERFMAX; + setperf(perf); + } else if (avg_idle > PERFDECTHRES && perf > PERFMIN) { + perf -= PERFDEC; + if (perf < PERFMIN) + perf = PERFMIN; + setperf(perf); } - return PERFTIMEOUTSLOW; } char socketname[MAXPATHLEN]; @@ -593,8 +645,8 @@ main(int argc, char *argv[]) sts = ts; if (doperf == PERF_AUTO || doperf == PERF_COOL) { - sts.tv_sec = 0; - sts.tv_nsec = perf_status(&pinfo, ncpu); + sts.tv_sec = 1; + perf_status(&pinfo, ncpu); } apmtimeout += sts.tv_sec; |