diff --git a/oldtop.c b/oldtop.c index 2faaf0cf..5593d671 100644 --- a/oldtop.c +++ b/oldtop.c @@ -1303,6 +1303,52 @@ static void show_meminfo(void) } +/*********************************************************************** + * The /proc filesystem calculates idle=jiffies-(user+nice+sys) and we + * recover jiffies by adding up the 4 numbers we are given. SMP kernels + * (as of pre-2.4 era) can report idle time going backwards, perhaps due + * to non-atomic reads and updates. There is no locking for these values. + */ +#ifndef NAN +#define NAN (-0.0) +#endif +#define JT unsigned long long +static void four_cpu_numbers(double *uret, double *nret, double *sret, double *iret){ + double tmp_u, tmp_n, tmp_s, tmp_i; + double scale; /* scale values to % */ + static JT old_u, old_n, old_s, old_i; + JT new_u, new_n, new_s, new_i; + JT ticks_past; /* avoid div-by-0 by not calling too often :-( */ + + FILE_TO_BUF(STAT_FILE,stat_fd); + sscanf(buf, "cpu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i); + ticks_past = (new_u+new_n+new_s+new_i)-(old_u+old_n+old_s+old_i); + if(ticks_past){ + scale = 100.0 / (double)ticks_past; + tmp_u = ( (double)new_u - (double)old_u ) * scale; + tmp_n = ( (double)new_n - (double)old_n ) * scale; + tmp_s = ( (double)new_s - (double)old_s ) * scale; + tmp_i = ( (double)new_i - (double)old_i ) * scale; + }else{ + tmp_u = NAN; + tmp_n = NAN; + tmp_s = NAN; + tmp_i = 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); + old_u=new_u; + old_n=new_n; + old_s=new_s; + old_i=new_i; +} +#undef JT + +/***********************************************************************/ + + /* * Calculates the number of tasks in each state (running, sleeping, etc.). * Calculates the CPU time in each state (system, user, nice, etc). diff --git a/proc/sysinfo.c b/proc/sysinfo.c index 972383f3..be05d5c8 100644 --- a/proc/sysinfo.c +++ b/proc/sysinfo.c @@ -39,6 +39,8 @@ static int uptime_fd = -1; static int loadavg_fd = -1; #define MEMINFO_FILE "/proc/meminfo" static int meminfo_fd = -1; +#define VMINFO_FILE "/proc/vmstat" +static int vminfo_fd = -1; static char buf[1024]; @@ -170,7 +172,7 @@ static void init_Hertz_value(void){ /*********************************************************************** * The /proc filesystem calculates idle=jiffies-(user+nice+sys) and we - * recover jiffies by adding up the 4 numbers we are given. SMP kernels + * recover jiffies by adding up the 4 or 5 numbers we are given. SMP kernels * (as of pre-2.4 era) can report idle time going backwards, perhaps due * to non-atomic reads and updates. There is no locking for these values. */ @@ -178,36 +180,40 @@ static void init_Hertz_value(void){ #define NAN (-0.0) #endif #define JT unsigned long long -void four_cpu_numbers(double *uret, double *nret, double *sret, double *iret){ - double tmp_u, tmp_n, tmp_s, tmp_i; +void five_cpu_numbers(double *uret, double *nret, double *sret, double *iret, double *Iret){ + double tmp_u, tmp_n, tmp_s, tmp_i, tmp_I; double scale; /* scale values to % */ - static JT old_u, old_n, old_s, old_i; - JT new_u, new_n, new_s, new_i; + static JT old_u, old_n, old_s, old_i, old_I; + JT new_u, new_n, new_s, new_i, new_I; JT ticks_past; /* avoid div-by-0 by not calling too often :-( */ FILE_TO_BUF(STAT_FILE,stat_fd); - sscanf(buf, "cpu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i); - ticks_past = (new_u+new_n+new_s+new_i)-(old_u+old_n+old_s+old_i); + sscanf(buf, "cpu %Lu %Lu %Lu %Lu %Lu", &new_u, &new_n, &new_s, &new_i, &new_I); + ticks_past = (new_u+new_n+new_s+new_i+new_I)-(old_u+old_n+old_s+old_i+old_I); if(ticks_past){ scale = 100.0 / (double)ticks_past; tmp_u = ( (double)new_u - (double)old_u ) * scale; tmp_n = ( (double)new_n - (double)old_n ) * scale; tmp_s = ( (double)new_s - (double)old_s ) * scale; tmp_i = ( (double)new_i - (double)old_i ) * scale; + tmp_I = ( (double)new_I - (double)old_I ) * scale; }else{ tmp_u = NAN; tmp_n = NAN; tmp_s = NAN; tmp_i = NAN; + tmp_I = 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(iret, tmp_I); old_u=new_u; old_n=new_n; old_s=new_s; old_i=new_i; + old_i=new_I; } #undef JT @@ -267,6 +273,14 @@ static int compare_mem_table_structs(const void *a, const void *b){ * LowFree: 1436 kB * SwapTotal: 122580 kB old * SwapFree: 60352 kB old + * Inactive: 20420 kB 2.5.41+ + * Dirty: 0 kB 2.5.41+ + * Writeback: 0 kB 2.5.41+ + * Mapped: 9792 kB 2.5.41+ + * Slab: 4564 kB 2.5.41+ + * Committed_AS: 8440 kB 2.5.41+ + * PageTables: 304 kB 2.5.41+ + * ReverseMaps: 5738 2.5.41+ */ /* obsolete */ @@ -292,6 +306,16 @@ unsigned kb_swap_cached; /* late 2.4 only */ /* derived values */ unsigned kb_swap_used; unsigned kb_main_used; +/* 2.5.41+ */ +unsigned kb_writeback; +unsigned kb_slab; +unsigned nr_reversemaps; +unsigned kb_active; +unsigned kb_committed_as; +unsigned kb_dirty; +unsigned kb_inactive; +unsigned kb_mapped; +unsigned kb_pagetables; void meminfo(void){ char namebuf[16]; /* big enough to hold any row name */ @@ -303,24 +327,34 @@ void meminfo(void){ {"Active", &kb_active}, {"Buffers", &kb_main_buffers}, {"Cached", &kb_main_cached}, + {"Committed_AS", &kb_committed_as}, + {"Dirty", &kb_dirty}, {"HighFree", &kb_high_free}, {"HighTotal", &kb_high_total}, {"Inact_clean", &kb_inact_clean}, {"Inact_dirty", &kb_inact_dirty}, {"Inact_target", &kb_inact_target}, + {"Inactive", &kb_inactive}, {"LowFree", &kb_low_free}, {"LowTotal", &kb_low_total}, + {"Mapped", &kb_mapped}, {"MemFree", &kb_main_free}, {"MemShared", &kb_main_shared}, {"MemTotal", &kb_main_total}, + {"PageTables", &kb_pagetables}, + {"ReverseMaps", &nr_reversemaps}, + {"Slab", &kb_slab}, {"SwapCached", &kb_swap_cached}, {"SwapFree", &kb_swap_free}, - {"SwapTotal", &kb_swap_total} + {"SwapTotal", &kb_swap_total}, + {"Writeback", &kb_writeback} }; const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct); FILE_TO_BUF(MEMINFO_FILE,meminfo_fd); + kb_inactive = -1; + head = buf; for(;;){ tail = strchr(head, ':'); @@ -346,6 +380,109 @@ nextline: kb_low_total = kb_main_total; kb_low_free = kb_main_free; } + if(kb_inactive==-1){ + kb_inactive = kb_inact_dirty + kb_inact_clean; + } kb_swap_used = kb_swap_total - kb_swap_free; kb_main_used = kb_main_total - kb_main_free; } + +/*****************************************************************/ + +/* read /proc/vminfo only for 2.5.41 and above */ + +typedef struct vm_table_struct { + const char *name; /* VM statistic name */ + const unsigned *slot; /* slot in return struct */ +} vm_table_struct; + +static int compare_vm_table_structs(const void *a, const void *b){ + return strcmp(((vm_table_struct*)a)->name,((vm_table_struct*)b)->name); +} + +unsigned vm_nr_dirty; +unsigned vm_nr_writeback; +unsigned vm_nr_pagecache; +unsigned vm_nr_page_table_pages; +unsigned vm_nr_reverse_maps; +unsigned vm_nr_mapped; +unsigned vm_nr_slab; +unsigned vm_pgpgin; +unsigned vm_pgpgout; +unsigned vm_pswpin; /* same as 1st num on /proc/stat swap line */ +unsigned vm_pswpout; /* same as 2nd num on /proc/stat swap line */ +unsigned vm_pgalloc; +unsigned vm_pgfree; +unsigned vm_pgactivate; +unsigned vm_pgdeactivate; +unsigned vm_pgfault; +unsigned vm_pgmajfault; +unsigned vm_pgscan; +unsigned vm_pgrefill; +unsigned vm_pgsteal; +unsigned vm_kswapd_steal; +unsigned vm_pageoutrun; +unsigned vm_allocstall; + +void vminfo(void){ + char namebuf[16]; /* big enough to hold any row name */ + vm_table_struct findme = { namebuf, NULL}; + vm_table_struct *found; + char *head; + char *tail; + static const vm_table_struct vm_table[] = { + {"allocstall", &vm_allocstall}, + {"kswapd_steal", &vm_kswapd_steal}, + {"nr_dirty", &vm_nr_dirty}, + {"nr_mapped", &vm_nr_mapped}, + {"nr_page_table_pages", &vm_nr_page_table_pages}, + {"nr_pagecache", &vm_nr_pagecache}, + {"nr_reverse_maps", &vm_nr_reverse_maps}, + {"nr_slab", &vm_nr_slab}, + {"nr_writeback", &vm_nr_writeback}, + {"pageoutrun", &vm_pageoutrun}, + {"pgactivate", &vm_pgactivate}, + {"pgalloc", &vm_pgalloc}, + {"pgdeactivate", &vm_pgdeactivate}, + {"pgfault", &vm_pgfault}, + {"pgfree", &vm_pgfree}, + {"pgmajfault", &vm_pgmajfault}, + {"pgpgin", &vm_pgpgin}, + {"pgpgout", &vm_pgpgout}, + {"pgrefill", &vm_pgrefill}, + {"pgscan", &vm_pgscan}, + {"pgsteal", &vm_pgsteal}, + {"pswpin", &vm_pswpin}, + {"pswpout", &vm_pswpout} + }; + const int vm_table_count = sizeof(vm_table)/sizeof(vm_table_struct); + + FILE_TO_BUF(VMINFO_FILE,vminfo_fd); + + head = buf; + for(;;){ + tail = strchr(head, ' '); + if(!tail) break; + *tail = '\0'; + if(strlen(head) >= sizeof(namebuf)){ + head = tail+1; + goto nextline; + } + strcpy(namebuf,head); + found = bsearch(&findme, vm_table, vm_table_count, + sizeof(vm_table_struct), compare_vm_table_structs + ); + head = tail+1; + if(!found) goto nextline; + *(found->slot) = strtoul(head,&tail,10); +nextline: + +//if(found) fprintf(stderr,"%s=%d\n",found->name,*(found->slot)); +//else fprintf(stderr,"%s not found\n",findme.name); + + tail = strchr(head, '\n'); + if(!tail) break; + head = tail+1; + } +} +/*****************************************************************/ diff --git a/proc/sysinfo.h b/proc/sysinfo.h index c4af4f46..cf701e25 100644 --- a/proc/sysinfo.h +++ b/proc/sysinfo.h @@ -5,7 +5,7 @@ extern unsigned long long Hertz; /* clock tick frequency */ extern long smp_num_cpus; /* number of CPUs */ #define JT double -extern void four_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret); +extern void five_cpu_numbers(JT *uret, JT *nret, JT *sret, JT *iret, JT *Iret); #undef JT extern int uptime (double *uptime_secs, double *idle_secs); @@ -35,7 +35,44 @@ extern unsigned kb_swap_cached; /* late 2.4 only */ /* derived values */ extern unsigned kb_swap_used; extern unsigned kb_main_used; +/* 2.5.41+ */ +extern unsigned kb_writeback; +extern unsigned kb_slab; +extern unsigned nr_reversemaps; +extern unsigned kb_active; +extern unsigned kb_committed_as; +extern unsigned kb_dirty; +extern unsigned kb_inactive; +extern unsigned kb_mapped; +extern unsigned kb_pagetables; extern void meminfo(void); + +extern unsigned vm_nr_dirty; +extern unsigned vm_nr_writeback; +extern unsigned vm_nr_pagecache; +extern unsigned vm_nr_page_table_pages; +extern unsigned vm_nr_reverse_maps; +extern unsigned vm_nr_mapped; +extern unsigned vm_nr_slab; +extern unsigned vm_pgpgin; +extern unsigned vm_pgpgout; +extern unsigned vm_pswpin; +extern unsigned vm_pswpout; +extern unsigned vm_pgalloc; +extern unsigned vm_pgfree; +extern unsigned vm_pgactivate; +extern unsigned vm_pgdeactivate; +extern unsigned vm_pgfault; +extern unsigned vm_pgmajfault; +extern unsigned vm_pgscan; +extern unsigned vm_pgrefill; +extern unsigned vm_pgsteal; +extern unsigned vm_kswapd_steal; +extern unsigned vm_pageoutrun; +extern unsigned vm_allocstall; + +extern void vminfo(void); + #endif /* SYSINFO_H */ diff --git a/top.c b/top.c index f95a9ece..c7d9db71 100644 --- a/top.c +++ b/top.c @@ -812,6 +812,7 @@ static CPUS_t *refreshcpus (CPUS_t *cpus) { static FILE *fp = NULL; int i; + char buf[256]; /* enough for a /proc/stat CPU line (not the intr line) */ /* by opening this file once, we'll avoid the hit on minor page faults (sorry Linux, but you'll have to close it for us) */ @@ -827,19 +828,22 @@ static CPUS_t *refreshcpus (CPUS_t *cpus) fflush(fp); /* first value the last slot with the cpu summary line */ - if (4 != fscanf(fp, CPU_FMTS_JUST1 - , &cpus[Cpu_tot].u, &cpus[Cpu_tot].n, &cpus[Cpu_tot].s, &cpus[Cpu_tot].i)) + if(!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); + 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].I)) std_err("failed /proc/stat read"); /* and now value each separate cpu's tics */ for (i = 0; i < Cpu_tot; i++) { #ifdef PRETEND4CPUS rewind(fp); - if (4 != fscanf(fp, CPU_FMTS_JUST1 + if(!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); + if (4 > sscanf(buf, CPU_FMTS_JUST1 #else - if (4 != fscanf(fp, CPU_FMTS_MULTI + if(!fgets(buf, sizeof(buf), fp)) std_err("failed /proc/stat read"); + if (4 > sscanf(buf, CPU_FMTS_MULTI #endif - , &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i)) + , &cpus[i].u, &cpus[i].n, &cpus[i].s, &cpus[i].i, &cpus[i].I)) std_err("failed /proc/stat read"); } @@ -1692,13 +1696,14 @@ static void cpudo (CPUS_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 = (STIC_t)x) < 0 ? 0 : tz) - STIC_t u_frme, s_frme, n_frme, i_frme, tot_frme, tz; + STIC_t u_frme, s_frme, n_frme, i_frme, I_frme, tot_frme, tz; u_frme = TRIMz(cpu->u - cpu->u_sav); s_frme = TRIMz(cpu->s - cpu->s_sav); n_frme = TRIMz(cpu->n - cpu->n_sav); i_frme = TRIMz(cpu->i - cpu->i_sav); - tot_frme = u_frme + s_frme + n_frme + i_frme; + I_frme = TRIMz(cpu->I - cpu->I_sav); + tot_frme = u_frme + s_frme + n_frme + i_frme + I_frme; if (1 > tot_frme) tot_frme = 1; /* display some kinda' cpu state percentages @@ -1708,7 +1713,8 @@ static void cpudo (CPUS_t *cpu, const char *pfx) , (float)u_frme * 100 / tot_frme , (float)s_frme * 100 / tot_frme , (float)n_frme * 100 / tot_frme - , (float)i_frme * 100 / tot_frme)); + , (float)i_frme * 100 / tot_frme + , (float)I_frme * 100 / tot_frme)); Msg_row += 1; /* remember for next time around */ @@ -1716,6 +1722,7 @@ static void cpudo (CPUS_t *cpu, const char *pfx) cpu->s_sav = cpu->s; cpu->n_sav = cpu->n; cpu->i_sav = cpu->i; + cpu->I_sav = cpu->I; #undef TRIMz } @@ -1807,14 +1814,12 @@ static void frame_states (proc_t **ppt, int show) if (CHKw(Curwin, View_CPUSUM)) { /* display just the 1st /proc/stat line */ - cpudo(&smpcpu[Cpu_tot], "Cpu(s) state:"); + cpudo(&smpcpu[Cpu_tot], "CPU use:"); } else { char tmp[SMLBUFSIZ]; /* display each cpu's states separately */ for (i = 0; i < Cpu_tot; i++) { - sprintf(tmp, "%-6scpu%-2d:" /* [ cpu states as ] */ - , i ? " " : "State" /* 'State cpu0 : ... ' */ - , Mode_irixps ? i : Cpu_map[i]); /* ' cpu1 : ... ' */ + sprintf(tmp, "CPU%4d:", Mode_irixps ? i : Cpu_map[i]); cpudo(&smpcpu[i], tmp); } } diff --git a/top.h b/top.h index eb2d8cbe..5da8171d 100644 --- a/top.h +++ b/top.h @@ -167,11 +167,13 @@ typedef struct { TICS_t u, /* ticks count as represented in /proc/stat */ n, /* (not in the order of our display) */ s, - i; + i, + I; TICS_t u_sav, /* tics count in the order of our display */ s_sav, n_sav, - i_sav; + i_sav, + I_sav; } CPUS_t; /* The scaling 'type' used with scale_num() -- this is how @@ -306,11 +308,11 @@ typedef struct win { reads during history processing. ( 5th number added in anticipation of kernel change ) */ #ifdef TICS_64_BITS -#define CPU_FMTS_JUST1 "cpu %Lu %Lu %Lu %Lu \n" -#define CPU_FMTS_MULTI "cpu%*d %Lu %Lu %Lu %Lu %*d \n" +#define CPU_FMTS_JUST1 "cpu %Lu %Lu %Lu %Lu %Lu" +#define CPU_FMTS_MULTI "cpu%*d %Lu %Lu %Lu %Lu %Lu" #else -#define CPU_FMTS_JUST1 "cpu %lu %lu %lu %lu \n" -#define CPU_FMTS_MULTI "cpu%*d %lu %lu %lu %lu %*d \n" +#define CPU_FMTS_JUST1 "cpu %lu %lu %lu %lu %lu" +#define CPU_FMTS_MULTI "cpu%*d %lu %lu %lu %lu %lu" #endif /* This is the format for 'command line' display in the absence @@ -330,7 +332,7 @@ typedef struct win { " %3u \02stopped,\03 %3u \02zombie\03\n" #define STATES_line2 "%s\03" \ " %#5.1f%% \02user,\03 %#5.1f%% \02system,\03" \ - " %#5.1f%% \02nice,\03 %#5.1f%% \02idle\03\n" + " %#5.1f%% \02nice,\03 %#5.1f%% \02idle,\03 %#5.1f%% \02IO-wait\03\n" #ifdef CASEUP_SUMMK #define MEMORY_line1 "Mem: \03" \ " %8uK \02total,\03 %8uK \02used,\03" \ diff --git a/vmstat.c b/vmstat.c index f9000245..1300bfca 100644 --- a/vmstat.c +++ b/vmstat.c @@ -16,10 +16,6 @@ * Ideally, blocks in & out would be counted in 1k increments, rather than by block: this only makes a difference for CDs and is a problematic fix. */ -/* PROCPS - This is part of the procps package maintained by Michael K. Johnson - ; report bugs to . -*/ #include "proc/sysinfo.h" #include "proc/version.h" @@ -46,6 +42,7 @@ static char buff[BUFFSIZE]; /* used in the procedures */ typedef unsigned long jiff; +static int a_option; /* "-a" means "show active/inactive" */ /****************************************************************/ @@ -54,6 +51,7 @@ static void usage(void) { fprintf(stderr,"usage: %s [-V] [-n] [delay [count]]\n",PROGNAME); fprintf(stderr," -V prints version.\n"); fprintf(stderr," -n causes the headers not to be reprinted regularly.\n"); + fprintf(stderr," -a print inactive/active page stats.\n"); fprintf(stderr," delay is the delay between updates in seconds. \n"); fprintf(stderr," count is the number of updates.\n"); exit(EXIT_FAILURE); @@ -76,14 +74,16 @@ static int winhi(void) { static void showheader(void){ - printf("%8s%28s%8s%12s%11s%12s\n", + printf("%8s%28s%10s%12s%11s%9s\n", "procs","memory","swap","io","system","cpu"); - printf("%2s %2s %2s %6s %6s %6s %6s %3s %3s %5s %5s %4s %5s %3s %3s %3s\n", - "r","b","w","swpd","free","buff","cache","si","so","bi","bo", + printf("%2s %2s %2s %6s %6s %6s %6s %4s %4s %5s %5s %4s %5s %2s %2s %2s\n", + "r","b","w","swpd","free", + a_option?"inact":"buff", a_option?"active":"cache", + "si","so","bi","bo", "in","cs","us","sy","id"); } -static void getstat(jiff *cuse, jiff *cice, jiff *csys, jiff long *cide, +static void getstat(jiff *cuse, jiff *cice, jiff *csys, jiff long *cide, jiff long *ciow, unsigned *pin, unsigned *pout, unsigned *s_in, unsigned *sout, unsigned *itot, unsigned *i1, unsigned *ct) { static int Stat; @@ -95,20 +95,28 @@ static void getstat(jiff *cuse, jiff *cice, jiff *csys, jiff long *cide, close(Stat); *itot = 0; *i1 = 1; /* ensure assert below will fail if the sscanf bombs */ + *ciow = 0; /* not separated out until the 2.5.41 kernel */ b = strstr(buff, "cpu "); - sscanf(b, "cpu %lu %lu %lu %lu", cuse, cice, csys, cide); + if(b) sscanf(b, "cpu %lu %lu %lu %lu %lu", cuse, cice, csys, cide, ciow); b = strstr(buff, "page "); - sscanf(b, "page %u %u", pin, pout); + if(b) sscanf(b, "page %u %u", pin, pout); b = strstr(buff, "swap "); - sscanf(b, "swap %u %u", s_in, sout); + if(b) sscanf(b, "swap %u %u", s_in, sout); b = strstr(buff, "intr "); - sscanf(b, "intr %u %u", itot, i1); + if(b) sscanf(b, "intr %u %u", itot, i1); b = strstr(buff, "ctxt "); - sscanf(b, "ctxt %u", ct); + if(b) sscanf(b, "ctxt %u", ct); } else { crash("/proc/stat"); } + if(1){ + vminfo(); + *pin = vm_pgpgout; + *pout = vm_pgpgin; + *s_in = vm_pswpout; + *sout = vm_pswpin; + } } static void getrunners(unsigned int *running, unsigned int *blocked, @@ -131,7 +139,15 @@ static void getrunners(unsigned int *running, unsigned int *blocked, sprintf(filename, "/proc/%s/stat", ent->d_name); if ((fd = open(filename, O_RDONLY, 0)) != -1) { /*this weeds the rest*/ read(fd,buff,BUFFSIZE-1); - sscanf(buff, "%*d %*s %c %*d %*d %*d %*d %*d %*u %*u %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %*u %u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u\n",&c,&size); + sscanf( + buff, + "%*d %*s %c " + "%*d %*d %*d %*d %*d %*u %*u" + " %*u %*u %*u %*d %*d %*d %*d %*d %*d %*u %*u %*d %*u %u" + /* " %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u %*u\n" */ , + &c, + &size + ); close(fd); if (c=='R') { @@ -159,7 +175,7 @@ static void getrunners(unsigned int *running, unsigned int *blocked, int main(int argc, char *argv[]) { - const char format[]="%2u %2u %2u %6u %6u %6u %6u %3u %3u %5u %5u %4u %5u %3u %3u %3u\n"; + const char format[]="%2u %2u %2u %6u %6u %6u %6u %4u %4u %5u %5u %4u %5u %2u %2u %2u\n"; unsigned int height=22; /* window height, reset later if needed. */ #if 0 unsigned long int args[2]={0,0}; @@ -168,7 +184,7 @@ int main(int argc, char *argv[]) { unsigned int tog=0; /* toggle switch for cleaner code */ unsigned int i,hz; unsigned int running,blocked,swapped; - jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2]; + jiff cpu_use[2], cpu_nic[2], cpu_sys[2], cpu_idl[2], cpu_iow[2]; jiff duse,dsys,didl,Div,divo2; unsigned int pgpgin[2], pgpgout[2], pswpin[2], pswpout[2]; unsigned int inter[2],ticks[2],ctxt[2]; @@ -183,13 +199,17 @@ int main(int argc, char *argv[]) { for (argv++;*argv;argv++) { if ('-' ==(**argv)) { switch (*(++(*argv))) { - case 'V': + case 'V': display_version(); exit(0); + case 'a': + /* active/inactive mode */ + a_option=1; + break; case 'n': /* print only one header */ moreheaders=FALSE; - break; + break; default: /* no other aguments defined yet. */ usage(); @@ -220,18 +240,20 @@ int main(int argc, char *argv[]) { showheader(); getrunners(&running,&blocked,&swapped); meminfo(); - getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl, + getstat(cpu_use,cpu_nic,cpu_sys,cpu_idl,cpu_iow, pgpgin,pgpgout,pswpin,pswpout, inter,ticks,ctxt); duse= *cpu_use + *cpu_nic; - dsys= *cpu_sys; + dsys= *cpu_sys + *cpu_iow; /* ADC -- add IO-wait here? */ didl= *cpu_idl; Div= duse+dsys+didl; - hz=sysconf(_SC_CLK_TCK); /* get ticks/s from system */ + hz=Hertz; /* get ticks/s from libproc */ divo2= Div/2UL; printf(format, running,blocked,swapped, - kb_swap_used,kb_main_free,kb_main_buffers,kb_main_cached, + kb_swap_used,kb_main_free, + a_option?kb_inactive:kb_main_buffers, + a_option?kb_active:kb_main_cached, (*pswpin *kb_per_page*hz+divo2)/Div, (*pswpout*kb_per_page*hz+divo2)/Div, (*pgpgin *hz+divo2)/Div, @@ -249,11 +271,11 @@ int main(int argc, char *argv[]) { tog= !tog; getrunners(&running,&blocked,&swapped); meminfo(); - getstat(cpu_use+tog,cpu_nic+tog,cpu_sys+tog,cpu_idl+tog, + getstat(cpu_use+tog,cpu_nic+tog,cpu_sys+tog,cpu_idl+tog,cpu_iow+tog, pgpgin+tog,pgpgout+tog,pswpin+tog,pswpout+tog, inter+tog,ticks+tog,ctxt+tog); 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_iow[tog]-cpu_iow[!tog]; didl= cpu_idl[tog]-cpu_idl[!tog]; /* idle can run backwards for a moment -- kernel "feature" */ if(cpu_idl[tog]