top: Attempt to avoid negative "(unknown)" %

Top was using the 'theorical' interval value to determine the percentages.
The measured thread times were taken in an always a bit larger interval than
that theorical value, hence the negative '%' occuring regularly.

Should fix #4589.
This commit is contained in:
Philippe Saint-Pierre
2012-05-08 21:09:36 -04:00
parent f5b83627d0
commit f1e0212d72
+24 -23
View File
@@ -20,6 +20,7 @@
#include <termios.h> #include <termios.h>
static const char IDLE_NAME[] = "idle thread "; static const char IDLE_NAME[] = "idle thread ";
static bigtime_t lastMeasure = 0;
/* /*
* Keeps track of a single thread's times * Keeps track of a single thread's times
@@ -243,8 +244,7 @@ compare(
utotal = 0; utotal = 0;
for (i = 0; i < times.nthreads; i++) { for (i = 0; i < times.nthreads; i++) {
ignore = 0; ignore = 0;
if (get_thread_info(times.thread_times[i].thid, if (get_thread_info(times.thread_times[i].thid, &t) < B_NO_ERROR) {
&t) < B_NO_ERROR) {
strcpy(t.name, "(unknown)"); strcpy(t.name, "(unknown)");
strcpy(tm.args, "(unknown)"); strcpy(tm.args, "(unknown)");
} else { } else {
@@ -286,10 +286,10 @@ compare(
} }
free_times(&times); free_times(&times);
printf("------ %7.2f %7.2f %7.2f %4.1f%% TOTAL (%4.1f%% idle time, %4.1f%% unknown)", printf("------ %7.2f %7.2f %7.2f %4.1f%% TOTAL (%4.1f%% idle time, %4.1f%% unknown)",
(double)(gtotal / 1000), (double) (gtotal / 1000),
(double) (utotal / 1000), (double) (utotal / 1000),
(double) (ktotal / 1000), (double) (ktotal / 1000),
cpu_perc(gtotal, uinterval), cpu_perc(gtotal, uinterval),
cpu_perc(idletime, uinterval), cpu_perc(idletime, uinterval),
cpu_perc(cpus * uinterval - (gtotal + idletime), uinterval)); cpu_perc(cpus * uinterval - (gtotal + idletime), uinterval));
fflush(stdout); fflush(stdout);
@@ -339,7 +339,6 @@ static thread_time_list_t
gather( gather(
thread_time_list_t *old, thread_time_list_t *old,
bigtime_t *busy_wait_time, bigtime_t *busy_wait_time,
bigtime_t uinterval,
int refresh int refresh
) )
{ {
@@ -351,10 +350,18 @@ gather(
bigtime_t old_busy; bigtime_t old_busy;
int i; int i;
system_info info; system_info info;
bigtime_t oldLastMeasure;
i = 0; i = 0;
init_times(&times); init_times(&times);
tmcookie = 0; tmcookie = 0;
oldLastMeasure = lastMeasure;
lastMeasure = system_time();
get_system_info(&info);
old_busy = *busy_wait_time;
*busy_wait_time = info._busy_wait_time;
while (get_next_team_info(&tmcookie, &tm) == B_NO_ERROR) { while (get_next_team_info(&tmcookie, &tm) == B_NO_ERROR) {
thcookie = 0; thcookie = 0;
while (get_next_thread_info(tm.team, &thcookie, &t) == B_NO_ERROR) { while (get_next_thread_info(tm.team, &thcookie, &t) == B_NO_ERROR) {
@@ -365,15 +372,13 @@ gather(
i++; i++;
} }
} }
get_system_info(&info);
old_busy = *busy_wait_time;
*busy_wait_time = info._busy_wait_time;
if (old != NULL) { if (old != NULL) {
if (screen_size_changed) { if (screen_size_changed) {
setup_term(true); setup_term(true);
screen_size_changed = 0; screen_size_changed = 0;
} }
compare(old, &times, old_busy, *busy_wait_time, uinterval, refresh); compare(old, &times, old_busy, *busy_wait_time,
system_time() - oldLastMeasure, refresh);
free_times(old); free_times(old);
} }
return (times); return (times);
@@ -451,30 +456,26 @@ main(int argc, char **argv)
signal(SIGWINCH, winch_handler); signal(SIGWINCH, winch_handler);
then = system_time(); lastMeasure = system_time();
if (iters < 0) { if (iters < 0) {
// You will only have to wait half a second for the first iteration. // You will only have to wait half a second for the first iteration.
uinterval = 1 * 1000000 / 2; uinterval = 1 * 1000000 / 2;
baseline = gather(NULL, &busy, 0, refresh); baseline = gather(NULL, &busy, refresh);
elapsed = system_time() - then; elapsed = system_time() - lastMeasure;
if (elapsed < uinterval) { if (elapsed < uinterval)
snooze(uinterval - elapsed); snooze(uinterval - elapsed);
elapsed = uinterval;
}
then = system_time(); then = system_time();
baseline = gather(&baseline, &busy, elapsed, refresh); baseline = gather(&baseline, &busy, refresh);
} else } else
baseline = gather(NULL, &busy, 0, refresh); baseline = gather(NULL, &busy, refresh);
uinterval = interval * 1000000; uinterval = interval * 1000000;
for (i = 0; iters < 0 || i < iters; i++) { for (i = 0; iters < 0 || i < iters; i++) {
elapsed = system_time() - then; elapsed = system_time() - lastMeasure;
if (elapsed < uinterval) { if (elapsed < uinterval)
snooze(uinterval - elapsed); snooze(uinterval - elapsed);
elapsed = uinterval; baseline = gather(&baseline, &busy, refresh);
}
then = system_time();
baseline = gather(&baseline, &busy, elapsed, refresh);
} }
exit(0); exit(0);
} }