diff options
author | Patrick Cain <pcain@codeaurora.org> | 2012-10-24 12:33:15 -0700 |
---|---|---|
committer | Patrick Cain <pcain@codeaurora.org> | 2012-10-25 12:46:00 -0700 |
commit | d5f3cfbb0b2a00a615932cf55d15e42cf5e4448c (patch) | |
tree | c19bcba145f87640bceffce9296e3b018030dd50 | |
parent | 1e2c884c9779fe5717830966b615a7221243c1ac (diff) | |
download | android_external_powertop-d5f3cfbb0b2a00a615932cf55d15e42cf5e4448c.tar.gz android_external_powertop-d5f3cfbb0b2a00a615932cf55d15e42cf5e4448c.tar.bz2 android_external_powertop-d5f3cfbb0b2a00a615932cf55d15e42cf5e4448c.zip |
powertop: Fix number of online CPUs calculation
Currently powertop counts offline hotplugged cores as
active CPUs. This change fixes that so only currently
online cores will have their statistics counted and
averaged across the correct number of online CPUs.
Change-Id: Ie5314e37044a915601e7537f08d90bdaa171b604
-rw-r--r-- | powertop.c | 40 |
1 files changed, 30 insertions, 10 deletions
@@ -56,6 +56,8 @@ int topcstate = 0; int dump = 0; int reset_pm_stats = 0; +static int cpu_count = 0; + #define IRQCOUNT 150 struct irqdata { @@ -328,6 +330,7 @@ static void read_data_cpuidle(uint64_t * usage, uint64_t * duration) char line[4096]; char filename[128], *f; int len, clevel = 0; + int numcpus = 0; memset(usage, 0, 64); memset(duration, 0, 64); @@ -343,8 +346,20 @@ static void read_data_cpuidle(uint64_t * usage, uint64_t * duration) if (!isdigit(entry->d_name[3])) continue; - - len = sprintf(filename, "/sys/devices/system/cpu/%s/cpuidle", + len = snprintf(filename, 128, "/sys/devices/system/cpu/%s/online", + entry->d_name); + file = fopen(filename, "r"); + if (file) { + f = fgets(line, 4096, file); + fclose(file); + if (f != NULL) { + if (*f == '1') + numcpus++; + else + continue; + } + } + len = snprintf(filename, 128, "/sys/devices/system/cpu/%s/cpuidle", entry->d_name); dir = opendir(filename); @@ -424,6 +439,8 @@ static void read_data_cpuidle(uint64_t * usage, uint64_t * duration) } closedir(cpudir); + if (numcpus) + cpu_count = numcpus; } static void read_data(uint64_t * usage, uint64_t * duration) @@ -878,6 +895,7 @@ int main(int argc, char **argv) struct timeval tv; int key; + int num_cpus = sysconf(_SC_NPROCESSORS_ONLN); int i = 0; double c0 = 0; char *c; @@ -932,13 +950,15 @@ int main(int argc, char **argv) if (totalevents == 0 && maxcstate <= 1) { sprintf(cstate_lines[5],_("< Detailed C-state information is not available.>\n")); } else { - double sleept, percentage;; - c0 = sysconf(_SC_NPROCESSORS_ONLN) * ticktime * 1000 * FREQ - totalticks; + double sleept, percentage; + if (cpu_count) + num_cpus = cpu_count; + c0 = num_cpus * ticktime * 1000 * FREQ - totalticks; if (c0 < 0) c0 = 0; /* rounding errors in measurement might make c0 go slightly negative.. this is confusing */ sprintf(cstate_lines[0], _("Cn\t Avg residency\n")); - percentage = c0 * 100.0 / (sysconf(_SC_NPROCESSORS_ONLN) * ticktime * 1000 * FREQ); + percentage = c0 * 100.0 / (num_cpus * ticktime * 1000 * FREQ); sprintf(cstate_lines[1], _("C0 (cpu running) (%4.1f%%)\n"), percentage); if (percentage > 50) topcstate = 0; @@ -948,7 +968,7 @@ int main(int argc, char **argv) + 0.1) / FREQ; percentage = (cur_duration[i] - last_duration[i]) * 100 / - (sysconf(_SC_NPROCESSORS_ONLN) * ticktime * 1000 * FREQ); + (num_cpus * ticktime * 1000 * FREQ); if (cnames[i][0]==0) sprintf(cnames[i],"C%i",i+1); @@ -1038,9 +1058,9 @@ int main(int argc, char **argv) #endif if (strstr(line, "total events")) { int d; - d = strtoull(line, NULL, 10) / sysconf(_SC_NPROCESSORS_ONLN); + d = strtoull(line, NULL, 10) / num_cpus; if (totalevents == 0) { /* No c-state info available, use timerstats instead */ - totalevents = d * sysconf(_SC_NPROCESSORS_ONLN) + total_interrupt; + totalevents = d * num_cpus + total_interrupt; if (d < interrupt_0) totalevents += interrupt_0 - d; } @@ -1050,8 +1070,8 @@ int main(int argc, char **argv) if (totalevents && ticktime) { - wakeups_per_second = totalevents * 1.0 / ticktime / sysconf(_SC_NPROCESSORS_ONLN); - show_wakeups(wakeups_per_second, ticktime, c0 * 100.0 / (sysconf(_SC_NPROCESSORS_ONLN) * ticktime * 1000 * FREQ) ); + wakeups_per_second = totalevents * 1.0 / ticktime / num_cpus; + show_wakeups(wakeups_per_second, ticktime, c0 * 100.0 / (num_cpus * ticktime * 1000 * FREQ)); } count_usb_urbs(); print_battery_sysfs(); |