summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/apmd/apmd.c138
1 files changed, 43 insertions, 95 deletions
diff --git a/usr.sbin/apmd/apmd.c b/usr.sbin/apmd/apmd.c
index 58ad09e088f..0eedae27feb 100644
--- a/usr.sbin/apmd/apmd.c
+++ b/usr.sbin/apmd/apmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apmd.c,v 1.49 2007/11/24 14:58:44 deraadt Exp $ */
+/* $OpenBSD: apmd.c,v 1.50 2009/02/03 01:52:49 tedu Exp $ */
/*
* Copyright (c) 1995, 1996 John T. Kohl
@@ -61,12 +61,15 @@ const char sockfile[] = _PATH_APM_SOCKET;
int debug = 0;
int doperf = PERF_NONE;
-#define PERFINC 50
-#define PERFDEC 20
+#define PERFINC 15
+#define PERFDEC 15
#define PERFMIN 0
#define PERFMAX 100
#define PERFINCTHRES 10
#define PERFDECTHRES 30
+#define PERFTIMEOUTERR 999999999
+#define PERFTIMEOUTFAST 10000
+#define PERFTIMEOUTSLOW 25000
extern char *__progname;
@@ -74,9 +77,8 @@ 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_avg_idle_mp(int ncpu);
-int get_avg_idle_up(void);
-void perf_status(struct apm_power_info *pinfo, int ncpu);
+int get_min_idle_mp(int ncpu);
+useconds_t 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);
@@ -195,13 +197,12 @@ power_status(int fd, int force, struct apm_power_info *pinfo)
/* multi- and uni-processor case */
int
-get_avg_idle_mp(int ncpu)
+get_min_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_avg_idle;
+ int i, cpu, min_idle;
size_t cp_time_sz = CPUSTATES * sizeof(int64_t);
if (!cp_time_old)
@@ -212,11 +213,7 @@ get_avg_idle_mp(int ncpu)
if ((cp_time = calloc(sizeof(int64_t *), ncpu)) == NULL)
return -1;
- if (!avg_idle)
- if ((avg_idle = calloc(sizeof(int), ncpu)) == NULL)
- return -1;
-
- min_avg_idle = 0;
+ min_idle = 100;
for (cpu = 0; cpu < ncpu; cpu++) {
int cp_time_mib[] = {CTL_KERN, KERN_CPTIME2, cpu};
@@ -230,14 +227,14 @@ get_avg_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)
- < 0)
+ if (sysctl(cp_time_mib, 3, cp_time[cpu], &cp_time_sz, NULL, 0))
syslog(LOG_INFO, "cannot read kern.cp_time2");
sum = 0;
+ idle = 100;
for (i = 0; i < CPUSTATES; i++) {
- if ((change = cp_time[cpu][i] - cp_time_old[cpu][i])
- < 0) {
+ change = cp_time[cpu][i] - cp_time_old[cpu][i];
+ if (change < 0) {
/* counter wrapped */
change = ((uint64_t)cp_time[cpu][i] -
(uint64_t)cp_time_old[cpu][i]);
@@ -249,101 +246,52 @@ get_avg_idle_mp(int ncpu)
if (sum == 0)
sum = 1;
- /* 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];
+ if ((100 * idle) / sum < min_idle)
+ min_idle = (100 * idle) / sum;
memcpy(cp_time_old[cpu], cp_time[cpu], cp_time_sz);
}
- 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;
+ return min_idle;
}
-void
+useconds_t
perf_status(struct apm_power_info *pinfo, int ncpu)
{
- int avg_idle;
+ int avg_idle, min_idle;
int hw_perf_mib[] = {CTL_HW, HW_SETPERF};
int perf;
int forcehi = 0;
size_t perf_sz = sizeof(perf);
- if (ncpu > 1) {
- avg_idle = get_avg_idle_mp(ncpu);
- } else {
- avg_idle = get_avg_idle_up();
- }
-
if (avg_idle == -1)
- return;
+ return PERFTIMEOUTERR;
+
+ if (sysctl(hw_perf_mib, 2, &perf, &perf_sz, NULL, 0) < 0)
+ syslog(LOG_INFO, "cannot read hw.setperf");
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;
- break;
+ forcehi = 1;
case PERF_COOL:
- 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);
+ 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;
}
+ return PERFTIMEOUTSLOW;
}
char socketname[MAXPATHLEN];
@@ -645,8 +593,8 @@ main(int argc, char *argv[])
sts = ts;
if (doperf == PERF_AUTO || doperf == PERF_COOL) {
- sts.tv_sec = 1;
- perf_status(&pinfo, ncpu);
+ sts.tv_sec = 0;
+ sts.tv_nsec = perf_status(&pinfo, ncpu);
}
apmtimeout += sts.tv_sec;