diff options
author | Benoît Dejean <bdejean@src.gnome.org> | 2008-04-21 18:59:25 +0000 |
---|---|---|
committer | Benoît Dejean <bdejean@src.gnome.org> | 2008-04-21 18:59:25 +0000 |
commit | 4d78d26932d129849fda1645e6cb112ec906f384 (patch) | |
tree | 2cce38ec9040314558d967e3c056ea50a6e88e36 /sysdeps | |
parent | cd950bbf73499bc1517af028cdd1f99e09e45151 (diff) | |
download | libgtop-4d78d26932d129849fda1645e6cb112ec906f384.tar.gz |
First try to implement proportional set size by recyling
glibtop_proc_mem's duplicate members.x
Currently implemented on linux in rss member, for now
size,share,resident,rss are the only filled members.
svn path=/trunk/; revision=2740
Diffstat (limited to 'sysdeps')
-rw-r--r-- | sysdeps/linux/procmem.c | 85 |
1 files changed, 68 insertions, 17 deletions
diff --git a/sysdeps/linux/procmem.c b/sysdeps/linux/procmem.c index 18666435..1e1b3b6f 100644 --- a/sysdeps/linux/procmem.c +++ b/sysdeps/linux/procmem.c @@ -27,21 +27,53 @@ #include "glibtop_private.h" static const unsigned long _glibtop_sysdeps_proc_mem = -(1L << GLIBTOP_PROC_MEM_VSIZE) + (1L << GLIBTOP_PROC_MEM_RSS) + -(1L << GLIBTOP_PROC_MEM_RSS_RLIM); - -static const unsigned long _glibtop_sysdeps_proc_mem_statm = (1L << GLIBTOP_PROC_MEM_SIZE) + (1L << GLIBTOP_PROC_MEM_RESIDENT) + (1L << GLIBTOP_PROC_MEM_SHARE); +static const unsigned long _glibtop_sysdeps_proc_mem_pss = +(1L << GLIBTOP_PROC_MEM_RSS); + + +static unsigned long +get_pss(glibtop* server, pid_t pid) +{ + char filepath[128]; + FILE* smaps; + char* line = NULL; + size_t line_size = 0; + unsigned long pss = 0; + + snprintf(filepath, sizeof filepath, "/proc/%u/smaps", (unsigned)pid); + + if (!(smaps = fopen(filepath, "r"))) { + glibtop_error_io_r(server, "Cannot open %s", filepath); + goto out; + } + + while (getline(&line, &line_size, smaps) != -1) { + if (strncmp(line, "Pss:", 4)) + continue; + pss += get_scaled(line + 4, NULL); + } + +out: + if (smaps) + fclose(smaps); + + free(line); + + return pss; +} + /* Init function. */ void _glibtop_init_proc_mem_s (glibtop *server) { - server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem | - _glibtop_sysdeps_proc_mem_statm; + server->sysdeps.proc_mem = _glibtop_sysdeps_proc_mem; + if (server->os_version_code >= LINUX_VERSION_CODE(2, 6, 25)) + server->sysdeps.proc_mem |= _glibtop_sysdeps_proc_mem_pss; } /* Provides detailed information about a process. */ @@ -54,19 +86,34 @@ glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid) memset (buf, 0, sizeof (glibtop_proc_mem)); - if (proc_stat_to_buffer(buffer, sizeof buffer, pid)) - return; + /* As of 2.6.24 in fs/proc/*.c - p = proc_stat_after_cmd (buffer); - if (!p) return; + == rss vs. resident == - p = skip_multiple_token (p, 20); + stat/rss: + get_mm_rss where + #define get_mm_rss(mm) \ + (get_mm_counter(mm, file_rss) + get_mm_counter(mm, anon_rss)) - buf->vsize = strtoull (p, &p, 0); - buf->rss = strtoull (p, &p, 0); - buf->rss_rlim = strtoull (p, &p, 0); + statm/resident: + *shared = get_mm_counter(mm, file_rss); + *resident = *shared + get_mm_counter(mm, anon_rss); - buf->flags = _glibtop_sysdeps_proc_mem; + == vsize vs. size == + + stat/vsize: + task_vsize(mm) ... total_vm * pagesize + + statm/size + mm->total_vm + + ================= + rss == resident + vsize == size + rss_lim is not implemented in statm, but there's limits which + provides all limits + share is only implemented in statm + */ if (proc_statm_to_buffer(buffer, sizeof buffer, pid)) return; @@ -78,7 +125,11 @@ glibtop_get_proc_mem_s (glibtop *server, glibtop_proc_mem *buf, pid_t pid) buf->size *= pagesize; buf->resident *= pagesize; buf->share *= pagesize; - buf->rss *= pagesize; - buf->flags |= _glibtop_sysdeps_proc_mem_statm; + buf->flags |= _glibtop_sysdeps_proc_mem; + + if (server->os_version_code >= LINUX_VERSION_CODE(2, 6, 25)) { + buf->rss = get_pss(server, pid); + buf->flags |= _glibtop_sysdeps_proc_mem_pss; + } } |