diff options
author | njl <njl@FreeBSD.org> | 2005-04-10 19:02:29 +0000 |
---|---|---|
committer | njl <njl@FreeBSD.org> | 2005-04-10 19:02:29 +0000 |
commit | 46d7cfdb4be46bba3546642a8321d0ce74c213e5 (patch) | |
tree | 2e8425148f2be3d609f0c43c1aefdb1b9a3e3112 /usr.sbin/powerd | |
parent | b2ebe1668997f2f770fe8a122a8614a9648942c4 (diff) | |
download | FreeBSD-src-46d7cfdb4be46bba3546642a8321d0ce74c213e5.zip FreeBSD-src-46d7cfdb4be46bba3546642a8321d0ce74c213e5.tar.gz |
Add support for recording the total energy used (in joules) when in
verbose mode. This is useful for profiling new adaptive algorithms
in performance (via time(1)) and total energy consumed for a given
workload.
Diffstat (limited to 'usr.sbin/powerd')
-rw-r--r-- | usr.sbin/powerd/powerd.c | 53 |
1 files changed, 47 insertions, 6 deletions
diff --git a/usr.sbin/powerd/powerd.c b/usr.sbin/powerd/powerd.c index 18566d2..a2ecb48 100644 --- a/usr.sbin/powerd/powerd.c +++ b/usr.sbin/powerd/powerd.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <fcntl.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -69,10 +70,11 @@ const char *modes[] = { #define APMDEV "/dev/apm" static int read_usage_times(long *idle, long *total); -static int read_freqs(int *numfreqs, int **freqs); +static int read_freqs(int *numfreqs, int **freqs, int **power); static int set_freq(int freq); static void acline_init(void); static int acline_read(void); +static void handle_sigs(int sig); static void parse_mode(char *arg, int *mode, int ch); static void usage(void); @@ -88,6 +90,7 @@ static int cpu_idle_mark; static int poll_ival; static int apm_fd; +static int exit_requested; static int read_usage_times(long *idle, long *total) @@ -116,7 +119,7 @@ read_usage_times(long *idle, long *total) } static int -read_freqs(int *numfreqs, int **freqs) +read_freqs(int *numfreqs, int **freqs, int **power) { char *freqstr, *p, *q; int i; @@ -138,13 +141,19 @@ read_freqs(int *numfreqs, int **freqs) free(freqstr); return (-1); } + if ((*power = malloc(*numfreqs * sizeof(int))) == NULL) { + free(freqstr); + free(*freqs); + return (-1); + } for (i = 0, p = freqstr; i < *numfreqs; i++) { q = strchr(p, ' '); if (q != NULL) *q = '\0'; - if (sscanf(p, "%d/%*d", &(*freqs)[i]) != 1) { + if (sscanf(p, "%d/%d", &(*freqs)[i], &(*power)[i]) != 2) { free(freqstr); free(*freqs); + free(*power); return (-1); } p = q + 1; @@ -225,6 +234,12 @@ parse_mode(char *arg, int *mode, int ch) } static void +handle_sigs(int __unused sig) +{ + exit_requested = 1; +} + +static void usage(void) { @@ -237,8 +252,9 @@ int main(int argc, char * argv[]) { long idle, total; - int curfreq, *freqs, i, numfreqs; + int curfreq, *freqs, i, *mwatts, numfreqs; int ch, mode_ac, mode_battery, mode_none, acline, mode, vflag; + uint64_t mjoules_used; size_t len; /* Default mode for all AC states is adaptive. */ @@ -246,6 +262,7 @@ main(int argc, char * argv[]) cpu_running_mark = DEFAULT_ACTIVE_PERCENT; cpu_idle_mark = DEFAULT_IDLE_PERCENT; poll_ival = DEFAULT_POLL_INTERVAL; + mjoules_used = 0; vflag = 0; apm_fd = -1; @@ -307,7 +324,7 @@ main(int argc, char * argv[]) /* Check if we can read the idle time and supported freqs. */ if (read_usage_times(NULL, NULL)) err(1, "read_usage_times"); - if (read_freqs(&numfreqs, &freqs)) + if (read_freqs(&numfreqs, &freqs, &mwatts)) err(1, "error reading supported CPU frequencies"); /* Decide whether to use ACPI or APM to read the AC line status. */ @@ -316,12 +333,23 @@ main(int argc, char * argv[]) /* Run in the background unless in verbose mode. */ if (!vflag) daemon(0, 0); + signal(SIGINT, handle_sigs); + signal(SIGTERM, handle_sigs); /* Main loop. */ for (;;) { /* Check status every few milliseconds. */ usleep(poll_ival); + /* If the user requested we quit, print some statistics. */ + if (exit_requested) { + if (vflag && mjoules_used != 0) + printf("total joules used: %u.%03u\n", + (u_int)(mjoules_used / 1000), + (int)mjoules_used % 1000); + break; + } + /* Read the current AC status and record the mode. */ acline = acline_read(); switch (acline) { @@ -343,6 +371,18 @@ main(int argc, char * argv[]) if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0)) err(1, "error reading current CPU frequency"); + if (vflag) { + for (i = 0; i < numfreqs; i++) { + if (freqs[i] == curfreq) + break; + } + + /* Keep a sum of all power actually used. */ + if (i < numfreqs && mwatts[i] != -1) + mjoules_used += + (mwatts[i] * (poll_ival / 1000)) / 1000; + } + /* Always switch to the lowest frequency in min mode. */ if (mode == MODE_MIN) { if (curfreq != freqs[numfreqs - 1]) { @@ -409,7 +449,8 @@ main(int argc, char * argv[]) freqs[i]); } } - /* NOTREACHED */ + free(freqs); + free(mwatts); exit(0); } |