aboutsummaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorChris E Ferron <chris.e.ferron@linux.intel.com>2012-04-25 10:26:35 -0700
committerChris E Ferron <chris.e.ferron@linux.intel.com>2012-04-25 10:26:35 -0700
commitefba72db63efb2eafb2ef5622c0a33ed5d944aa5 (patch)
tree7d83fb38f7beb8bd585bfafe5dcde12f9f43c8c3 /src/main.cpp
parent3575f3e5d542434e788d79bf5d646b73a34ce94f (diff)
downloadpowertop-2.0-v2-efba72db63efb2eafb2ef5622c0a33ed5d944aa5.tar.gz
This is the inital Auto Tools work, along with some small updates.
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp446
1 files changed, 446 insertions, 0 deletions
diff --git a/src/main.cpp b/src/main.cpp
new file mode 100644
index 0000000..77e6d05
--- /dev/null
+++ b/src/main.cpp
@@ -0,0 +1,446 @@
+/*
+ * Copyright 2010, Intel Corporation
+ *
+ * This is part of PowerTOP
+ *
+ * This program file is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc,
+ * 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA
+ * or just google for it.
+ *
+ * getopt code is taken from "The GNU C Library" reference manual,
+ * section 24.2 "Parsing program options using getopt"
+ * http://www.gnu.org/s/libc/manual/html_node/Getopt-Long-Option-Example.html
+ * Manual published under the terms of the Free Documentation License.
+ *
+ * Authors:
+ * Arjan van de Ven <arjan@linux.intel.com>
+ */
+#include <iostream>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <sys/stat.h>
+#include <sys/statfs.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <locale.h>
+
+#include "cpu/cpu.h"
+#include "process/process.h"
+#include "perf/perf.h"
+#include "perf/perf_bundle.h"
+#include "lib.h"
+
+
+#include "devices/device.h"
+#include "devices/usb.h"
+#include "measurement/measurement.h"
+#include "parameters/parameters.h"
+#include "calibrate/calibrate.h"
+
+
+#include "tuning/tuning.h"
+
+#include "display.h"
+#include "devlist.h"
+#include "report.h"
+
+#define DEBUGFS_MAGIC 0x64626720
+
+int debug_learning = 0;
+unsigned time_out = 20;
+int leave_powertop = 0;
+
+static const struct option long_options[] =
+{
+ /* These options set a flag. */
+ {"debug", no_argument, &debug_learning, 'd'},
+ {"version", no_argument, NULL, 'V'},
+ {"help",no_argument, NULL, 'u'}, /* u for usage */
+ {"calibrate",no_argument, NULL, 'c'},
+ {"html", optional_argument, NULL, 'h'},
+ {"csv", optional_argument, NULL, 'C'},
+ {"extech", optional_argument, NULL, 'e'},
+ {"time", optional_argument, NULL, 't'},
+ {"iteration", optional_argument, NULL, 'i'},
+ {NULL, 0, NULL, 0}
+};
+
+static void print_version()
+{
+ printf(_("Powertop version" POWERTOP_VERSION ", compiled on "__DATE__ "\n"));
+}
+
+static bool set_refresh_timeout()
+{
+ static char buf[4];
+ mvprintw(1, 0, "%s (currently %u): ", _("Set refresh time out"), time_out);
+ memset(buf, '\0', sizeof(buf));
+ get_user_input(buf, sizeof(buf) - 1);
+ show_tab(0);
+ unsigned time = strtoul(buf, NULL, 0);
+ if (!time) return 0;
+ if (time > 32) time = 32;
+ time_out = time;
+ return 1;
+}
+
+static void print_usage()
+{
+ printf(_("Usage: powertop [OPTIONS]\n\n"));
+ printf(_("--debug \t run in \"debug\" mode\n"));
+ printf(_("--version \t print version information\n"));
+ printf(_("--calibrate \t runs powertop in calibration mode\n"));
+ printf(_("--extech=devnode \t uses an Extech Power Analyzer for measurements\n"));
+ printf(_("--html[=FILENAME]\t\t generate a html report\n"));
+ printf(_("--csv[=FILENAME]\t\t generate a csv report\n"));
+ printf(_("--time[=secs]\t\t generate a report for secs\n"));
+ printf(_("--iteration[=iterations]\t\t number of times to run tests\n"));
+ printf(_("--help \t\t print this help menu\n"));
+ printf("\n");
+ printf(_("For more help please refer to the README\n\n"));
+}
+
+static void do_sleep(int seconds)
+{
+ time_t target;
+ int delta;
+
+ if (!ncurses_initialized()) {
+ sleep(seconds);
+ return;
+ }
+#ifndef DISABLE_NCURSES
+ target = time(NULL) + seconds;
+ delta = seconds;
+ do {
+ int c;
+ usleep(6000);
+ halfdelay(delta * 10);
+
+ c = getch();
+
+ switch (c) {
+ case KEY_NPAGE:
+ case KEY_RIGHT:
+ show_next_tab();
+ break;
+ case KEY_PPAGE:
+ case KEY_LEFT:
+ show_prev_tab();
+ break;
+ case KEY_DOWN:
+ cursor_down();
+ break;
+ case KEY_UP:
+ cursor_up();
+ break;
+ case 10:
+ cursor_enter();
+ break;
+ case 's':
+ if (set_refresh_timeout())
+ return;
+ break;
+ case 'r':
+ window_refresh();
+ return;
+ case KEY_EXIT:
+ case 'q':
+ case 27:
+ leave_powertop = 1;
+ return;
+ }
+
+ delta = target - time(NULL);
+ if (delta <= 0)
+ break;
+
+ } while (1);
+#endif
+}
+
+
+void one_measurement(int seconds)
+{
+ create_all_usb_devices();
+ start_power_measurement();
+ devices_start_measurement();
+ start_process_measurement();
+ start_cpu_measurement();
+
+ do_sleep(seconds);
+
+ end_cpu_measurement();
+ end_process_measurement();
+ collect_open_devices();
+ devices_end_measurement();
+ end_power_measurement();
+
+ process_cpu_data();
+ process_process_data();
+
+ /* output stats */
+ process_update_display();
+ report_summary();
+ w_display_cpu_cstates();
+ w_display_cpu_pstates();
+ report_display_cpu_cstates();
+ report_display_cpu_pstates();
+ report_process_update_display();
+
+ tuning_update_display();
+
+ end_process_data();
+
+ global_joules_consumed();
+ compute_bundle();
+
+ show_report_devices();
+ report_show_open_devices();
+
+ report_devices();
+
+ store_results(measurement_time);
+ end_cpu_data();
+}
+
+void out_of_memory()
+{
+ reset_display();
+ printf("Out of memory. Aborting...\n");
+ abort();
+}
+
+static void load_board_params()
+{
+ string boardname;
+ char filename[4096];
+
+ boardname = read_sysfs_string("/etc/boardname");
+
+ if (boardname.length() < 2)
+ return;
+
+ sprintf(filename, "/var/cache/powertop/saved_parameters.powertop.%s", boardname.c_str());
+
+ if (access(filename, R_OK))
+ return;
+
+ load_parameters(filename);
+ global_fixed_parameters = 1;
+ global_power_override = 1;
+}
+
+void report(int time, int iterations, char *file)
+{
+
+ /* one to warm up everything */
+ fprintf(stderr, _("Preparing to take measurements\n"));
+ utf_ok = 0;
+ one_measurement(1);
+ fprintf(stderr, _("Measuring %d time(s) for %d seconds each\n"),iterations,time);
+ for (int i=0; i != iterations; i++){
+ init_report_output(file);
+ initialize_tuning();
+ /* and then the real measurement */
+ one_measurement(time);
+ report_show_tunables();
+ finish_report_output();
+ clear_tuning();
+ }
+ /* and wrap up */
+ learn_parameters(50, 0);
+ save_all_results("saved_results.powertop");
+ save_parameters("saved_parameters.powertop");
+ end_pci_access();
+ exit(0);
+}
+
+int main(int argc, char **argv)
+{
+ int ret;
+ int uid;
+ int option_index;
+ int c;
+ bool wantreport = FALSE;
+ char filename[4096];;
+ int iterations = 1;
+ struct statfs st_fs;
+
+ //set_new_handler(out_of_memory);
+
+ setlocale (LC_ALL, "");
+#ifndef DISABLE_I18N
+ bindtextdomain ("powertop", "/usr/share/locale");
+ textdomain ("powertop");
+#endif
+ uid = getuid();
+
+ if (uid != 0) {
+ printf(_("PowerTOP " POWERTOP_VERSION " must be run with root privileges.\n"));
+ printf(_("exiting...\n"));
+ exit(EXIT_FAILURE);
+ }
+ ret = system("/sbin/modprobe cpufreq_stats > /dev/null 2>&1");
+ ret = system("/sbin/modprobe msr > /dev/null 2>&1");
+
+ statfs("/sys/kernel/debug", &st_fs);
+ if (st_fs.f_type != (long) DEBUGFS_MAGIC) {
+ if (access("/bin/mount", X_OK) == 0) {
+ ret = system("/bin/mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1");
+ } else {
+ ret = system("mount -t debugfs debugfs /sys/kernel/debug > /dev/null 2>&1");
+ }
+ if (ret != 0) {
+ printf(_("Failed to mount debugfs!\n"));
+ printf(_("exiting...\n"));
+ exit(EXIT_FAILURE);
+ }
+ }
+
+ srand(time(NULL));
+
+ if (access("/var/cache/", W_OK) == 0)
+ mkdir("/var/cache/powertop", 0600);
+ else
+ mkdir("/data/local/powertop", 0600);
+
+ load_results("saved_results.powertop");
+ load_parameters("saved_parameters.powertop");
+
+ enumerate_cpus();
+ create_all_devices();
+ detect_power_meters();
+
+ register_parameter("base power", 100, 0.5);
+ register_parameter("cpu-wakeups", 39.5);
+ register_parameter("cpu-consumption", 1.56);
+ register_parameter("gpu-operations", 0.5576);
+ register_parameter("disk-operations-hard", 0.2);
+ register_parameter("disk-operations", 0.0);
+ register_parameter("xwakes", 0.1);
+
+ load_board_params();
+
+ while (1) { /* parse commandline options */
+ c = getopt_long (argc, argv, "ch:C:i:t:uV", long_options, &option_index);
+ /* Detect the end of the options. */
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'V':
+ print_version();
+ exit(0);
+ break;
+
+ case 'e': /* Extech power analyzer support */
+ extech_power_meter(optarg ? optarg : "/dev/ttyUSB0");
+ break;
+ case 'u':
+ print_usage();
+ exit(0);
+ break;
+
+ case 'c':
+ calibrate();
+ break;
+
+ case 'h': /* html report */
+ wantreport = TRUE;
+ reporttype = 1;
+ sprintf(filename, "%s", optarg ? optarg : "powertop.html" );
+ break;
+
+ case 't':
+ time_out = (optarg ? atoi(optarg) : 20);
+ break;
+
+ case 'i':
+ iterations = (optarg ? atoi(optarg) : 1);
+ break;
+
+ case 'C': /* csv report*/
+ wantreport = TRUE;
+ reporttype = 0;
+ sprintf(filename, "%s", optarg ? optarg : "powertop.csv");
+ break;
+ case '?': /* Unknown option */
+ /* getopt_long already printed an error message. */
+ break;
+ }
+ }
+
+ if (wantreport)
+ report(time_out, iterations, filename);
+
+ if (debug_learning)
+ printf("Learning debugging enabled\n");
+
+
+
+ learn_parameters(250, 0);
+ save_parameters("saved_parameters.powertop");
+
+
+ if (debug_learning) {
+ learn_parameters(1000, 1);
+ dump_parameter_bundle();
+ end_pci_access();
+ exit(0);
+ }
+
+
+ /* first one is short to not let the user wait too long */
+ init_display();
+ one_measurement(1);
+ initialize_tuning();
+ tuning_update_display();
+ show_tab(0);
+
+
+
+ while (!leave_powertop) {
+ one_measurement(time_out);
+ show_cur_tab();
+ learn_parameters(15, 0);
+ }
+#ifndef DISABLE_NCURSES
+ endwin();
+#endif
+ printf(_("Leaving PowerTOP\n"));
+
+
+ end_process_data();
+ clear_process_data();
+ end_cpu_data();
+ clear_cpu_data();
+
+ save_all_results("saved_results.powertop");
+ save_parameters("saved_parameters.powertop");
+ learn_parameters(500, 0);
+ save_parameters("saved_parameters.powertop");
+ end_pci_access();
+ clear_tuning();
+ reset_display();
+
+ clear_all_devices();
+ clear_all_cpus();
+
+ return 0;
+
+
+}