make sure ps/top output what they claim: vsz, not rss ... down the line we should make the output controllable either at runtime or buildtime as both statistics are quite useful

This commit is contained in:
Mike Frysinger 2007-02-08 08:21:58 +00:00
parent 4423e5beef
commit 0aa6ba5d44
5 changed files with 41 additions and 43 deletions

4
TODO
View File

@ -154,6 +154,10 @@ patch
And while we're at it, a new patch filename quoting format is apparently And while we're at it, a new patch filename quoting format is apparently
coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2 coming soon: http://marc.theaimsgroup.com/?l=git&m=112927316408690&w=2
--- ---
ps / top
Add support for both RSS and VSIZE rather than just one or the other.
Or make it a build option.
---
man man
It would be nice to have a man command. Not one that handles troff or It would be nice to have a man command. Not one that handles troff or
anything, just one that can handle preformatted ascii man pages, possibly anything, just one that can handle preformatted ascii man pages, possibly

View File

@ -668,7 +668,7 @@ typedef struct {
DIR *dir; DIR *dir;
/* Fields are set to 0/NULL if failed to determine (or not requested) */ /* Fields are set to 0/NULL if failed to determine (or not requested) */
char *cmd; char *cmd;
unsigned long rss; unsigned long vsz;
unsigned long stime, utime; unsigned long stime, utime;
unsigned pid; unsigned pid;
unsigned ppid; unsigned ppid;
@ -691,13 +691,13 @@ enum {
PSSCAN_COMM = 1 << 5, PSSCAN_COMM = 1 << 5,
PSSCAN_CMD = 1 << 6, PSSCAN_CMD = 1 << 6,
PSSCAN_STATE = 1 << 7, PSSCAN_STATE = 1 << 7,
PSSCAN_RSS = 1 << 8, PSSCAN_VSZ = 1 << 8,
PSSCAN_STIME = 1 << 9, PSSCAN_STIME = 1 << 9,
PSSCAN_UTIME = 1 << 10, PSSCAN_UTIME = 1 << 10,
/* These are all retrieved from proc/NN/stat in one go: */ /* These are all retrieved from proc/NN/stat in one go: */
PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID PSSCAN_STAT = PSSCAN_PPID | PSSCAN_PGID | PSSCAN_SID
| PSSCAN_COMM | PSSCAN_STATE | PSSCAN_COMM | PSSCAN_STATE
| PSSCAN_RSS | PSSCAN_STIME | PSSCAN_UTIME, | PSSCAN_VSZ | PSSCAN_STIME | PSSCAN_UTIME,
}; };
procps_status_t* alloc_procps_scan(int flags); procps_status_t* alloc_procps_scan(int flags);
void free_procps_scan(procps_status_t* sp); void free_procps_scan(procps_status_t* sp);

View File

@ -127,7 +127,7 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
* ("continue" would mean that current /proc/NNN * ("continue" would mean that current /proc/NNN
* is not a valid process info) */ * is not a valid process info) */
memset(&sp->rss, 0, sizeof(*sp) - offsetof(procps_status_t, rss)); memset(&sp->vsz, 0, sizeof(*sp) - offsetof(procps_status_t, vsz));
sp->pid = pid; sp->pid = pid;
if (!(flags & ~PSSCAN_PID)) break; if (!(flags & ~PSSCAN_PID)) break;
@ -164,17 +164,16 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
"%*s %*s %*s " /* cutime, cstime, priority */ "%*s %*s %*s " /* cutime, cstime, priority */
"%ld " /* nice */ "%ld " /* nice */
"%*s %*s %*s " /* timeout, it_real_value, start_time */ "%*s %*s %*s " /* timeout, it_real_value, start_time */
"%*s " /* vsize */ "%lu ", /* vsize */
"%lu", /* rss */
sp->state, &sp->ppid, sp->state, &sp->ppid,
&sp->pgid, &sp->sid, &sp->pgid, &sp->sid,
&sp->utime, &sp->stime, &sp->utime, &sp->stime,
&tasknice, &tasknice,
&sp->rss); &sp->vsz);
if (n != 8) if (n != 8)
break; break;
if (sp->rss == 0 && sp->state[0] != 'Z') if (sp->vsz == 0 && sp->state[0] != 'Z')
sp->state[1] = 'W'; sp->state[1] = 'W';
else else
sp->state[1] = ' '; sp->state[1] = ' ';
@ -185,11 +184,7 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
else else
sp->state[2] = ' '; sp->state[2] = ' ';
#ifdef PAGE_SHIFT sp->vsz >>= 10; /* vsize is in bytes and we want kb */
sp->rss <<= (PAGE_SHIFT - 10); /* 2**10 = 1kb */
#else
sp->rss *= (getpagesize() >> 10); /* 2**10 = 1kb */
#endif
} }
if (flags & PSSCAN_CMD) { if (flags & PSSCAN_CMD) {
@ -230,7 +225,6 @@ procps_status_t* procps_scan(procps_status_t* sp, int flags)
tty_pgrp, tty_pgrp,
task->flags, task->flags,
min_flt, min_flt,
cmin_flt, cmin_flt,
maj_flt, maj_flt,
cmaj_flt, cmaj_flt,

View File

@ -47,10 +47,10 @@ static void func_pgid(char *buf, int size, const procps_status_t *ps)
snprintf(buf, size+1, "%*u", size, ps->pgid); snprintf(buf, size+1, "%*u", size, ps->pgid);
} }
static void func_rss(char *buf, int size, const procps_status_t *ps) static void func_vsz(char *buf, int size, const procps_status_t *ps)
{ {
char buf5[5]; char buf5[5];
smart_ulltoa5( ((unsigned long long)ps->rss) << 10, buf5); smart_ulltoa5( ((unsigned long long)ps->vsz) << 10, buf5);
snprintf(buf, size+1, "%.*s", size, buf5); snprintf(buf, size+1, "%.*s", size, buf5);
} }
@ -103,9 +103,9 @@ static const ps_out_t out_spec[] = {
// { "ruser" ,"RUSER" ,func_ruser ,PSSCAN_UIDGID,sizeof("RUSER" )-1 }, // { "ruser" ,"RUSER" ,func_ruser ,PSSCAN_UIDGID,sizeof("RUSER" )-1 },
// { "time" ,"TIME" ,func_time ,PSSCAN_ ,sizeof("TIME" )-1 }, // { "time" ,"TIME" ,func_time ,PSSCAN_ ,sizeof("TIME" )-1 },
// { "tty" ,"TT" ,func_tty ,PSSCAN_ ,sizeof("TT" )-1 }, // { "tty" ,"TT" ,func_tty ,PSSCAN_ ,sizeof("TT" )-1 },
// { "vsz" ,"VSZ" ,func_vsz ,PSSCAN_VSZ ,4 }, { "vsz" ,"VSZ" ,func_vsz ,PSSCAN_VSZ ,4 },
// Not mandated by POSIX: // Not mandated by POSIX:
{ "rss" ,"RSS" ,func_rss ,PSSCAN_RSS ,4 }, // { "rss" ,"RSS" ,func_rss ,PSSCAN_RSS ,4 },
}; };
#define VEC_SIZE(v) ( sizeof(v) / sizeof((v)[0]) ) #define VEC_SIZE(v) ( sizeof(v) / sizeof((v)[0]) )
@ -321,13 +321,13 @@ int ps_main(int argc, char **argv)
if (use_selinux) if (use_selinux)
puts(" PID Context Stat Command"); puts(" PID Context Stat Command");
else else
puts(" PID Uid VmSize Stat Command"); puts(" PID Uid VSZ Stat Command");
while ((p = procps_scan(p, 0 while ((p = procps_scan(p, 0
| PSSCAN_PID | PSSCAN_PID
| PSSCAN_UIDGID | PSSCAN_UIDGID
| PSSCAN_STATE | PSSCAN_STATE
| PSSCAN_RSS | PSSCAN_VSZ
| PSSCAN_CMD | PSSCAN_CMD
))) { ))) {
char *namecmd = p->cmd; char *namecmd = p->cmd;
@ -355,12 +355,12 @@ int ps_main(int argc, char **argv)
#endif #endif
{ {
const char *user = get_cached_username(p->uid); const char *user = get_cached_username(p->uid);
if (p->rss == 0) if (p->vsz == 0)
len = printf("%5u %-8s %s ", len = printf("%5u %-8s %s ",
p->pid, user, p->state); p->pid, user, p->state);
else else
len = printf("%5u %-8s %6ld %s ", len = printf("%5u %-8s %6ld %s ",
p->pid, user, p->rss, p->state); p->pid, user, p->vsz, p->state);
} }
i = terminal_width-len; i = terminal_width-len;

View File

@ -32,7 +32,7 @@
typedef struct { typedef struct {
unsigned long rss; unsigned long vsz;
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
unsigned long ticks; unsigned long ticks;
unsigned pcpu; /* delta of ticks */ unsigned pcpu; /* delta of ticks */
@ -55,7 +55,7 @@ static struct save_hist *prev_hist;
static int prev_hist_count; static int prev_hist_count;
/* static int hist_iterations; */ /* static int hist_iterations; */
static unsigned total_pcpu; static unsigned total_pcpu;
/* static unsigned long total_rss; */ /* static unsigned long total_vsz; */
#endif #endif
#define OPT_BATCH_MODE (option_mask32 & 0x4) #define OPT_BATCH_MODE (option_mask32 & 0x4)
@ -72,8 +72,8 @@ static int pid_sort(top_status_t *P, top_status_t *Q)
static int mem_sort(top_status_t *P, top_status_t *Q) static int mem_sort(top_status_t *P, top_status_t *Q)
{ {
/* We want to avoid unsigned->signed and truncation errors */ /* We want to avoid unsigned->signed and truncation errors */
if (Q->rss < P->rss) return -1; if (Q->vsz < P->vsz) return -1;
return Q->rss != P->rss; /* 0 if ==, 1 if > */ return Q->vsz != P->vsz; /* 0 if ==, 1 if > */
} }
@ -147,7 +147,7 @@ static void do_stats(void)
get_jiffy_counts(); get_jiffy_counts();
total_pcpu = 0; total_pcpu = 0;
/* total_rss = 0; */ /* total_vsz = 0; */
new_hist = xmalloc(sizeof(struct save_hist)*ntop); new_hist = xmalloc(sizeof(struct save_hist)*ntop);
/* /*
* Make a pass through the data to get stats. * Make a pass through the data to get stats.
@ -179,7 +179,7 @@ static void do_stats(void)
i = (i+1) % prev_hist_count; i = (i+1) % prev_hist_count;
/* hist_iterations++; */ /* hist_iterations++; */
} while (i != last_i); } while (i != last_i);
/* total_rss += cur->rss; */ /* total_vsz += cur->vsz; */
} }
/* /*
@ -287,8 +287,8 @@ static void display_status(int count, int scr_width)
}; };
top_status_t *s = top; top_status_t *s = top;
char rss_str_buf[8]; char vsz_str_buf[8];
unsigned long total_memory = display_generic(scr_width); /* or use total_rss? */ unsigned long total_memory = display_generic(scr_width); /* or use total_vsz? */
unsigned pmem_shift, pmem_scale; unsigned pmem_shift, pmem_scale;
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
@ -297,22 +297,22 @@ static void display_status(int count, int scr_width)
/* what info of the processes is shown */ /* what info of the processes is shown */
printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width,
" PID USER STATUS RSS PPID %CPU %MEM COMMAND"); " PID USER STATUS VSZ PPID %CPU %MEM COMMAND");
#define MIN_WIDTH \ #define MIN_WIDTH \
sizeof( " PID USER STATUS RSS PPID %CPU %MEM C") sizeof( " PID USER STATUS VSZ PPID %CPU %MEM C")
#else #else
printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width, printf(OPT_BATCH_MODE ? "%.*s" : "\e[7m%.*s\e[0m", scr_width,
" PID USER STATUS RSS PPID %MEM COMMAND"); " PID USER STATUS VSZ PPID %MEM COMMAND");
#define MIN_WIDTH \ #define MIN_WIDTH \
sizeof( " PID USER STATUS RSS PPID %MEM C") sizeof( " PID USER STATUS VSZ PPID %MEM C")
#endif #endif
/* /*
* MEM% = s->rss/MemTotal * MEM% = s->vsz/MemTotal
*/ */
pmem_shift = bits_per_int-11; pmem_shift = bits_per_int-11;
pmem_scale = 1000*(1U<<(bits_per_int-11)) / total_memory; pmem_scale = 1000*(1U<<(bits_per_int-11)) / total_memory;
/* s->rss is in kb. we want (s->rss * pmem_scale) to never overflow */ /* s->vsz is in kb. we want (s->vsz * pmem_scale) to never overflow */
while (pmem_scale >= 512) { while (pmem_scale >= 512) {
pmem_scale /= 4; pmem_scale /= 4;
pmem_shift -= 2; pmem_shift -= 2;
@ -346,14 +346,14 @@ static void display_status(int count, int scr_width)
/* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */ /* printf(" pmem_scale=%u pcpu_scale=%u ", pmem_scale, pcpu_scale); */
#endif #endif
while (count-- > 0) { while (count-- > 0) {
div_t pmem = div((s->rss*pmem_scale) >> pmem_shift, 10); div_t pmem = div((s->vsz*pmem_scale) >> pmem_shift, 10);
int col = scr_width+1; int col = scr_width+1;
USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(div_t pcpu;) USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(div_t pcpu;)
if (s->rss >= 100*1024) if (s->vsz >= 100*1024)
sprintf(rss_str_buf, "%6ldM", s->rss/1024); sprintf(vsz_str_buf, "%6ldM", s->vsz/1024);
else else
sprintf(rss_str_buf, "%7ld", s->rss); sprintf(vsz_str_buf, "%7ld", s->vsz);
USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE( USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(
pcpu = div((s->pcpu*pcpu_scale) >> pcpu_shift, 10); pcpu = div((s->pcpu*pcpu_scale) >> pcpu_shift, 10);
) )
@ -362,7 +362,7 @@ static void display_status(int count, int scr_width)
USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE("%3u.%c") USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE("%3u.%c")
"%3u.%c ", "%3u.%c ",
s->pid, get_cached_username(s->uid), s->state, s->pid, get_cached_username(s->uid), s->state,
rss_str_buf, s->ppid, vsz_str_buf, s->ppid,
USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(pcpu.quot, '0'+pcpu.rem,) USE_FEATURE_TOP_CPU_USAGE_PERCENTAGE(pcpu.quot, '0'+pcpu.rem,)
pmem.quot, '0'+pmem.rem); pmem.quot, '0'+pmem.rem);
if (col > 0) if (col > 0)
@ -474,7 +474,7 @@ int top_main(int argc, char **argv)
while ((p = procps_scan(p, 0 while ((p = procps_scan(p, 0
| PSSCAN_PID | PSSCAN_PID
| PSSCAN_PPID | PSSCAN_PPID
| PSSCAN_RSS | PSSCAN_VSZ
| PSSCAN_STIME | PSSCAN_STIME
| PSSCAN_UTIME | PSSCAN_UTIME
| PSSCAN_STATE | PSSCAN_STATE
@ -486,7 +486,7 @@ int top_main(int argc, char **argv)
top = xrealloc(top, (++ntop)*sizeof(top_status_t)); top = xrealloc(top, (++ntop)*sizeof(top_status_t));
top[n].pid = p->pid; top[n].pid = p->pid;
top[n].ppid = p->ppid; top[n].ppid = p->ppid;
top[n].rss = p->rss; top[n].vsz = p->vsz;
#if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE #if ENABLE_FEATURE_TOP_CPU_USAGE_PERCENTAGE
top[n].ticks = p->stime + p->utime; top[n].ticks = p->stime + p->utime;
#endif #endif