diff options
author | Benoît Dejean <bdejean@src.gnome.org> | 2005-12-12 13:37:15 +0000 |
---|---|---|
committer | Benoît Dejean <bdejean@src.gnome.org> | 2005-12-12 13:37:15 +0000 |
commit | ba7355df9ec7bb5f1df2146d2e1d8009d97eb1f6 (patch) | |
tree | ae66915d225176438e6d55217bf53c57cc41d6f3 /sysdeps/linux | |
parent | 451f9f9d6cd066f792c5600ed8852dddcbb18234 (diff) | |
download | libgtop-ba7355df9ec7bb5f1df2146d2e1d8009d97eb1f6.tar.gz |
Implemented smap support. Closes #320710.
* procmap.c: (add_smaps), (glibtop_get_proc_map_s):
Implemented smap support.
Closes #320710.
Diffstat (limited to 'sysdeps/linux')
-rw-r--r-- | sysdeps/linux/ChangeLog | 7 | ||||
-rw-r--r-- | sysdeps/linux/procmap.c | 84 |
2 files changed, 87 insertions, 4 deletions
diff --git a/sysdeps/linux/ChangeLog b/sysdeps/linux/ChangeLog index 3ff090dc..d75a5161 100644 --- a/sysdeps/linux/ChangeLog +++ b/sysdeps/linux/ChangeLog @@ -1,5 +1,12 @@ 2005-12-12 Benoît Dejean <benoit@placenet.org> + * procmap.c: (add_smaps), (glibtop_get_proc_map_s): + + Implemented smap support. + Closes #320710. + +2005-12-12 Benoît Dejean <benoit@placenet.org> + * proclist.c: (glibtop_get_proclist_s): Improved so that it doesn't stat(2) every /proc/<PID>/. diff --git a/sysdeps/linux/procmap.c b/sysdeps/linux/procmap.c index c6752f2b..5b16d349 100644 --- a/sysdeps/linux/procmap.c +++ b/sysdeps/linux/procmap.c @@ -29,6 +29,13 @@ #include <glibtop/procmap.h> #include <linux/kdev_t.h> +#include <stddef.h> + +#include "glibtop_private.h" + + +#define MAPS_FILE "/proc/%u/maps" +#define SMAPS_FILE "/proc/%u/smaps" #define PROC_MAPS_FORMAT ((sizeof(void*) == 8) \ @@ -46,6 +53,12 @@ static const unsigned long _glibtop_sysdeps_map_entry = (1L << GLIBTOP_MAP_ENTRY_INODE) + (1L << GLIBTOP_MAP_ENTRY_DEVICE) + (1L << GLIBTOP_MAP_ENTRY_FILENAME); +static const unsigned long _glibtop_sysdeps_map_entry_smaps = +(1UL << GLIBTOP_MAP_ENTRY_SIZE) + (1UL << GLIBTOP_MAP_ENTRY_RSS) + +(1UL << GLIBTOP_MAP_ENTRY_SHARED_DIRTY) + (1UL << GLIBTOP_MAP_ENTRY_SHARED_CLEAN) + +(1UL << GLIBTOP_MAP_ENTRY_PRIVATE_DIRTY) + (1UL << GLIBTOP_MAP_ENTRY_PRIVATE_CLEAN); + + /* Init function. */ void @@ -56,6 +69,55 @@ glibtop_init_proc_map_s (glibtop *server) /* Provides detailed information about a process. */ + +static void +add_smaps(glibtop *server, FILE *smaps, glibtop_map_entry *entry) +{ +#define SMAP_OFFSET(MEMBER) offsetof(glibtop_map_entry, MEMBER) + + struct smap_value { + const char *name; + ptrdiff_t offset; + }; + + const struct smap_value values[] = { + { "Size:", SMAP_OFFSET(size) }, + { "Rss:", SMAP_OFFSET(rss) }, + { "Shared_Clean:", SMAP_OFFSET(shared_clean) }, + { "Shared_Dirty:", SMAP_OFFSET(shared_dirty) }, + { "Private_Clean:", SMAP_OFFSET(private_clean) }, + { "Private_Dirty:", SMAP_OFFSET(private_dirty) } + }; + + size_t i; + + for (i = 0; i < G_N_ELEMENTS(values); ++i) { + char line[80]; + char *offset; + guint64 *value; + + if (!fgets(line, sizeof line, smaps)) { + glibtop_warn_io_r(server, + "Could not read smaps value %s", + values[i].name); + return; + } + + offset = (void*) entry; + offset += values[i].offset; + value = (void*) offset; + + *value = get_scaled(line, values[i].name); + } + + entry->flags |= _glibtop_sysdeps_map_entry_smaps; + +#undef SMAP_OFFSET +} + + + + glibtop_map_entry * glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) { @@ -70,12 +132,18 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) sizeof(glibtop_map_entry), 100); FILE *maps; + const char *filename; glibtop_init_s (&server, GLIBTOP_SYSDEPS_PROC_MAP, 0); memset (buf, 0, sizeof (glibtop_proc_map)); - snprintf (procfilename, sizeof procfilename, "/proc/%d/maps", pid); + if (server->os_version_code >= LINUX_VERSION_CODE(2, 6, 0)) + filename = SMAPS_FILE; + else + filename = MAPS_FILE; + + snprintf (procfilename, sizeof procfilename, filename, (unsigned)pid); if((maps = fopen (procfilename, "r")) == NULL) { return (glibtop_map_entry*) g_array_free(entry_list, TRUE); @@ -83,6 +151,8 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) while(TRUE) { + char line[1024]; + unsigned long perm = 0; int rv; guint len; @@ -94,11 +164,13 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) glibtop_map_entry *entry; + if (!fgets(line, sizeof line, maps)) + break; /* 8 arguments */ - rv = fscanf (maps, PROC_MAPS_FORMAT, - &start, &end, flags, &offset, - &dev_major, &dev_minor, &inode, filename); + rv = sscanf(line, PROC_MAPS_FORMAT, + &start, &end, flags, &offset, + &dev_major, &dev_minor, &inode, filename); if(rv == EOF || rv < 7) break; @@ -138,6 +210,10 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid) entry->device = (guint64) MKDEV(dev_major, dev_minor); entry->inode = (guint64) inode; g_strlcpy(entry->filename, filename, sizeof entry->filename); + + if (server->os_version_code >= LINUX_VERSION_CODE(2, 6, 0)) + add_smaps(server, maps, entry); + } fclose (maps); |