[powerd] Adding different adaptive-mode settings for each power source

gelraen gelraen.ua at gmail.com
Tue Sep 30 22:37:33 UTC 2008


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


More information about the freebsd-hackers mailing list