summaryrefslogtreecommitdiffstats
path: root/src/devices/device.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/device.cpp')
-rw-r--r--src/devices/device.cpp345
1 files changed, 345 insertions, 0 deletions
diff --git a/src/devices/device.cpp b/src/devices/device.cpp
new file mode 100644
index 0000000..f191072
--- /dev/null
+++ b/src/devices/device.cpp
@@ -0,0 +1,345 @@
+/*
+ * Copyright 2010, Intel Corporation
+ *
+ * This file 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.
+ *
+ * Authors:
+ * Arjan van de Ven <arjan@linux.intel.com>
+ */
+
+#include "device.h"
+#include <vector>
+#include <algorithm>
+#include <stdio.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+using namespace std;
+
+#include "backlight.h"
+#include "usb.h"
+#include "ahci.h"
+#include "alsa.h"
+#include "rfkill.h"
+#include "i915-gpu.h"
+#include "thinkpad-fan.h"
+#include "thinkpad-light.h"
+#include "network.h"
+#include "runtime_pm.h"
+
+#include "../parameters/parameters.h"
+#include "../display.h"
+#include "../lib.h"
+#include "../report/report.h"
+#include "../report/report-maker.h"
+#include "../report/report-data-html.h"
+#include "../measurement/measurement.h"
+#include "../devlist.h"
+#include <unistd.h>
+
+device::device(void)
+{
+ cached_valid = 0;
+ hide = 0;
+
+ memset(guilty, 0, sizeof(guilty));
+ memset(real_path, 0, sizeof(real_path));
+}
+
+
+void device::register_sysfs_path(const char *path)
+{
+ char current_path[PATH_MAX + 1];
+ int iter = 0;
+ pt_strcpy(current_path, path);
+
+ while (iter++ < 10) {
+ char test_path[PATH_MAX + 1];
+ snprintf(test_path, sizeof(test_path), "%s/device", current_path);
+ if (access(test_path, R_OK) == 0)
+ strcpy(current_path, test_path);
+ else
+ break;
+ }
+
+ if (!realpath(current_path, real_path))
+ real_path[0] = 0;
+}
+
+void device::start_measurement(void)
+{
+ hide = false;
+}
+
+void device::end_measurement(void)
+{
+}
+
+double device::utilization(void)
+{
+ return 0.0;
+}
+
+
+
+vector<class device *> all_devices;
+
+
+void devices_start_measurement(void)
+{
+ unsigned int i;
+ for (i = 0; i < all_devices.size(); i++)
+ all_devices[i]->start_measurement();
+}
+
+void devices_end_measurement(void)
+{
+ unsigned int i;
+ for (i = 0; i < all_devices.size(); i++)
+ all_devices[i]->end_measurement();
+
+ clear_devpower();
+
+ for (i = 0; i < all_devices.size(); i++) {
+ all_devices[i]->hide = false;
+ all_devices[i]->register_power_with_devlist(&all_results, &all_parameters);
+ }
+}
+
+static bool power_device_sort(class device * i, class device * j)
+{
+ double pI, pJ;
+ pI = i->power_usage(&all_results, &all_parameters);
+ pJ = j->power_usage(&all_results, &all_parameters);
+
+ if (equals(pI, pJ)) {
+ int vI, vJ;
+ vI = i->power_valid();
+ vJ = j->power_valid();
+
+ if (vI != vJ)
+ return vI > vJ;
+
+ return i->utilization() > j->utilization();
+ }
+ return pI > pJ;
+}
+
+
+void report_devices(void)
+{
+ WINDOW *win;
+ unsigned int i;
+ int show_power;
+ double pw;
+
+ char util[128];
+ char power[128];
+
+ win = get_ncurses_win("Device stats");
+ if (!win)
+ return;
+
+ show_power = global_power_valid();
+
+ wclear(win);
+ wmove(win, 2,0);
+
+ sort(all_devices.begin(), all_devices.end(), power_device_sort);
+
+
+
+ pw = global_power();
+ if (pw > 0.0001) {
+ char buf[32];
+ wprintw(win, _("The battery reports a discharge rate of %sW\n"),
+ fmt_prefix(pw, buf));
+ wprintw(win, _("The energy consumed was %sJ\n"),
+ fmt_prefix(global_joules(), buf));
+ }
+
+ if (show_power) {
+ char buf[32];
+ wprintw(win, _("System baseline power is estimated at %sW\n"),
+ fmt_prefix(get_parameter_value("base power"), buf));
+ }
+
+ if (pw > 0.0001 || show_power)
+ wprintw(win, "\n");
+ if (show_power)
+ wprintw(win, _("Power est. Usage Device name\n"));
+ else
+ wprintw(win, _(" Usage Device name\n"));
+
+ for (i = 0; i < all_devices.size(); i++) {
+ double P;
+
+ util[0] = 0;
+
+ if (all_devices[i]->util_units()) {
+ if (all_devices[i]->utilization() < 1000)
+ sprintf(util, "%5.1f%s", all_devices[i]->utilization(), all_devices[i]->util_units());
+ else
+ sprintf(util, "%5i%s", (int)all_devices[i]->utilization(), all_devices[i]->util_units());
+ }
+ while (strlen(util) < 13) strcat(util, " ");
+
+ P = all_devices[i]->power_usage(&all_results, &all_parameters);
+
+ format_watts(P, power, 11);
+
+ if (!show_power || !all_devices[i]->power_valid())
+ strcpy(power, " ");
+
+
+ wprintw(win, "%s %s %s\n",
+ power,
+ util,
+ all_devices[i]->human_name()
+ );
+ }
+}
+
+void show_report_devices(void)
+{
+ unsigned int i;
+ int show_power, cols, rows, idx;
+ double pw;
+
+ show_power = global_power_valid();
+ sort(all_devices.begin(), all_devices.end(), power_device_sort);
+
+ /* div attr css_class and css_id */
+ tag_attr div_attr;
+ init_div(&div_attr, "clear_block", "devinfo");
+
+ /* Set Table attributes, rows, and cols */
+ table_attributes std_table_css;
+ cols=2;
+ if (show_power)
+ cols=3;
+
+ idx = cols;
+ rows= all_devices.size() + 1;
+ init_std_side_table_attr(&std_table_css, rows, cols);
+
+ /* Set Title attributes */
+ tag_attr title_attr;
+ init_title_attr(&title_attr);
+
+ /* Add section */
+ report.add_div(&div_attr);
+
+ /* Device Summary */
+ int summary_size=2;
+ string *summary = new string[summary_size];
+ pw = global_power();
+ char buf[32];
+ if (pw > 0.0001) {
+ summary[0]= __("The battery reports a discharge rate of: ");
+ summary[1]=string(fmt_prefix(pw, buf));
+ summary[1].append(" W");
+ report.add_summary_list(summary, summary_size);
+
+ summary[0]= __("The energy consumed was : ");
+ summary[1]=string(fmt_prefix(global_joules(), buf));
+ summary[1].append(" J");
+ report.add_summary_list(summary, summary_size);
+ }
+
+ if (show_power) {
+ summary[0]=__("The system baseline power is estimated at: ");
+ summary[1]=string(fmt_prefix(get_parameter_value("base power"), buf));
+ summary[1].append(" W");
+ report.add_summary_list(summary, summary_size);
+ }
+ delete [] summary;
+
+ /* Set array of data in row Major order */
+ string *device_data = new string[cols * rows];
+ device_data[0]= __("Usage");
+ device_data[1]= __("Device Name");
+ if (show_power)
+ device_data[2]= __("PW Estimate");
+
+ for (i = 0; i < all_devices.size(); i++) {
+ double P;
+ char util[128];
+ char power[128];
+
+ util[0] = 0;
+ if (all_devices[i]->util_units()) {
+ if (all_devices[i]->utilization() < 1000)
+ sprintf(util, "%5.1f%s",
+ all_devices[i]->utilization(),
+ all_devices[i]->util_units());
+ else
+ sprintf(util, "%5i%s",
+ (int)all_devices[i]->utilization(),
+ all_devices[i]->util_units());
+ }
+
+ P = all_devices[i]->power_usage(&all_results, &all_parameters);
+ format_watts(P, power, 11);
+
+ if (!show_power || !all_devices[i]->power_valid())
+ strcpy(power, " ");
+
+ device_data[idx]= string(util);
+ idx+=1;
+
+ device_data[idx]= string(all_devices[i]->human_name());
+ idx+=1;
+
+ if (show_power) {
+ device_data[idx]= string(power);
+ idx+=1;
+ }
+ }
+ /* Report Output */
+ report.add_title(&title_attr, __("Device Power Report"));
+ report.add_table(device_data, &std_table_css);
+ delete [] device_data;
+}
+
+
+void create_all_devices(void)
+{
+ create_all_backlights();
+ create_all_usb_devices();
+ create_all_ahcis();
+ create_all_alsa();
+ create_all_rfkills();
+ create_i915_gpu();
+ create_thinkpad_fan();
+ create_thinkpad_light();
+ create_all_nics();
+ create_all_runtime_pm_devices();
+}
+
+
+void clear_all_devices(void)
+{
+ unsigned int i;
+ for (i = 0; i < all_devices.size(); i++) {
+ delete all_devices[i];
+ }
+ all_devices.clear();
+}