summaryrefslogtreecommitdiffstats
path: root/usr.sbin/powerd
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2005-04-10 19:02:29 +0000
committernjl <njl@FreeBSD.org>2005-04-10 19:02:29 +0000
commit46d7cfdb4be46bba3546642a8321d0ce74c213e5 (patch)
tree2e8425148f2be3d609f0c43c1aefdb1b9a3e3112 /usr.sbin/powerd
parentb2ebe1668997f2f770fe8a122a8614a9648942c4 (diff)
downloadFreeBSD-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.c53
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);
}
OpenPOWER on IntegriCloud