Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 1 Oct 2008 01:13:31 +0300
From:      gelraen <gelraen.ua@gmail.com>
To:        freebsd-hackers@freebsd.org
Subject:   [powerd] Adding different adaptive-mode settings for each power source
Message-ID:  <ac42db050809301513j346a9f7bi8b49300418c5c2cb@mail.gmail.com>

next in thread | raw e-mail | index | archive | help
Hi,

I've needed to set different idle levels for adaptive mode while on
battery or on AC power. Cause powerd can only set mode (min, max, adp)
for each power source, I've added this ability and it seems to be a
good idea to share this improvement with others.

Best regards, gelraen.

P.S.: Sorry for my bad English :)



--- usr.sbin/powerd/powerd.c.orig	2008-09-30 18:19:04.000000000 +0300
+++ usr.sbin/powerd/powerd.c	2008-10-01 00:49:52.000000000 +0300
@@ -66,6 +66,8 @@
 	SRC_UNKNOWN,
 } power_src_t;

+#define SRCS_COUNT 3 /* Number of different power sources */
+
 const char *modes[] = {
 	"AC",
 	"battery",
@@ -95,8 +97,8 @@
 static int	acline_mib[3];

 /* Configuration */
-static int	cpu_running_mark;
-static int	cpu_idle_mark;
+static int	cpu_running_mark[SRCS_COUNT];
+static int	cpu_idle_mark[SRCS_COUNT];
 static int	poll_ival;
 static int	vflag;

@@ -357,7 +359,7 @@
 {

 	fprintf(stderr,
-"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival]
[-r %%] [-P pidfile]\n");
+"usage: powerd [-v] [-a mode] [-b mode] [-A %%:%%] [-B %%:%%] [-i %%]
[-n mode] [-N %%:%%] [-p ival] [-r %%] [-P pidfile]\n");
 	exit(1);
 }

@@ -377,8 +379,11 @@

 	/* Default mode for all AC states is adaptive. */
 	mode_ac = mode_battery = mode_none = MODE_ADAPTIVE;
-	cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
-	cpu_idle_mark = DEFAULT_IDLE_PERCENT;
+	for(i=0;i<SRCS_COUNT;i++)
+	{
+		cpu_running_mark[i] = DEFAULT_ACTIVE_PERCENT;
+		cpu_idle_mark[i] = DEFAULT_IDLE_PERCENT;
+	}
 	poll_ival = DEFAULT_POLL_INTERVAL;
 	mjoules_used = 0;
 	vflag = 0;
@@ -387,7 +392,7 @@
 	if (geteuid() != 0)
 		errx(1, "must be root to run");

-	while ((ch = getopt(argc, argv, "a:b:i:n:p:P:r:v")) != -1)
+	while ((ch = getopt(argc, argv, "A:B:N:a:b:i:n:p:P:r:v")) != -1)
 		switch (ch) {
 		case 'a':
 			parse_mode(optarg, &mode_ac, ch);
@@ -395,13 +400,87 @@
 		case 'b':
 			parse_mode(optarg, &mode_battery, ch);
 			break;
+		case 'A':
+			i=0;
+			while (optarg[i]!='\0' && optarg[i]!=':') i++;
+			if (optarg[i]!=':')
+			{
+				warnx("%s is not a valid setting",optarg);
+				usage();
+			}
+			optarg[i]='\0';
+			cpu_running_mark[SRC_AC] = atoi(optarg);
+			optarg[i]=':';
+			if (cpu_running_mark[SRC_AC] < 0 || cpu_running_mark[SRC_AC] > 100) {
+				warnx("%d is not a valid percent",
+				    cpu_running_mark[SRC_AC]);
+				usage();
+			}
+			cpu_idle_mark[SRC_AC] = atoi(optarg+i+1);
+			if (cpu_idle_mark[SRC_AC] < 0 || cpu_idle_mark[SRC_AC] > 100) {
+				warnx("%d is not a valid percent",
+				    cpu_idle_mark[SRC_AC]);
+				usage();
+			}
+			break;
+		case 'B':
+			i=0;
+			while (optarg[i]!='\0' && optarg[i]!=':') i++;
+			if (optarg[i]!=':')
+			{
+				warnx("%s is not a valid setting",optarg);
+				usage();
+			}
+			optarg[i]='\0';
+			cpu_running_mark[SRC_BATTERY] = atoi(optarg);
+			optarg[i]=':';
+			if (cpu_running_mark[SRC_BATTERY] < 0 ||
cpu_running_mark[SRC_BATTERY] > 100) {
+				warnx("%d is not a valid percent",
+				    cpu_running_mark[SRC_BATTERY]);
+				usage();
+			}
+			cpu_idle_mark[SRC_BATTERY] = atoi(optarg+i+1);
+			if (cpu_idle_mark[SRC_BATTERY] < 0 || cpu_idle_mark[SRC_BATTERY] > 100) {
+				warnx("%d is not a valid percent",
+				    cpu_idle_mark[SRC_BATTERY]);
+				usage();
+			}
+			break;
+		case 'N':
+			i=0;
+			while (optarg[i]!='\0' && optarg[i]!=':') i++;
+			if (optarg[i]!=':')
+			{
+				warnx("%s is not a valid setting",optarg);
+				usage();
+			}
+			optarg[i]='\0';
+			cpu_running_mark[SRC_UNKNOWN] = atoi(optarg);
+			optarg[i]=':';
+			if (cpu_running_mark[SRC_UNKNOWN] < 0 ||
cpu_running_mark[SRC_UNKNOWN] > 100) {
+				warnx("%d is not a valid percent",
+				    cpu_running_mark[SRC_UNKNOWN]);
+				usage();
+			}
+			cpu_idle_mark[SRC_UNKNOWN] = atoi(optarg+i+1);
+			if (cpu_idle_mark[SRC_UNKNOWN] < 0 || cpu_idle_mark[SRC_UNKNOWN] > 100) {
+				warnx("%d is not a valid percent",
+				    cpu_idle_mark[SRC_UNKNOWN]);
+				usage();
+			}
+			break;
 		case 'i':
-			cpu_idle_mark = atoi(optarg);
-			if (cpu_idle_mark < 0 || cpu_idle_mark > 100) {
+			cpu_idle_mark[0] = atoi(optarg);
+			if (cpu_idle_mark[0] < 0 || cpu_idle_mark[0] > 100) {
 				warnx("%d is not a valid percent",
-				    cpu_idle_mark);
+				    cpu_idle_mark[0]);
 				usage();
 			}
+			else
+			{
+				for(i=1;i<SRCS_COUNT;i++)
+					cpu_idle_mark[i]=cpu_idle_mark[0];
+			}
 			break;
 		case 'n':
 			parse_mode(optarg, &mode_none, ch);
@@ -417,12 +496,17 @@
 			pidfile = optarg;
 			break;
 		case 'r':
-			cpu_running_mark = atoi(optarg);
-			if (cpu_running_mark < 0 || cpu_running_mark > 100) {
+			cpu_running_mark[0] = atoi(optarg);
+			if (cpu_running_mark[0] < 0 || cpu_running_mark[0] > 100) {
 				warnx("%d is not a valid percent",
-				    cpu_running_mark);
+				    cpu_running_mark[0]);
 				usage();
 			}
+			else
+			{
+				for(i=0;i<SRCS_COUNT;i++)
+					cpu_running_mark[i]=cpu_running_mark[0];
+			}
 			break;
 		case 'v':
 			vflag = 1;
@@ -592,7 +676,7 @@
 			if (freqs[i] == curfreq)
 				break;
 		}
-		if (idle < (total * cpu_running_mark) / 100 &&
+		if (idle < (total * cpu_running_mark[acline_status]) / 100 &&
 		    curfreq < freqs[0]) {
 			i -= 2;
 			if (i < 0)
@@ -600,18 +684,18 @@
 			if (vflag) {
 				printf("idle time < %d%%, increasing clock"
 				    " speed from %d MHz to %d MHz\n",
-				    cpu_running_mark, curfreq, freqs[i]);
+				    cpu_running_mark[acline_status], curfreq, freqs[i]);
 			}
 			if (set_freq(freqs[i]))
 				warn("error setting CPU frequency %d",
 				    freqs[i]);
-		} else if (idle > (total * cpu_idle_mark) / 100 &&
+		} else if (idle > (total * cpu_idle_mark[acline_status]) / 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]);
+				    cpu_idle_mark[acline_status], curfreq, freqs[i]);
 			}
 			if (set_freq(freqs[i]) != 0)
 				warn("error setting CPU frequency %d",
--- usr.sbin/powerd/powerd.8.orig	2008-09-30 21:33:01.000000000 +0300
+++ usr.sbin/powerd/powerd.8	2008-10-01 00:52:15.000000000 +0300
@@ -34,8 +34,11 @@
 .Nm
 .Op Fl a Ar mode
 .Op Fl b Ar mode
+.Op Fl A Ar percent:percent
+.Op Fl B Ar percent:percent
 .Op Fl i Ar percent
 .Op Fl n Ar mode
+.Op Fl N Ar percent:percent
 .Op Fl p Ar ival
 .Op Fl P Ar pidfile
 .Op Fl r Ar percent
@@ -93,6 +96,13 @@
 adaptive
 mode should consider the CPU running and increase performance.
 The default is 65% or lower.
+.It Fl A Ar percent:percent
+Specifies parameters for adaptive mode while on AC power.
+Default values in this notation will look as 65:90. Empty values treated as 0
+.It Fl B Ar percent:percent
+Specifies parameters for adaptive mode while on battery.
+.It Fl N Ar percent:percent
+Specifies parameters for adaptive mode when AC line state is unknown.
 .It Fl v
 Verbose mode.
 Messages about power changes will be printed to stdout and



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?ac42db050809301513j346a9f7bi8b49300418c5c2cb>