ps: fix RSS parsing (rss field in /proc/PID/stat is in pages, not bytes)

This commit is contained in:
Denis Vlasenko 2007-08-26 18:23:13 +00:00
parent ec9781d5e4
commit 512499c8ca
2 changed files with 18 additions and 7 deletions

View File

@ -881,12 +881,12 @@ enum { COMM_LEN = TASK_COMM_LEN };
enum { COMM_LEN = 16 }; enum { COMM_LEN = 16 };
#endif #endif
#endif #endif
typedef struct { typedef struct procps_status_t {
DIR *dir; DIR *dir;
uint8_t shift_pages_to_bytes;
uint8_t shift_pages_to_kb;
/* 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 *argv0; char *argv0;
/*char *exe;*/
USE_SELINUX(char *context;) USE_SELINUX(char *context;)
/* Everything below must contain no ptrs to malloc'ed data: /* Everything below must contain no ptrs to malloc'ed data:
* it is memset(0) for each process in procps_scan() */ * it is memset(0) for each process in procps_scan() */

View File

@ -95,8 +95,15 @@ static int read_to_buf(const char *filename, void *buf)
procps_status_t *alloc_procps_scan(int flags) procps_status_t *alloc_procps_scan(int flags)
{ {
unsigned n = getpagesize();
procps_status_t* sp = xzalloc(sizeof(procps_status_t)); procps_status_t* sp = xzalloc(sizeof(procps_status_t));
sp->dir = xopendir("/proc"); sp->dir = xopendir("/proc");
while (1) {
n >>= 1;
if (!n) break;
sp->shift_pages_to_bytes++;
}
sp->shift_pages_to_kb = sp->shift_pages_to_bytes - 10;
return sp; return sp;
} }
@ -229,8 +236,10 @@ procps_status_t *procps_scan(procps_status_t* sp, int flags)
&rss); &rss);
if (n != 10) if (n != 10)
break; break;
sp->vsz = vsz >> 10; /* vsize is in bytes and we want kb */ /* vsz is in bytes and we want kb */
sp->rss = rss >> 10; sp->vsz = vsz >> 10;
/* vsz is in bytes but rss is in *PAGES*! Can you believe that? */
sp->rss = rss << sp->shift_pages_to_kb;
sp->tty_major = (tty >> 8) & 0xfff; sp->tty_major = (tty >> 8) & 0xfff;
sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00); sp->tty_minor = (tty & 0xff) | ((tty >> 12) & 0xfff00);
#else #else
@ -250,8 +259,10 @@ procps_status_t *procps_scan(procps_status_t* sp, int flags)
cp = skip_fields(cp, 3); /* cutime, cstime, priority */ cp = skip_fields(cp, 3); /* cutime, cstime, priority */
tasknice = fast_strtoul_10(&cp); tasknice = fast_strtoul_10(&cp);
cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */ cp = skip_fields(cp, 3); /* timeout, it_real_value, start_time */
sp->vsz = fast_strtoul_10(&cp) >> 10; /* vsize is in bytes and we want kb */ /* vsz is in bytes and we want kb */
sp->rss = fast_strtoul_10(&cp) >> 10; sp->vsz = fast_strtoul_10(&cp) >> 10;
/* vsz is in bytes but rss is in *PAGES*! Can you believe that? */
sp->rss = fast_strtoul_10(&cp) << sp->shift_pages_to_kb;
#endif #endif
if (sp->vsz == 0 && sp->state[0] != 'Z') if (sp->vsz == 0 && sp->state[0] != 'Z')