diff --git a/NEWS b/NEWS index c62d6e4a..e9ccf804 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ procps-3.1.11 --> procps-3.1.12 +top: new Linux 2.6.0-test4 CPU stats shown top: multiple -p options work again top: fixed 4 GB wrap-around ps: comes with tests diff --git a/proc/sysinfo.c b/proc/sysinfo.c index 02b58a51..4961484d 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -205,6 +205,7 @@ static void init_libproc(void){ old_Hertz_hack(); } +#if 0 /*********************************************************************** * The /proc filesystem calculates idle=jiffies-(user+nice+sys) and we * recover jiffies by adding up the 4 or 5 numbers we are given. SMP kernels @@ -215,19 +216,23 @@ static void init_libproc(void){ #define NAN (-0.0) #endif #define JT unsigned long long -void five_cpu_numbers(double *restrict uret, double *restrict nret, double *restrict sret, double *restrict iret, double *restrict wret){ - double tmp_u, tmp_n, tmp_s, tmp_i, tmp_w; +void seven_cpu_numbers(double *restrict uret, double *restrict nret, double *restrict sret, double *restrict iret, double *restrict wret, double *restrict xret, double *restrict yret){ + double tmp_u, tmp_n, tmp_s, tmp_i, tmp_w, tmp_x, tmp_y; double scale; /* scale values to % */ - static JT old_u, old_n, old_s, old_i, old_w; - JT new_u, new_n, new_s, new_i, new_w; + static JT old_u, old_n, old_s, old_i, old_w, old_x, old_y; + JT new_u, new_n, new_s, new_i, new_w, new_x, new_y; JT ticks_past; /* avoid div-by-0 by not calling too often :-( */ tmp_w = 0.0; new_w = 0; + tmp_x = 0.0; + new_x = 0; + tmp_y = 0.0; + new_y = 0; FILE_TO_BUF(STAT_FILE,stat_fd); - sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i, &new_w); - ticks_past = (new_u+new_n+new_s+new_i+new_w)-(old_u+old_n+old_s+old_i+old_w); + sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i, &new_w, &new_x, &new_y); + ticks_past = (new_u+new_n+new_s+new_i+new_w+new_x+new_y)-(old_u+old_n+old_s+old_i+old_w+old_x+old_y); if(ticks_past){ scale = 100.0 / (double)ticks_past; tmp_u = ( (double)new_u - (double)old_u ) * scale; @@ -235,25 +240,34 @@ void five_cpu_numbers(double *restrict uret, double *restrict nret, double *rest tmp_s = ( (double)new_s - (double)old_s ) * scale; tmp_i = ( (double)new_i - (double)old_i ) * scale; tmp_w = ( (double)new_w - (double)old_w ) * scale; + tmp_x = ( (double)new_x - (double)old_x ) * scale; + tmp_y = ( (double)new_y - (double)old_y ) * scale; }else{ tmp_u = NAN; tmp_n = NAN; tmp_s = NAN; tmp_i = NAN; tmp_w = NAN; + tmp_x = NAN; + tmp_y = NAN; } SET_IF_DESIRED(uret, tmp_u); SET_IF_DESIRED(nret, tmp_n); SET_IF_DESIRED(sret, tmp_s); SET_IF_DESIRED(iret, tmp_i); SET_IF_DESIRED(wret, tmp_w); + SET_IF_DESIRED(iret, tmp_x); + SET_IF_DESIRED(wret, tmp_y); old_u=new_u; old_n=new_n; old_s=new_s; old_i=new_i; old_w=new_w; + old_i=new_x; + old_w=new_y; } #undef JT +#endif /***********************************************************************/ void loadavg(double *restrict av1, double *restrict av5, double *restrict av15) { @@ -327,7 +341,7 @@ static void getrunners(unsigned int *restrict running, unsigned int *restrict bl /***********************************************************************/ -void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, +void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, unsigned long *restrict pin, unsigned long *restrict pout, unsigned long *restrict s_in, unsigned long *restrict sout, unsigned *restrict intr, unsigned *restrict ctxt, unsigned int *restrict running, unsigned int *restrict blocked, @@ -347,9 +361,11 @@ void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff read(fd,buff,BUFFSIZE-1); *intr = 0; *ciow = 0; /* not separated out until the 2.5.41 kernel */ + *cxxx = 0; /* not separated out until the 2.6.0-test4 kernel */ + *cyyy = 0; /* not separated out until the 2.6.0-test4 kernel */ b = strstr(buff, "cpu "); - if(b) sscanf(b, "cpu %Lu %Lu %Lu %Lu %Lu", cuse, cice, csys, cide, ciow); + if(b) sscanf(b, "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu", cuse, cice, csys, cide, ciow, cxxx, cyyy); b = strstr(buff, "page "); if(b) sscanf(b, "page %lu %lu", pin, pout); diff --git a/proc/sysinfo.h b/proc/sysinfo.h index f41237e8..62f4272a 100644 --- a/proc/sysinfo.h +++ b/proc/sysinfo.h @@ -9,9 +9,11 @@ EXTERN_C_BEGIN extern unsigned long long Hertz; /* clock tick frequency */ extern long smp_num_cpus; /* number of CPUs */ +#if 0 #define JT double -extern void five_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *wret); +extern void seven_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *wret, JT *xret, JT *yret); #undef JT +#endif extern int uptime (double *uptime_secs, double *idle_secs); extern void loadavg(double *av1, double *av5, double *av15); @@ -53,7 +55,7 @@ extern unsigned long kb_pagetables; #define BUFFSIZE 8192 typedef unsigned long long jiff; -extern void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, +extern void getstat(jiff *restrict cuse, jiff *restrict cice, jiff *restrict csys, jiff *restrict cide, jiff *restrict ciow, jiff *restrict cxxx, jiff *restrict cyyy, unsigned long *restrict pin, unsigned long *restrict pout, unsigned long *restrict s_in, unsigned long *restrict sout, unsigned *restrict intr, unsigned *restrict ctxt, unsigned int *restrict running, unsigned int *restrict blocked, diff --git a/top.c b/top.c index 89de977a..5428d204 100644 --- a/top.c +++ b/top.c @@ -886,8 +886,10 @@ static CPU_t *cpus_refresh (CPU_t *cpus) // first value the last slot with the cpu summary line if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); + cpus[Cpu_tot].x = 0; // FIXME: can't tell by kernel version number + cpus[Cpu_tot].y = 0; // FIXME: can't tell by kernel version number if (4 > sscanf(buf, CPU_FMTS_JUST1 - , &cpus[Cpu_tot].u, &cpus[Cpu_tot].n, &cpus[Cpu_tot].s, &cpus[Cpu_tot].i, &cpus[Cpu_tot].w)) + , &cpus[Cpu_tot].u, &cpus[Cpu_tot].n, &cpus[Cpu_tot].s, &cpus[Cpu_tot].i, &cpus[Cpu_tot].w, &cpus[Cpu_tot].x, &cpus[Cpu_tot].y)) std_err("failed /proc/stat read"); // and just in case we're 2.2.xx compiled without SMP support... if (1 == Cpu_tot) memcpy(cpus, &cpus[1], sizeof(CPU_t)); @@ -898,8 +900,10 @@ static CPU_t *cpus_refresh (CPU_t *cpus) rewind(fp); #endif if (!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); + cpus[i].x = 0; // FIXME: can't tell by kernel version number + cpus[i].y = 0; // FIXME: can't tell by kernel version number if (4 > sscanf(buf, CPU_FMTS_MULTI - , &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w)) + , &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].w, &cpus[i].x, &cpus[i].y)) std_err("failed /proc/stat read"); } return cpus; @@ -1565,6 +1569,8 @@ static void before (char *me) Cpu_map[i] = i; if (linux_version_code > LINUX_VERSION(2, 5, 41)) States_fmts = STATES_line2x5; + if (linux_version_code >= LINUX_VERSION(2, 6, 0)) // grrr... only some 2.6.0-testX :-( + States_fmts = STATES_line2x6; /* get virtual page size -- nearing huge! */ Page_size = getpagesize(); @@ -1811,7 +1817,7 @@ static void parse_args (char **args) case 'U': do { const char *errmsg; - if (selection_type && /* selection_type != 'U' */) std_err("conflicting process selection"); + if (selection_type /* && selection_type != 'U' */) std_err("conflicting process selection"); if (cp[1]) cp++; else if (*args) cp = *args++; else std_err("-u missing name"); @@ -2766,7 +2772,7 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) /* we'll trim to zero if we get negative time ticks, which has happened with some SMP kernels (pre-2.4?) */ #define TRIMz(x) ((tz = (SIC_t)(x)) < 0 ? 0 : tz) - SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, tot_frme, tz; + SIC_t u_frme, s_frme, n_frme, i_frme, w_frme, x_frme, y_frme, tot_frme, tz; float scale; u_frme = cpu->u - cpu->u_sav; @@ -2774,7 +2780,9 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) n_frme = cpu->n - cpu->n_sav; i_frme = TRIMz(cpu->i - cpu->i_sav); w_frme = cpu->w - cpu->w_sav; - tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme; + x_frme = cpu->x - cpu->x_sav; + y_frme = cpu->y - cpu->y_sav; + tot_frme = u_frme + s_frme + n_frme + i_frme + w_frme + x_frme + y_frme; if (1 > tot_frme) tot_frme = 1; scale = 100.0 / (float)tot_frme; @@ -2786,7 +2794,10 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) , (float)s_frme * scale , (float)n_frme * scale , (float)i_frme * scale - , (float)w_frme * scale)); + , (float)w_frme * scale + , (float)x_frme * scale + , (float)y_frme * scale + )); Msg_row += 1; // remember for next time around @@ -2795,6 +2806,8 @@ static void summaryhlp (CPU_t *cpu, const char *pfx) cpu->n_sav = cpu->n; cpu->i_sav = cpu->i; cpu->w_sav = cpu->w; + cpu->x_sav = cpu->x; + cpu->y_sav = cpu->y; #undef TRIMz } diff --git a/top.h b/top.h index 90f1a7ea..ee1c320e 100644 --- a/top.h +++ b/top.h @@ -188,8 +188,8 @@ typedef struct HST_t { calculations. It exists primarily for SMP support but serves all environments. */ typedef struct CPU_t { - TIC_t u, n, s, i, w; // as represented in /proc/stat - TIC_t u_sav, s_sav, n_sav, i_sav, w_sav; // in the order of our display + TIC_t u, n, s, i, w, x, y; // as represented in /proc/stat + TIC_t u_sav, s_sav, n_sav, i_sav, w_sav, x_sav, y_sav; // in the order of our display } CPU_t; /* These 2 types support rcfile compatibility */ @@ -350,11 +350,11 @@ typedef struct WIN_t { /* These are the possible fscanf formats used in /proc/stat reads during history processing. ( 5th number only for Linux 2.5.41 and above ) */ -#define CPU_FMTS_JUST1 "cpu %Lu %Lu %Lu %Lu %Lu" +#define CPU_FMTS_JUST1 "cpu %Lu %Lu %Lu %Lu %Lu %Lu %Lu" #ifdef PRETEND4CPUS #define CPU_FMTS_MULTI CPU_FMTS_JUST1 #else -#define CPU_FMTS_MULTI "cpu%*d %Lu %Lu %Lu %Lu %Lu" +#define CPU_FMTS_MULTI "cpu%*d %Lu %Lu %Lu %Lu %Lu %Lu %Lu" #endif /* Summary Lines specially formatted string(s) -- @@ -367,6 +367,8 @@ typedef struct WIN_t { " %#5.1f%% \02user,\03 %#5.1f%% \02system,\03 %#5.1f%% \02nice,\03 %#5.1f%% \02idle\03\n" #define STATES_line2x5 "%s\03" \ " %#5.1f%% \02user,\03 %#5.1f%% \02system,\03 %#5.1f%% \02nice,\03 %#5.1f%% \02idle,\03 %#5.1f%% \02IO-wait\03\n" +#define STATES_line2x6 "%s\03" \ + " %#4.1f%% \02us,\03 %#4.1f%% \02sy,\03 %#4.1f%% \02ni,\03 %#4.1f%% \02id,\03 %#4.1f%% \02wa,\03 %#4.1f%% \02hi,\03 %#4.1f%% \02si,\03\n" #ifdef CASEUP_SUMMK #define MEMORY_line1 "Mem: \03" \ " %8uK \02total,\03 %8uK \02used,\03 %8uK \02free,\03 %8uK \02buffers\03\n" @@ -626,4 +628,4 @@ typedef struct WIN_t { // int main (int dont_care_argc, char **argv); #endif /* _Itop */ - + diff --git a/vmstat.c b/vmstat.c index 2f44724b..09d1fa4b 100644 --- a/vmstat.c +++ b/vmstat.c @@ -198,7 +198,7 @@ static void new_format(void) { unsigned int i; unsigned int hz = Hertz; unsigned int running,blocked,dummy_1,dummy_2; - jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2]; + jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2], cpu_xxx[2], cpu_yyy[2]; jiff duse, dsys, didl, diow, Div, divo2; unsigned long pgpgin[2], pgpgout[2], pswpin[2], pswpout[2]; unsigned int intr[2], ctxt[2]; @@ -210,14 +210,14 @@ static void new_format(void) { new_header(); meminfo(); - getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow, + getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow,cpu_xxx,cpu_yyy, pgpgin,pgpgout,pswpin,pswpout, intr,ctxt, &running,&blocked, &dummy_1, &dummy_2); duse= *cpu_use + *cpu_nic; - dsys= *cpu_sys; + dsys= *cpu_sys + *cpu_xxx + *cpu_yyy; didl= *cpu_idl; diow= *cpu_iow; Div= duse+dsys+didl+diow; @@ -246,14 +246,14 @@ static void new_format(void) { meminfo(); - getstat(cpu_use+tog,cpu_nic+tog,cpu_sys+tog,cpu_idl+tog,cpu_iow+tog, + getstat(cpu_use+tog,cpu_nic+tog,cpu_sys+tog,cpu_idl+tog,cpu_iow+tog,cpu_xxx+tog,cpu_yyy+tog, pgpgin+tog,pgpgout+tog,pswpin+tog,pswpout+tog, intr+tog,ctxt+tog, &running,&blocked, &dummy_1,&dummy_2); duse= cpu_use[tog]-cpu_use[!tog] + cpu_nic[tog]-cpu_nic[!tog]; - dsys= cpu_sys[tog]-cpu_sys[!tog]; + dsys= cpu_sys[tog]-cpu_sys[!tog] + cpu_xxx[tog]-cpu_xxx[!tog] + cpu_yyy[tog]-cpu_yyy[!tog]; didl= cpu_idl[tog]-cpu_idl[!tog]; diow= cpu_iow[tog]-cpu_iow[!tog]; @@ -490,13 +490,13 @@ static void disksum_format(void) { static void sum_format(void) { unsigned int running, blocked, btime, processes; - jiff cpu_use, cpu_nic, cpu_sys, cpu_idl, cpu_iow; + jiff cpu_use, cpu_nic, cpu_sys, cpu_idl, cpu_iow, cpu_xxx, cpu_yyy; unsigned long pgpgin, pgpgout, pswpin, pswpout; unsigned int intr, ctxt; meminfo(); - getstat(&cpu_use, &cpu_nic, &cpu_sys, &cpu_idl, &cpu_iow, + getstat(&cpu_use, &cpu_nic, &cpu_sys, &cpu_idl, &cpu_iow, &cpu_xxx, &cpu_yyy, &pgpgin, &pgpgout, &pswpin, &pswpout, &intr, &ctxt, &running, &blocked, @@ -517,6 +517,8 @@ static void sum_format(void) { printf("%13Lu system cpu ticks\n", cpu_sys); printf("%13Lu idle cpu ticks\n", cpu_idl); printf("%13Lu IO-wait cpu ticks\n", cpu_iow); + printf("%13Lu IRQ cpu ticks\n", cpu_xxx); + printf("%13Lu softirq cpu ticks\n", cpu_yyy); printf("%13lu pages paged in\n", pgpgin); printf("%13lu pages paged out\n", pgpgout); printf("%13lu pages swapped in\n", pswpin); @@ -531,11 +533,11 @@ static void sum_format(void) { static void fork_format(void) { unsigned int running, blocked, btime, processes; - jiff cpu_use, cpu_nic, cpu_sys, cpu_idl, cpu_iow; + jiff cpu_use, cpu_nic, cpu_sys, cpu_idl, cpu_iow, cpu_xxx, cpu_yyy; unsigned long pgpgin, pgpgout, pswpin, pswpout; unsigned int intr, ctxt; - getstat(&cpu_use, &cpu_nic, &cpu_sys, &cpu_idl, &cpu_iow, + getstat(&cpu_use, &cpu_nic, &cpu_sys, &cpu_idl, &cpu_iow, &cpu_xxx, &cpu_yyy, &pgpgin, &pgpgout, &pswpin, &pswpout, &intr, &ctxt, &running, &blocked,