diff options
author | Eugeni Dodonov <eugeni.dodonov@intel.com> | 2011-11-04 15:18:00 -0200 |
---|---|---|
committer | Eugeni Dodonov <eugeni.dodonov@intel.com> | 2011-11-09 11:44:31 -0200 |
commit | 155770eb603567f8d4d21a6df064c507d1d2b492 (patch) | |
tree | 672652cc97deca0949ad338d1aff18a6eb1fe30d | |
parent | 31a4b13132d8d3c1c8e2d16205b9785f4e6bb48d (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.ac | 10 | ||||
-rw-r--r-- | tools/intel_gpu_top.c | 128 |
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); |