--- ./usr.sbin/powerd/powerd.c Sun Apr 17 11:25:41 2005 +++ /home/sunny/powerd.c Sun Apr 24 20:46:40 2005 @@ -46,7 +46,8 @@ #define DEFAULT_ACTIVE_PERCENT 65 #define DEFAULT_IDLE_PERCENT 90 -#define DEFAULT_POLL_INTERVAL 500 /* Poll interval in milliseconds */ +#define DEFAULT_POLL_INTERVAL 500 /* Poll interval in milliseconds */ +#define VERY_HIGH_TEMPERATURE 200 enum modes_t { MODE_MIN, @@ -83,11 +84,13 @@ static int freq_mib[4]; static int levels_mib[4]; static int acline_mib[3]; +static int temp_mib[5]; /* Configuration */ static int cpu_running_mark; static int cpu_idle_mark; static int poll_ival; +static int passive_cooling_mark; static int apm_fd; static int exit_requested; @@ -244,7 +247,7 @@ { fprintf(stderr, -"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%]\n"); +"usage: powerd [-v] [-a mode] [-b mode] [-i %%] [-n mode] [-p ival] [-r %%] [-t temperature]\n"); exit(1); } @@ -252,7 +255,7 @@ main(int argc, char * argv[]) { long idle, total; - int curfreq, *freqs, i, *mwatts, numfreqs; + int curfreq, *freqs, i, *mwatts, numfreqs, temperature; int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag; uint64_t mjoules_used; size_t len; @@ -263,10 +266,11 @@ cpu_idle_mark = DEFAULT_IDLE_PERCENT; poll_ival = DEFAULT_POLL_INTERVAL; mjoules_used = 0; + passive_cooling_mark = VERY_HIGH_TEMPERATURE; vflag = 0; apm_fd = -1; - while ((ch = getopt(argc, argv, "a:b:i:n:p:r:v")) != EOF) + while ((ch = getopt(argc, argv, "a:b:i:n:p:r:t:v")) != EOF) switch (ch) { case 'a': parse_mode(optarg, &mode_ac, ch); @@ -300,6 +304,16 @@ usage(); } break; + case 't': + passive_cooling_mark = atoi(optarg); + if(passive_cooling_mark < 0 || passive_cooling_mark > 100) { + warnx("%d is not valid temperature for passive cooling", + passive_cooling_mark); + usage(); + } + passive_cooling_mark *= 10; + passive_cooling_mark += 2733; + break; case 'v': vflag = 1; break; @@ -320,6 +334,9 @@ len = 4; if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len)) err(1, "lookup freq_levels"); + len = 5; + if (sysctlnametomib("hw.acpi.thermal.tz0.temperature", temp_mib, &len)) + err(1, "lookup temperature"); /* Check if we can read the idle time and supported freqs. */ if (read_usage_times(NULL, NULL)) @@ -370,6 +387,10 @@ len = sizeof(curfreq); if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0)) err(1, "error reading current CPU frequency"); + /* Read current temperature. */ + len = sizeof(temperature); + if(sysctl(temp_mib, 5, &temperature, &len, NULL, 0)) + err(1, "error reading current temperature"); if (vflag) { for (i = 0; i < numfreqs; i++) { @@ -410,12 +431,31 @@ err(1, "error setting CPU freq %d", freqs[0]); } + /* Check for passive cooling override */ + if(temperature > passive_cooling_mark) { + if (vflag) { + printf("passive cooling override; " + "changing frequency to %d MHz\n", + freqs[numfreqs - 1]); + } + if (set_freq(freqs[numfreqs - 1])) + err(1, "error setting CPU freq %d", + freqs[numfreqs - 1]); + } continue; } /* Adaptive mode; get the current CPU usage times. */ if (read_usage_times(&idle, &total)) err(1, "read_usage_times"); + /* + * If temperature has risen over passive cooling mark, we + * would want to decrease frequency regardless of the load, + * Simplest way to go about this would be to report 100% + * idle CPU and let adaptive algorithm do its job. + */ + if(temperature > passive_cooling_mark) + idle = total; /* * If we're idle less than the active mark, jump the CPU to