summaryrefslogtreecommitdiff
path: root/sysdeps/linux
diff options
context:
space:
mode:
authorBenoît Dejean <benoit@placenet.org>2009-05-03 16:25:31 +0200
committerBenoît Dejean <benoit@placenet.org>2009-05-03 16:25:31 +0200
commit62bafe804e2841786d0084454bc649f964991b7e (patch)
tree2a8a93becc5a66e96fc0174ef8ef36ec0df0e78b /sysdeps/linux
parent9f051c9569466b3d08e20a32e6f51df80453a6d3 (diff)
downloadlibgtop-62bafe804e2841786d0084454bc649f964991b7e.tar.gz
Don't use sscanf anymore when parsins smaps.
That's more code but it brings a 20% speed improvement.
Diffstat (limited to 'sysdeps/linux')
-rw-r--r--sysdeps/linux/procmap.c71
1 files changed, 70 insertions, 1 deletions
diff --git a/sysdeps/linux/procmap.c b/sysdeps/linux/procmap.c
index 5762e9f1..40efafca 100644
--- a/sysdeps/linux/procmap.c
+++ b/sysdeps/linux/procmap.c
@@ -141,6 +141,68 @@ parse_smaps(glibtop_map_entry *entry, const char* line)
}
+/*
+ sscanf is too slow
+ and system-monitor calls procmap for each pid every second
+
+ manual parsing is faster
+
+ error checking is weaker
+*/
+
+static gboolean
+parse_line(char* line,
+ guint64* start, guint64* end, char flags[4], guint64* offset,
+ gushort* dev_major, gushort* dev_minor, guint64* inode,
+ char** filename)
+{
+ /* %16llx-%16llx %4c %16llx %02hx:%02hx %llu%*[ ]%n */
+
+ char *p, *next;
+
+ p = line;
+
+ *start = strtoull(p, &p, 16);
+
+ if (G_UNLIKELY(*p != '-'))
+ return FALSE;
+ p++;
+
+ *end = strtoull(p, &p, 16);
+
+ p = next_token(p);
+
+ memcpy(flags, p, 4);
+ p += 4;
+
+ *offset = strtoull(p, &p, 16);
+
+ *dev_major = strtoul(p, &p, 16);
+
+ if (G_UNLIKELY(*p != ':'))
+ return FALSE;
+ p++;
+
+ *dev_minor = strtoul(p, &p, 16);
+
+ *inode = strtoull(p, &p, 10);
+
+ p = next_token(p);
+
+ *filename = p;
+
+ for ( ; *p; p++) {
+ if (*p == '\n') {
+ *p = '\0';
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+
+
glibtop_map_entry *
@@ -181,7 +243,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
{
unsigned long perm;
guint len;
- int line_end;
+ /* int line_end; */
unsigned short dev_major, dev_minor;
guint64 start, end, offset, inode;
@@ -195,6 +257,12 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
new_entry_line:
+ if (!parse_line(line,
+ &start, &end, flags, &offset,
+ &dev_major, &dev_minor, &inode, &filename))
+ continue;
+
+ /*
if (sscanf(line, PROC_MAPS_FORMAT,
&start, &end, flags, &offset,
&dev_major, &dev_minor, &inode, &line_end) != 7)
@@ -202,6 +270,7 @@ glibtop_get_proc_map_s (glibtop *server, glibtop_proc_map *buf, pid_t pid)
filename = line + line_end;
g_strstrip(filename);
+ */
/* Compute access permissions. */
perm = 0;