From Denis Vlasenko: * CPU% = process[i].ticks/sum(process[i].ticks) * busy_cpu_ticks/total_cpu_ticks * got rid of empty line under "Load average" line and used last line - +2 visible processes * do not do float conversion of loadavg, just read it as string from /proc * fix display on small screen
This commit was genuinely broken at the time (not related to our build system): scripts/config/mkconfigs.c (2005-08-01 - 2006-10-05 arasi) uretilen bbconfigopts.h icine .config satirlarini kacissiz, ham newline'larla gömüyordu - gecerli C degildi, busybox'un kendi bb_mkdep araci bile parse edemiyordu (7d219aab7 ile duzeltildi, mkconfigs shell scripte cevrildi)
No binary (build failed)
—
(log yok)
| @@ -52,13 +52,13 @@ static procps_status_t *top; /* Hehe */ | |
| static int ntop; | |
| #ifdef CONFIG_FEATURE_USE_TERMIOS | |
| - | static int pid_sort (procps_status_t *P, procps_status_t *Q) |
| + | static int pid_sort(procps_status_t *P, procps_status_t *Q) |
| { | |
| return (Q->pid - P->pid); | |
| } | |
| #endif | |
| - | static int mem_sort (procps_status_t *P, procps_status_t *Q) |
| + | static int mem_sort(procps_status_t *P, procps_status_t *Q) |
| { | |
| return (int)(Q->rss - P->rss); | |
| } | |
| @@ -68,12 +68,12 @@ static int mem_sort (procps_status_t *P, procps_status_t *Q) | |
| #define sort_depth 3 | |
| static cmp_t sort_function[sort_depth]; | |
| - | static int pcpu_sort (procps_status_t *P, procps_status_t *Q) |
| + | static int pcpu_sort(procps_status_t *P, procps_status_t *Q) |
| { | |
| return (Q->pcpu - P->pcpu); | |
| } | |
| - | static int time_sort (procps_status_t *P, procps_status_t *Q) |
| + | static int time_sort(procps_status_t *P, procps_status_t *Q) |
| { | |
| return (int)((Q->stime + Q->utime) - (P->stime + P->utime)); | |
| } | |
| @@ -81,7 +81,7 @@ static int time_sort (procps_status_t *P, procps_status_t *Q) | |
| static int mult_lvl_cmp(void* a, void* b) { | |
| int i, cmp_val; | |
| - | for(i = 0; i < sort_depth; i++) { |
| + | for (i = 0; i < sort_depth; i++) { |
| cmp_val = (*sort_function[i])(a, b); | |
| if (cmp_val != 0) | |
| return cmp_val; | |
| @@ -94,199 +94,105 @@ static int mult_lvl_cmp(void* a, void* b) { | |
| struct save_hist { | |
| int ticks; | |
| int pid; | |
| - | int utime; |
| - | int stime; |
| }; | |
| /* | |
| * Calculates percent cpu usage for each task. | |
| */ | |
| - | static struct save_hist *save_history; |
| + | static struct save_hist *prev_hist; |
| + | static int prev_hist_count; |
| + | /* static int hist_iterations; */ |
| - | static unsigned long Hertz; |
| - | /*********************************************************************** |
| - | * Some values in /proc are expressed in units of 1/HZ seconds, where HZ |
| - | * is the kernel clock tick rate. One of these units is called a jiffy. |
| - | * The HZ value used in the kernel may vary according to hacker desire. |
| - | * According to Linus Torvalds, this is not true. He considers the values |
| - | * in /proc as being in architecture-dependent units that have no relation |
| - | * to the kernel clock tick rate. Examination of the kernel source code |
| - | * reveals that opinion as wishful thinking. |
| - | * |
| - | * In any case, we need the HZ constant as used in /proc. (the real HZ value |
| - | * may differ, but we don't care) There are several ways we could get HZ: |
| - | * |
| - | * 1. Include the kernel header file. If it changes, recompile this library. |
| - | * 2. Use the sysconf() function. When HZ changes, recompile the C library! |
| - | * 3. Ask the kernel. This is obviously correct... |
| - | * |
| - | * Linus Torvalds won't let us ask the kernel, because he thinks we should |
| - | * not know the HZ value. Oh well, we don't have to listen to him. |
| - | * Someone smuggled out the HZ value. :-) |
| - | * |
| - | * This code should work fine, even if Linus fixes the kernel to match his |
| - | * stated behavior. The code only fails in case of a partial conversion. |
| - | * |
| - | */ |
| - | |
| - | #define file_to_buf_bufsize 80 |
| - | static inline int file_to_buf(char *buf, const char *filename, int fd) |
| - | { |
| - | int sz; |
| + | static unsigned total_pcpu; |
| + | /* static unsigned long total_rss; */ |
| - | if (fd == -1) { |
| - | fd = open(filename, O_RDONLY); |
| - | if(fd == -1) |
| - | bb_perror_msg_and_die("is /proc mounted?"); |
| - | } else { |
| - | lseek(fd, 0L, SEEK_SET); |
| - | } |
| - | sz = read(fd, buf, file_to_buf_bufsize - 1); |
| - | if (sz < 0) { |
| - | bb_perror_msg_and_die("%s", filename); |
| - | } |
| - | buf[sz] = '\0'; |
| - | return fd; |
| - | } |
| + | struct jiffy_counts { |
| + | unsigned long long usr,nic,sys,idle,iowait,irq,softirq,steal; |
| + | unsigned long long total; |
| + | unsigned long long busy; |
| + | }; |
| + | static struct jiffy_counts jif, prev_jif; |
| - | static void init_Hertz_value(void) |
| + | static void get_jiffy_counts(void) |
| { | |
| - | unsigned long user_j, nice_j, sys_j, other_j; /* jiffies (clock ticks) */ |
| - | double up_1, up_2, seconds; |
| - | unsigned long jiffies, h; |
| - | char buf[80]; |
| - | int uptime_fd = -1; |
| - | int stat_fd = -1; |
| - | |
| - | long smp_num_cpus = sysconf(_SC_NPROCESSORS_CONF); |
| - | |
| - | if(smp_num_cpus<1) smp_num_cpus=1; |
| - | |
| - | do { |
| - | uptime_fd = file_to_buf(buf, "uptime", uptime_fd); |
| - | up_1 = strtod(buf, 0); |
| - | stat_fd = file_to_buf(buf, "stat", stat_fd); |
| - | sscanf(buf, "cpu %lu %lu %lu %lu", &user_j, &nice_j, &sys_j, &other_j); |
| - | uptime_fd = file_to_buf(buf, "uptime", uptime_fd); |
| - | up_2 = strtod(buf, 0); |
| - | } while((long)( (up_2-up_1)*1000.0/up_1 )); /* want under 0.1% error */ |
| - | close(uptime_fd); |
| - | close(stat_fd); |
| - | |
| - | jiffies = user_j + nice_j + sys_j + other_j; |
| - | seconds = (up_1 + up_2) / 2; |
| - | h = (unsigned long)( (double)jiffies/seconds/smp_num_cpus ); |
| - | /* actual values used by 2.4 kernels: 32 64 100 128 1000 1024 1200 */ |
| - | switch(h) { |
| - | case 30 ... 34 : Hertz = 32; break; /* ia64 emulator */ |
| - | case 48 ... 52 : Hertz = 50; break; |
| - | case 58 ... 62 : Hertz = 60; break; |
| - | case 63 ... 65 : Hertz = 64; break; /* StrongARM /Shark */ |
| - | case 95 ... 105 : Hertz = 100; break; /* normal Linux */ |
| - | case 124 ... 132 : Hertz = 128; break; /* MIPS, ARM */ |
| - | case 195 ... 204 : Hertz = 200; break; /* normal << 1 */ |
| - | case 253 ... 260 : Hertz = 256; break; |
| - | case 295 ... 304 : Hertz = 300; break; /* 3 cpus */ |
| - | case 393 ... 408 : Hertz = 400; break; /* normal << 2 */ |
| - | case 495 ... 504 : Hertz = 500; break; /* 5 cpus */ |
| - | case 595 ... 604 : Hertz = 600; break; /* 6 cpus */ |
| - | case 695 ... 704 : Hertz = 700; break; /* 7 cpus */ |
| - | case 790 ... 808 : Hertz = 800; break; /* normal << 3 */ |
| - | case 895 ... 904 : Hertz = 900; break; /* 9 cpus */ |
| - | case 990 ... 1010 : Hertz = 1000; break; /* ARM */ |
| - | case 1015 ... 1035 : Hertz = 1024; break; /* Alpha, ia64 */ |
| - | case 1095 ... 1104 : Hertz = 1100; break; /* 11 cpus */ |
| - | case 1180 ... 1220 : Hertz = 1200; break; /* Alpha */ |
| - | default: |
| - | /* If 32-bit or big-endian (not Alpha or ia64), assume HZ is 100. */ |
| - | Hertz = (sizeof(long)==sizeof(int) || htons(999)==999) ? 100UL : 1024UL; |
| + | FILE* fp = bb_xfopen("stat", "r"); |
| + | prev_jif = jif; |
| + | if (fscanf(fp, "cpu %lld %lld %lld %lld %lld %lld %lld %lld", |
| + | &jif.usr,&jif.nic,&jif.sys,&jif.idle, |
| + | &jif.iowait,&jif.irq,&jif.softirq,&jif.steal) < 4) { |
| + | bb_error_msg_and_die("failed to read 'stat'"); |
| } | |
| + | fclose(fp); |
| + | jif.total = jif.usr + jif.nic + jif.sys + jif.idle |
| + | + jif.iowait + jif.irq + jif.softirq + jif.steal; |
| + | /* procps 2.x does not count iowait as busy time */ |
| + | jif.busy = jif.total - jif.idle - jif.iowait; |
| } | |
| static void do_stats(void) | |
| { | |
| - | struct timeval t; |
| - | static struct timeval oldtime; |
| - | struct timezone timez; |
| - | float elapsed_time; |
| - | |
| procps_status_t *cur; | |
| - | int total_time, i, n; |
| - | static int prev_count; |
| - | int systime, usrtime, pid; |
| - | |
| - | struct save_hist *New_save_hist; |
| + | int pid, total_time, i, last_i, n; |
| + | struct save_hist *new_hist; |
| - | /* |
| - | * Finds the current time (in microseconds) and calculates the time |
| - | * elapsed since the last update. |
| - | */ |
| - | gettimeofday(&t, &timez); |
| - | elapsed_time = (t.tv_sec - oldtime.tv_sec) |
| - | + (float) (t.tv_usec - oldtime.tv_usec) / 1000000.0; |
| - | oldtime.tv_sec = t.tv_sec; |
| - | oldtime.tv_usec = t.tv_usec; |
| - | |
| - | New_save_hist = alloca(sizeof(struct save_hist)*ntop); |
| + | get_jiffy_counts(); |
| + | total_pcpu = 0; |
| + | /* total_rss = 0; */ |
| + | new_hist = xmalloc(sizeof(struct save_hist)*ntop); |
| /* | |
| * Make a pass through the data to get stats. | |
| */ | |
| - | for(n = 0; n < ntop; n++) { |
| + | /* hist_iterations = 0; */ |
| + | i = 0; |
| + | for (n = 0; n < ntop; n++) { |
| cur = top + n; | |
| /* | |
| * Calculate time in cur process. Time is sum of user time | |
| - | * (usrtime) plus system time (systime). |
| + | * and system time |
| */ | |
| - | systime = cur->stime; |
| - | usrtime = cur->utime; |
| pid = cur->pid; | |
| - | total_time = systime + usrtime; |
| - | New_save_hist[n].ticks = total_time; |
| - | New_save_hist[n].pid = pid; |
| - | New_save_hist[n].stime = systime; |
| - | New_save_hist[n].utime = usrtime; |
| + | total_time = cur->stime + cur->utime; |
| + | new_hist[n].ticks = total_time; |
| + | new_hist[n].pid = pid; |
| /* find matching entry from previous pass */ | |
| - | for (i = 0; i < prev_count; i++) { |
| - | if (save_history[i].pid == pid) { |
| - | total_time -= save_history[i].ticks; |
| - | systime -= save_history[i].stime; |
| - | usrtime -= save_history[i].utime; |
| + | cur->pcpu = 0; |
| + | /* do not start at index 0, continue at last used one |
| + | * (brought hist_iterations from ~14000 down to 172) */ |
| + | last_i = i; |
| + | if (prev_hist_count) do { |
| + | if (prev_hist[i].pid == pid) { |
| + | cur->pcpu = total_time - prev_hist[i].ticks; |
| break; | |
| } | |
| - | } |
| - | |
| - | /* |
| - | * Calculate percent cpu time for cur task. |
| - | */ |
| - | i = (total_time * 10 * 100/Hertz) / elapsed_time; |
| - | if (i > 999) |
| - | i = 999; |
| - | cur->pcpu = i; |
| + | i = (i+1) % prev_hist_count; |
| + | /* hist_iterations++; */ |
| + | } while (i != last_i); |
| + | total_pcpu += cur->pcpu; |
| + | /* total_rss += cur->rss; */ |
| } | |
| /* | |
| * Save cur frame's information. | |
| */ | |
| - | free(save_history); |
| - | save_history = memcpy(xmalloc(sizeof(struct save_hist)*n), New_save_hist, |
| - | sizeof(struct save_hist)*n); |
| - | prev_count = n; |
| - | qsort(top, n, sizeof(procps_status_t), (void*)mult_lvl_cmp); |
| + | free(prev_hist); |
| + | prev_hist = new_hist; |
| + | prev_hist_count = ntop; |
| } | |
| #else | |
| static cmp_t sort_function; | |
| #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */ | |
| /* display generic info (meminfo / loadavg) */ | |
| - | static unsigned long display_generic(void) |
| + | static unsigned long display_generic(int scr_width) |
| { | |
| FILE *fp; | |
| char buf[80]; | |
| - | float avg1, avg2, avg3; |
| + | char scrbuf[80]; |
| + | char *end; |
| unsigned long total, used, mfree, shared, buffers, cached; | |
| unsigned int needs_conversion = 1; | |
| @@ -332,11 +238,14 @@ static unsigned long display_generic(void) | |
| } | |
| fclose(fp); | |
| - | /* read load average */ |
| + | /* read load average as a string */ |
| fp = bb_xfopen("loadavg", "r"); | |
| - | if (fscanf(fp, "%f %f %f", &avg1, &avg2, &avg3) != 3) { |
| - | bb_error_msg_and_die("failed to read 'loadavg'"); |
| - | } |
| + | buf[0] = '\0'; |
| + | fgets(buf, sizeof(buf), fp); |
| + | end = strchr(buf, ' '); |
| + | if (end) end = strchr(end+1, ' '); |
| + | if (end) end = strchr(end+1, ' '); |
| + | if (end) *end = '\0'; |
| fclose(fp); | |
| if (needs_conversion) { | |
| @@ -351,59 +260,110 @@ static unsigned long display_generic(void) | |
| /* output memory info and load average */ | |
| /* clear screen & go to top */ | |
| - | printf("\e[H\e[J" "Mem: " |
| - | "%ldK used, %ldK free, %ldK shrd, %ldK buff, %ldK cached\n", |
| + | if (scr_width > sizeof(scrbuf)) |
| + | scr_width = sizeof(scrbuf); |
| + | snprintf(scrbuf, scr_width, |
| + | "Mem: %ldK used, %ldK free, %ldK shrd, %ldK buff, %ldK cached", |
| used, mfree, shared, buffers, cached); | |
| - | printf("Load average: %.2f, %.2f, %.2f " |
| - | "(State: S=sleeping R=running, W=waiting)\n", |
| - | avg1, avg2, avg3); |
| + | printf("\e[H\e[J%s\n", scrbuf); |
| + | snprintf(scrbuf, scr_width, |
| + | "Load average: %s (Status: S=sleeping R=running, W=waiting)", buf); |
| + | printf("%s\n", scrbuf); |
| + | |
| return total; | |
| } | |
| /* display process statuses */ | |
| - | static void display_status(int count, int col) |
| + | static void display_status(int count, int scr_width) |
| { | |
| + | enum { |
| + | bits_per_int = sizeof(int)*8 |
| + | }; |
| + | |
| procps_status_t *s = top; | |
| char rss_str_buf[8]; | |
| - | unsigned long total_memory = display_generic(); |
| + | unsigned long total_memory = display_generic(scr_width); /* or use total_rss? */ |
| + | unsigned pmem_shift, pmem_scale; |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| + | unsigned pcpu_shift, pcpu_scale; |
| + | |
| /* what info of the processes is shown */ | |
| - | printf("\n\e[7m PID USER STATUS RSS PPID %%CPU %%MEM COMMAND\e[0m\n"); |
| + | printf("\e[7m%.*s\e[0m", scr_width, |
| + | " PID USER STATUS RSS PPID %CPU %MEM COMMAND"); |
| + | #define MIN_WIDTH \ |
| + | sizeof( " PID USER STATUS RSS PPID %CPU %MEM C") |
| #else | |
| - | printf("\n\e[7m PID USER STATUS RSS PPID %%MEM COMMAND\e[0m\n"); |
| + | printf("\e[7m%.*s\e[0m", scr_width, |
| + | " PID USER STATUS RSS PPID %MEM COMMAND"); |
| + | #define MIN_WIDTH \ |
| + | sizeof( " PID USER STATUS RSS PPID %MEM C") |
| #endif | |
| - | while (count--) { |
| - | char *namecmd = s->short_cmd; |
| - | int pmem; |
| + | /* |
| + | * MEM% = s->rss/MemTotal |
| + | */ |
| + | pmem_shift = bits_per_int-11; |
| + | pmem_scale = 1000*(1U<<(bits_per_int-11)) / total_memory; |
| + | /* s->rss is in kb. we want (s->rss * pmem_scale) to never overflow */ |
| + | while (pmem_scale >= 512) { |
| + | pmem_scale /= 4; |
| + | pmem_shift -= 2; |
| + | } |
| + | #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
| + | /* |
| + | * CPU% = s->pcpu/sum(s->pcpu) * busy_cpu_ticks/total_cpu_ticks |
| + | * (pcpu is delta of sys+user time between samples) |
| + | */ |
| + | /* (jif.xxx - prev_jif.xxx) and s->pcpu are |
| + | * in 0..~64000 range (HZ*update_interval). |
| + | * we assume that unsigned is at least 32-bit. |
| + | */ |
| + | pcpu_shift = 6; |
| + | pcpu_scale = (1000*64*(uint16_t)(jif.busy-prev_jif.busy) ? : 1); |
| + | while (pcpu_scale < (1U<<(bits_per_int-2))) { |
| + | pcpu_scale *= 4; |
| + | pcpu_shift += 2; |
| + | } |
| + | pcpu_scale /= ( (uint16_t)(jif.total-prev_jif.total)*total_pcpu ? : 1); |
| + | /* we want (s->pcpu * pcpu_scale) to never overflow */ |
| + | while (pcpu_scale >= 1024) { |
| + | pcpu_scale /= 4; |
| + | pcpu_shift -= 2; |
| + | } |
| + | /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */ |
| + | #endif |
| - | pmem = 1000.0 * s->rss / total_memory; |
| - | if (pmem > 999) pmem = 999; |
| + | while (count--) { |
| + | div_t pmem = div( (s->rss*pmem_scale) >> pmem_shift, 10); |
| + | int col = scr_width+1; |
| - | if(s->rss > 10*1024) |
| + | if (s->rss >= 100*1024) |
| sprintf(rss_str_buf, "%6ldM", s->rss/1024); | |
| else | |
| sprintf(rss_str_buf, "%7ld", s->rss); | |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| - | printf("%5d %-8s %s %s %5d %2d.%d %2u.%u ", |
| - | s->pid, s->user, s->state, rss_str_buf, s->ppid, |
| - | s->pcpu/10, s->pcpu%10, pmem/10, pmem%10); |
| + | { |
| + | div_t pcpu = div((s->pcpu*pcpu_scale) >> pcpu_shift, 10); |
| + | col -= printf("\n%5d %-8s %s %s%6d%3u.%c%3u.%c ", |
| + | s->pid, s->user, s->state, rss_str_buf, s->ppid, |
| + | pcpu.quot, '0'+pcpu.rem, pmem.quot, '0'+pmem.rem); |
| + | } |
| #else | |
| - | printf("%5d %-8s %s %s %5d %2u.%u ", |
| + | col -= printf("\n%5d %-8s %s %s%6d%3u.%c ", |
| s->pid, s->user, s->state, rss_str_buf, s->ppid, | |
| - | pmem/10, pmem%10); |
| + | pmem.quot, '0'+pmem.rem);); |
| #endif | |
| - | if((int)strlen(namecmd) > col) |
| - | namecmd[col] = 0; |
| - | printf("%s", namecmd); |
| - | if(count) |
| - | putchar('\n'); |
| - | else |
| - | fflush(stdout); |
| + | if (col>0) |
| + | printf("%.*s", col, s->short_cmd); |
| + | /* printf(" %d/%d %lld/%lld", s->pcpu, total_pcpu, |
| + | jif.busy - prev_jif.busy, jif.total - prev_jif.total); */ |
| s++; | |
| } | |
| + | /* printf(" %d", hist_iterations); */ |
| + | putchar('\r'); |
| + | fflush(stdout); |
| } | |
| static void clearmems(void) | |
| @@ -427,7 +387,7 @@ static void reset_term(void) | |
| #ifdef CONFIG_FEATURE_CLEAN_UP | |
| clearmems(); | |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| - | free(save_history); |
| + | free(prev_hist); |
| #endif | |
| #endif /* CONFIG_FEATURE_CLEAN_UP */ | |
| } | |
| @@ -453,21 +413,13 @@ int top_main(int argc, char **argv) | |
| /* do normal option parsing */ | |
| opt = bb_getopt_ulflags(argc, argv, "d:", &sinterval); | |
| - | if((opt & 1)) { |
| + | if ((opt & 1)) { |
| interval = atoi(sinterval); | |
| } else { | |
| /* Default update rate is 5 seconds */ | |
| interval = 5; | |
| } | |
| - | /* Default to 25 lines - 5 lines for status */ |
| - | lines = 25 - 5; |
| - | /* Default CMD format size */ |
| - | #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
| - | col = 35 - 6; |
| - | #else |
| - | col = 35; |
| - | #endif |
| /* change to /proc */ | |
| bb_xchdir("/proc"); | |
| #ifdef CONFIG_FEATURE_USE_TERMIOS | |
| @@ -477,24 +429,14 @@ int top_main(int argc, char **argv) | |
| /* Turn off echoing */ | |
| new_settings.c_lflag &= ~(ECHO | ECHONL); | |
| - | signal (SIGTERM, sig_catcher); |
| - | sigaction (SIGTERM, (struct sigaction *) 0, &sa); |
| + | signal(SIGTERM, sig_catcher); |
| + | sigaction(SIGTERM, (struct sigaction *) 0, &sa); |
| sa.sa_flags |= SA_RESTART; | |
| sa.sa_flags &= ~SA_INTERRUPT; | |
| - | sigaction (SIGTERM, &sa, (struct sigaction *) 0); |
| - | sigaction (SIGINT, &sa, (struct sigaction *) 0); |
| + | sigaction(SIGTERM, &sa, (struct sigaction *) 0); |
| + | sigaction(SIGINT, &sa, (struct sigaction *) 0); |
| tcsetattr(0, TCSANOW, (void *) &new_settings); | |
| atexit(reset_term); | |
| - | |
| - | get_terminal_width_height(0, &col, &lines); |
| - | if (lines > 4) { |
| - | lines -= 4; |
| - | #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE |
| - | col = col - 80 + 35 - 6; |
| - | #else |
| - | col = col - 80 + 35; |
| - | #endif |
| - | } |
| #endif /* CONFIG_FEATURE_USE_TERMIOS */ | |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| @@ -506,9 +448,21 @@ int top_main(int argc, char **argv) | |
| #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */ | |
| while (1) { | |
| - | /* read process IDs & status for all the processes */ |
| - | procps_status_t * p; |
| + | procps_status_t *p; |
| + | /* Default to 25 lines - 5 lines for status */ |
| + | lines = 24 - 3; |
| + | col = 79; |
| + | #ifdef CONFIG_FEATURE_USE_TERMIOS |
| + | get_terminal_width_height(0, &col, &lines); |
| + | if (lines < 5 || col < MIN_WIDTH) { |
| + | sleep(interval); |
| + | continue; |
| + | } |
| + | lines -= 3; |
| + | #endif /* CONFIG_FEATURE_USE_TERMIOS */ |
| + | |
| + | /* read process IDs & status for all the processes */ |
| while ((p = procps_scan(0)) != 0) { | |
| int n = ntop; | |
| @@ -519,14 +473,14 @@ int top_main(int argc, char **argv) | |
| bb_error_msg_and_die("Can't find process info in /proc"); | |
| } | |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| - | if(!Hertz) { |
| - | init_Hertz_value(); |
| + | if (!prev_hist_count) { |
| do_stats(); | |
| sleep(1); | |
| clearmems(); | |
| continue; | |
| } | |
| do_stats(); | |
| + | qsort(top, ntop, sizeof(procps_status_t), (void*)mult_lvl_cmp); |
| #else | |
| qsort(top, ntop, sizeof(procps_status_t), (void*)sort_function); | |
| #endif /* CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE */ | |
| @@ -539,16 +493,16 @@ int top_main(int argc, char **argv) | |
| #ifdef CONFIG_FEATURE_USE_TERMIOS | |
| tv.tv_sec = interval; | |
| tv.tv_usec = 0; | |
| - | FD_ZERO (&readfds); |
| - | FD_SET (0, &readfds); |
| - | select (1, &readfds, NULL, NULL, &tv); |
| - | if (FD_ISSET (0, &readfds)) { |
| - | if (read (0, &c, 1) <= 0) { /* signal */ |
| + | FD_ZERO(&readfds); |
| + | FD_SET(0, &readfds); |
| + | select(1, &readfds, NULL, NULL, &tv); |
| + | if (FD_ISSET(0, &readfds)) { |
| + | if (read(0, &c, 1) <= 0) { /* signal */ |
| return EXIT_FAILURE; | |
| } | |
| - | if(c == 'q' || c == initial_settings.c_cc[VINTR]) |
| + | if (c == 'q' || c == initial_settings.c_cc[VINTR]) |
| break; | |
| - | if(c == 'M') { |
| + | if (c == 'M') { |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| sort_function[0] = mem_sort; | |
| sort_function[1] = pcpu_sort; | |
| @@ -558,18 +512,18 @@ int top_main(int argc, char **argv) | |
| #endif | |
| } | |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| - | if(c == 'P') { |
| + | if (c == 'P') { |
| sort_function[0] = pcpu_sort; | |
| sort_function[1] = mem_sort; | |
| sort_function[2] = time_sort; | |
| } | |
| - | if(c == 'T') { |
| + | if (c == 'T') { |
| sort_function[0] = time_sort; | |
| sort_function[1] = mem_sort; | |
| sort_function[2] = pcpu_sort; | |
| } | |
| #endif | |
| - | if(c == 'N') { |
| + | if (c == 'N') { |
| #ifdef CONFIG_FEATURE_TOP_CPU_USAGE_PERCENTAGE | |
| sort_function[0] = pid_sort; | |
| #else | |
| @@ -582,7 +536,7 @@ int top_main(int argc, char **argv) | |
| #endif /* CONFIG_FEATURE_USE_TERMIOS */ | |
| clearmems(); | |
| } | |
| - | if(ENABLE_FEATURE_CLEAN_UP) |
| + | if (ENABLE_FEATURE_CLEAN_UP) |
| clearmems(); | |
| putchar('\n'); | |
| return EXIT_SUCCESS; | |