summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugeni Dodonov <eugeni.dodonov@intel.com>2011-11-04 15:18:00 -0200
committerEugeni Dodonov <eugeni.dodonov@intel.com>2011-11-09 11:44:31 -0200
commit155770eb603567f8d4d21a6df064c507d1d2b492 (patch)
tree672652cc97deca0949ad338d1aff18a6eb1fe30d
parent31a4b13132d8d3c1c8e2d16205b9785f4e6bb48d (diff)
intel_gpu_top: Add linux-specific monitoring bits
Those bits are only used when compiling with --enable-linux-features, and allow to perform additional monitoring of CPU (user and system) usage and power usage over time. Signed-off-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
-rw-r--r--configure.ac10
-rw-r--r--tools/intel_gpu_top.c128
2 files changed, 138 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac
index 3e1218e..65947f9 100644
--- a/configure.ac
+++ b/configure.ac
@@ -97,6 +97,16 @@ if test "x$SHADER_DEBUGGER" = xyes; then
fi
fi
+AC_ARG_ENABLE(linux-features,
+ AS_HELP_STRING([--enable-linux-features],
+ [Enable additional Linux-specific features [default=no]]),
+ [LINUX_FEATURES="$enableval"],
+ [LINUX_FEATURES=no])
+AM_CONDITIONAL(HAVE_LINUX_FEATURES, [test "x$LINUX_FEATURES" = xyes])
+if test "x$LINUX_FEATURES" = xyes; then
+ AC_DEFINE(HAVE_LINUX_FEATURES, 1, [Have linux-specific features])
+fi
+
m4_ifndef([XORG_MACROS_VERSION], [AC_FATAL([must install xorg-macros 1.3 or later before running autoconf/autogen])])
XORG_MACROS_VERSION(1.3)
XORG_DEFAULT_OPTIONS
diff --git a/tools/intel_gpu_top.c b/tools/intel_gpu_top.c
index 260a28b..b656328 100644
--- a/tools/intel_gpu_top.c
+++ b/tools/intel_gpu_top.c
@@ -37,6 +37,7 @@
#include <string.h>
#include "intel_gpu_tools.h"
#include "instdone.h"
+#include "config.h"
#define FORCEWAKE 0xA18C
#define FORCEWAKE_ACK 0x130090
@@ -109,6 +110,105 @@ const char *stats_reg_names[STATS_COUNT] = {
uint64_t stats[STATS_COUNT];
uint64_t last_stats[STATS_COUNT];
+/*
+ * Architecture-specific monitoring facilities.
+ *
+ * Currently, they only exist for Linux, but let's not allow their usage block
+ * the tools usage on other systems.
+ */
+
+#ifdef HAVE_LINUX_FEATURES
+
+#define BATTERY "BAT1"
+
+struct cpudata
+{
+ unsigned long user, system, idle, nice, total;
+};
+
+struct proc_cpudata
+{
+ unsigned long userproc, systemproc, vmem, rmem;
+ char pname[255];
+};
+
+struct powerdata
+{
+ long rate;
+};
+
+ static void
+get_cpu_stat(struct cpudata *cpu)
+{
+ FILE *file;
+ char temp[10];
+ char line[255];
+
+ /* CPU */
+ file = fopen("/proc/stat", "r");
+ fgets(line, 255, file);
+ fclose(file);
+ sscanf(line, "%s %lu %lu %lu %lu", temp, &cpu->user, &cpu->nice, &cpu->system,
+ &cpu->idle);
+ cpu->total = cpu->user + cpu->system + cpu->idle + cpu->nice;
+
+}
+
+ static char*
+get_battery_file(char *battery)
+{
+ /* The format is /proc/acpi/battery/BAT?/state */
+ char *temp = (char *)malloc(sizeof(char) * (35 * strlen(battery)));
+ sprintf(temp, "/proc/acpi/battery/%s/state", battery);
+ return temp;
+}
+
+ static void
+get_power_stat(struct powerdata *power, const char *battery_file)
+{
+ FILE *file;
+ char line[255];
+
+ file = fopen(battery_file, "r");
+ if (!file) {
+ /* Unable to read battery information */
+ power->rate=-1;
+ return;
+ }
+ /* Sample /proc/acpi/battery/BAT?/state file format:
+ * present: yes
+ * capacity state: ok
+ * charging state: discharging
+ * present rate: 1746 mA
+ * remaining capacity: 5301 mAh
+ * present voltage: 11788 mV
+ */
+ fgets(line, 255, file);
+ fgets(line, 255, file);
+ fgets(line, 255, file);
+ fgets(line, 255, file);
+ sscanf(line, "present rate:\t%lu mAh\n", &power->rate);
+ fclose(file);
+}
+
+static void linux_print_header(FILE *out)
+{
+ fprintf(out, "user%%\tsys%%\tpower\t");
+}
+
+static void linux_print(FILE *out, struct cpudata *cpu, struct cpudata *oldcpu,
+ struct powerdata *power)
+{
+ float uload, sload;
+ uload = (float) ((cpu->user - oldcpu->user) * 100) / (cpu->total - oldcpu->total);
+ sload = (float) ((cpu->system - oldcpu->system) * 100) / (cpu->total - oldcpu->total);
+ fprintf(out, "%.2f\t%.2f\t%ld\t",
+ uload, sload, power->rate);
+}
+
+#endif
+
+
static unsigned long
gettime(void)
{
@@ -425,6 +525,12 @@ int main(int argc, char **argv)
char *cmd=NULL;
int interactive=1;
+#ifdef HAVE_LINUX_FEATURES
+ struct cpudata oldcpu, cpu;
+ struct powerdata power;
+ char *battery = BATTERY, *battery_file = NULL;
+#endif
+
/* Parse options? */
while ((ch = getopt(argc, argv, "s:o:e:h")) != -1) {
switch (ch) {
@@ -514,6 +620,14 @@ int main(int argc, char **argv)
ring_init(&blt_ring);
}
+#ifdef HAVE_LINUX_FEATURES
+ /* Calculate initial stats */
+ /* Battery */
+ battery_file = get_battery_file(battery);
+ /* CPU */
+ get_cpu_stat(&oldcpu);
+#endif
+
/* Initialize GPU stats */
if (HAS_STATS_REGS(devid)) {
for (i = 0; i < STATS_COUNT; i++) {
@@ -576,6 +690,14 @@ int main(int argc, char **argv)
usleep(interval);
}
+#ifdef HAVE_LINUX_FEATURES
+ /* CPU */
+ get_cpu_stat(&cpu);
+
+ /* Power */
+ get_power_stat(&power, battery_file);
+#endif
+
if (HAS_STATS_REGS(devid)) {
for (i = 0; i < STATS_COUNT; i++) {
uint32_t stats_high, stats_low, stats_high_2;
@@ -645,6 +767,9 @@ int main(int argc, char **argv)
/* Print headers for columns at first run */
if (print_headers) {
fprintf(output, "# time\t");
+#ifdef HAVE_LINUX_FEATURES
+ linux_print_header(output);
+#endif
ring_print_header(output, &render_ring);
ring_print_header(output, &bsd_ring);
ring_print_header(output, &bsd6_ring);
@@ -664,6 +789,9 @@ int main(int argc, char **argv)
/* Print statistics */
fprintf(output, "%.2f\t", elapsed_time);
+#ifdef HAVE_LINUX_FEATURES
+ linux_print(output, &cpu, &oldcpu, &power);
+#endif
ring_log(&render_ring, last_samples_per_sec, output);
ring_log(&bsd_ring, last_samples_per_sec, output);
ring_log(&bsd6_ring, last_samples_per_sec, output);