]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
parser: Do not scan processes twice
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 15 Aug 2010 16:43:08 +0000 (19:43 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 15 Aug 2010 16:43:08 +0000 (19:43 +0300)
Before we would scan some processes twice: First when we find out the
pages of the interesting processes, then again when we scan the rest
of the processes. This patch changes the handling so that the second
time we ignore all interesting pids that we already scanned.

Signed-off-by: Timo Kokkonen <kaapeli@itanic.dy.fi>
pagemap.h
parse.c

index fae18f01422d14b7c2b3cfd035c8b437ad361b36..27e49188167ff9ae91b99897df3646bd3a69ae56 100644 (file)
--- a/pagemap.h
+++ b/pagemap.h
@@ -67,6 +67,7 @@ struct process {
 #define PARSE_MAP_NAME         0x2
 #define PARSE_PROCESS_NAME     0x4
 #define PARSE_DUMP             0x8
+#define PARSE_NOADD_TREE       0x10
 
 struct parse_opts {
        int parse_mask;
diff --git a/parse.c b/parse.c
index 3934fff77ee58b6e160756d0adeed1d1b45e506b..7f62748a8468c51fbec1c1277c62b77f00829978 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -165,25 +165,51 @@ static char *get_name_by_pid(int pid)
        return bname;
 }
 
-static int check_parse_opts(struct parse_opts *opts, struct pageframe *pf,
-               struct maps *map)
+static int should_scan_process(struct parse_opts *opts, struct process *process)
 {
+       int match = 0;
+       char *name;
+
+       if (opts->parse_mask & PARSE_PROCESS_NAME) {
+               name = get_name_by_pid(process->pid);
+               if (!strcmp(opts->name, name ? name : ""))
+                       match = 1;
+       }
+
        if (opts->parse_mask & PARSE_PID) {
-               if (opts->pid == map->pid)
-                       return 1;
+               if (opts->pid == process->pid)
+                       match = 1;
        }
 
+       if (opts->parse_mask & PARSE_NOADD_TREE)
+               match = !match;
+
+       return match;
+}
+
+static int should_scan_mapping(struct parse_opts *opts, struct maps *map)
+{
+       int match = 0;
+
        if (opts->parse_mask & PARSE_MAP_NAME) {
                if (!strcmp(opts->name, map->name))
-                       return 1;
-       }
+                       match = 1;
 
-       if (opts->parse_mask & PARSE_PROCESS_NAME) {
-               if (!strcmp(opts->name, get_name_by_pid(map->pid)))
-                       return 1;
-       }
+               if (opts->parse_mask & PARSE_NOADD_TREE)
+                       match = !match;
+       } else
+               match = 1;
 
-       return 0;
+       return match;
+}
+
+static int should_add_to_tree(struct parse_opts *opts, struct pageframe *pf,
+               struct maps *map)
+{
+       if (opts->parse_mask & PARSE_NOADD_TREE)
+               return 0;
+
+       return 1;
 }
 
 /* Read data from the /proc/pid/pagemap file */
@@ -205,6 +231,9 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                start = map->start >> (PAGE_SHIFT - 3);
                len = map->size >> (PAGE_SHIFT);
 
+               if (!should_scan_mapping(opts, map))
+                       continue;
+
                ret = fseek(file, start, SEEK_SET);
                if (ret) {
                        error = errno;
@@ -237,7 +266,7 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                                        pageframe->page_present))
                                continue;
 
-                       if (check_parse_opts(opts, pageframe, map)) {
+                       if (should_add_to_tree(opts, pageframe, map)) {
                                match = tree_to_pageframe(
                                        bintree_add(&pf_tree->tree,
                                                &pageframe->tree,
@@ -297,6 +326,8 @@ static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
        process->pid = pid;
        process->tid = tid;
 
+       if (!should_scan_process(opts, process))
+               goto free;
 
        snprintf(path, sizeof(path), "/proc/%d/task/%d/maps", pid, tid);
        file = fopen(path, "rb");
@@ -480,6 +511,9 @@ int scan_all_pids(struct pageframe *pf, struct process **process_list,
        if (opts->parse_mask & PARSE_DUMP)
                return 0;
 
+       /* Do not add new pages in the tree after the initial scan */
+       opts->parse_mask |= PARSE_NOADD_TREE;
+
        while (1) {
                pid = get_next_pid(&dir);
                if (pid <= 0)