Add IRIX mode to process cpu% calculation. For historic reasons top has two different ways of calculation the process cpu% in a multi-cpu system. Add 'IRIX mode' where a single-threaded process in an infinite loop shows 100% and a multi-threaded program can exceed 100%. The default remains 'Solaris mode' (even for -H) where the maximum cpu% for a single thread is 100/num_cpus.
Signed-off-by: David Laight <[email protected]> --- --- b/top.c 2021-11-12 11:25:43.849264597 +0000 +++ c/top.c 2021-11-12 11:36:49.510234350 +0000 @@ -165,6 +165,7 @@ #endif #if ENABLE_FEATURE_TOP_SMP_CPU smallint smp_cpu_info; /* one/many cpu info lines? */ + smallint irix_mode; /* 100% => one cpu busy */ #endif unsigned lines; /* screen height */ #if ENABLE_FEATURE_TOP_INTERACTIVE @@ -201,6 +202,7 @@ #define sort_field (G.sort_field ) #define inverted (G.inverted ) #define smp_cpu_info (G.smp_cpu_info ) +#define irix_mode (G.irix_mode ) #define initial_settings (G.initial_settings ) #define sort_function (G.sort_function ) #define prev_hist (G.prev_hist ) @@ -222,8 +224,9 @@ OPT_n = (1 << 1), OPT_b = (1 << 2), OPT_H = (1 << 3), - OPT_m = (1 << 4), - OPT_EOF = (1 << 5), /* pseudo: "we saw EOF in stdin" */ + OPT_I = (1 << 4), + OPT_m = (1 << 5), + OPT_EOF = (1 << 6), /* pseudo: "we saw EOF in stdin" */ }; #define OPT_BATCH_MODE (option_mask32 & OPT_b) @@ -311,6 +314,13 @@ return; #else if (!smp_cpu_info) { + if (irix_mode && !num_cpus) { + jiffy_counts_t dummy_jif; + while (read_cpu_jiffy(fp, &dummy_jif) >= 4) + num_cpus++; + if (!num_cpus) + irix_mode = 0; + } fclose(fp); return; } @@ -599,6 +609,27 @@ return meminfo[MI_MEMTOTAL]; } +#if ENABLE_FEATURE_TOP_DECIMALS +# define UPSCALE 1000 +# define STAT_BUF(buf_name) char buf_name[8]; +# define SHOW_STAT(name, buf) fmt_proc_pc(name, buf) +# define FMT "%s" +static NOINLINE const char *fmt_proc_pc(unsigned value, char *buf) +{ + if (value >= 1000) + snprintf(buf, 16, "%5u", value/10); + else + snprintf(buf, 16, "%3u.%c", value/10, '0' + (value % 10)); + return buf; +} + +#else +# define UPSCALE 100 +# define STAT_BUF(buf_name) +# define SHOW_STAT(name, buf) name +# define FMT "%4u%%" +#endif + static NOINLINE void display_process_list(int lines_rem, int scr_width) { top_status_t *s; @@ -615,21 +646,13 @@ " COMMAND"); lines_rem--; -#if ENABLE_FEATURE_TOP_DECIMALS -# define UPSCALE 1000 -# define CALC_STAT(name, val) div_t name = div((val), 10) -# define SHOW_STAT(name) name.quot, '0'+name.rem -# define FMT "%3u.%c" -#else -# define UPSCALE 100 -# define CALC_STAT(name, val) unsigned name = (val) -# define SHOW_STAT(name) name -# define FMT "%4u%%" -#endif - #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE /* s->pcpu is in jiffies */ delta_jifs = cur_jif.total - prev_jif.total; +#if ENABLE_FEATURE_TOP_SMP_CPU + if (irix_mode && num_cpus) + delta_jifs /= num_cpus; +#endif #endif /* Ok, all preliminary data is ready, go through the list */ @@ -641,9 +664,11 @@ char vsz_str_buf[8]; unsigned col; - CALC_STAT(pmem, (s->vsz * UPSCALE + total_memory/2) / total_memory); + unsigned pmem = (s->vsz * UPSCALE + total_memory/2) / total_memory; + STAT_BUF(pmem_buf) #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE - CALC_STAT(pcpu, (s->pcpu * UPSCALE + delta_jifs/2) / delta_jifs); + unsigned pcpu = (s->pcpu * UPSCALE + delta_jifs/2) / delta_jifs; + STAT_BUF(pcpu_buf) #endif smart_ulltoa5(s->vsz, vsz_str_buf, " mgtpezy"); @@ -655,9 +680,9 @@ " ", s->pid, s->ppid, get_cached_username(s->uid), s->state, vsz_str_buf, - SHOW_STAT(pmem) + SHOW_STAT(pmem, pmem_buf) IF_FEATURE_TOP_SMP_PROCESS(, s->last_seen_on_cpu) - IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu)) + IF_FEATURE_TOP_CPU_USAGE_PERCENTAGE(, SHOW_STAT(pcpu, pcpu_buf)) ); if ((int)(scr_width - col) > 1) read_cmdline(line_buf + col, scr_width - col, s->pid, s->comm); @@ -983,6 +1008,10 @@ get_jiffy_counts(); continue; } + if (c == 'i') { + irix_mode ^= 1; + continue; + } # endif # endif break; /* unknown key -> force refresh */ @@ -1069,7 +1098,7 @@ /* all args are options; -n NUM */ make_all_argv_opts(argv); /* options can be specified w/o dash */ - col = getopt32(argv, "d:n:bHm", &str_interval, &str_iterations); + col = getopt32(argv, "d:n:bHIm", &str_interval, &str_iterations); /* NB: -m and -H are accepted even if not configured */ #if ENABLE_FEATURE_TOPMEM if (col & OPT_m) /* -m (busybox specific) */ @@ -1094,6 +1123,10 @@ scan_mask |= PSSCAN_TASKS; } #endif +#if ENABLE_FEATURE_TOP_SMP_CPU + if (col & OPT_I) + irix_mode = 1; +#endif /* change to /proc */ xchdir("/proc"); - Registered Address Lakeside, Bramley Road, Mount Farm, Milton Keynes, MK1 1PT, UK Registration No: 1397386 (Wales) _______________________________________________ busybox mailing list [email protected] http://lists.busybox.net/mailman/listinfo/busybox
