]> git.itanic.dy.fi Git - scan-pagemap/commitdiff
Correct the usage of linked lists
authorTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 15 Aug 2010 17:45:57 +0000 (20:45 +0300)
committerTimo Kokkonen <kaapeli@itanic.dy.fi>
Sun, 15 Aug 2010 17:45:57 +0000 (20:45 +0300)
There is really no documentation about how the linked lists in the
lists.h should be used. Specifically, it does not mention the fact
that the head entry of the list should never be used at all. Instead,
the head entry, when being empty, just points to itself.

Now that this fact is clear, a lot of difficult assumptions can be
left out and some overly complicated code can be cleared with the list
handling. This is because the head entry does not have to contain a
valid entry at all.

This also fixes a bug with was caused by the incorrect list handling:
printing the process list always had the head entry missing, since the
list_for_all() functions left the head entry unhandled for purpose.

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

index dda98bb5fd97ce1825355448296e898abcf3a7cc..18e95c49fba977f26928d20f13b155be082abd7c 100644 (file)
--- a/analyze.c
+++ b/analyze.c
@@ -41,14 +41,10 @@ static void count_pages(struct bintree *b, struct bintree_ops *ops)
        struct maps_list *ml;
 
        if (af->pid) {
-               if (!pf->ml)
+               if (list_empty(&pf->ml.list)) {
                        return;
-               if (list_empty(&pf->ml->list)) {
-                       ml = list_to_maps_list(&pf->ml->list);
-                       if (ml->map->pid == af->pid)
-                               goto get_stats;
                }
-               list_for_each_entry(ml, &pf->ml->list, list) {
+               list_for_each_entry(ml, &pf->ml.list, list) {
                        if (ml->map->pid == af->pid)
                                goto get_stats;
                }
diff --git a/main.c b/main.c
index 60efb67602b68502db81e6f7fde55b15c82f588e..c388da647eb19cf2fcf1dc63b96035569fb83e6b 100644 (file)
--- a/main.c
+++ b/main.c
@@ -75,7 +75,7 @@ void read_args(int argc, char *argv[], struct parse_opts *opts)
 int main(int argc, char *argv[])
 {
        struct pageframe pf;
-       struct process *process_list = NULL;
+       struct process process_list;
        struct parse_opts opts;
 
        if (getuid()) {
@@ -93,14 +93,18 @@ int main(int argc, char *argv[])
        }
 
        memset(&pf, 0, sizeof(pf));
+       INIT_LIST_HEAD(&pf.ml.list);
+
+       memset(&process_list, 0, sizeof(process_list));
+       INIT_LIST_HEAD(&process_list.list);
 
        if (scan_all_pids(&pf, &process_list, &opts))
                return 1;
 
        if (opts.parse_mask & PARSE_DUMP)
-               dump_process_maps(process_list);
+               dump_process_maps(&process_list);
        else
-               print_pid_stats(&pf, process_list, &opts);
+               print_pid_stats(&pf, &process_list, &opts);
 
        print_page_stats(&pf);
 
index 27e49188167ff9ae91b99897df3646bd3a69ae56..b06afb69f142755c0e5f2c7239b2fa2b72f6d13f 100644 (file)
--- a/pagemap.h
+++ b/pagemap.h
@@ -19,7 +19,7 @@ struct maps_list {
 
 struct pageframe {
        struct bintree tree;
-       struct maps_list *ml;   /* List to mappings which point to this pfn */
+       struct maps_list ml;    /* List to mappings which point to this pfn */
        unsigned long pfn;      /* page frame number */
        int swap_type;
        int swap_offset;
diff --git a/parse.c b/parse.c
index 7f62748a8468c51fbec1c1277c62b77f00829978..d13d4c70e20973f28e79f5a703dfbbd824a18353 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -91,6 +91,7 @@ static struct pageframe *alloc_pageframe(void)
                goto err;
 
        clear_pageframe(pageframe);
+       INIT_LIST_HEAD(&pageframe->ml.list);
 err:
        return pageframe;
 }
@@ -289,14 +290,9 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                         * Add a link from the physical page to this
                         * process's page map
                         */
-                       if (!match->ml) {
-                               match->ml = alloc_maplist();
-                               match->ml->map = map;
-                       } else {
-                               tmp = alloc_maplist();
-                               tmp->map = map;
-                               list_add(&tmp->list, &match->ml->list);
-                       }
+                       tmp = alloc_maplist();
+                       tmp->map = map;
+                       list_add(&tmp->list, &match->ml.list);
 
                        if (match->page_present)
                                map->pages_present++;
@@ -309,7 +305,7 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
 }
 
 static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
-                       struct process **process_list, struct parse_opts *opts)
+                       struct process *process_list, struct parse_opts *opts)
 {
        struct maps *maps;
        struct process *process;
@@ -320,9 +316,6 @@ static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
        memset(process, 0, sizeof(*process));
        INIT_LIST_HEAD(&process->list);
 
-       if (*process_list == NULL)
-               *process_list = process;
-
        process->pid = pid;
        process->tid = tid;
 
@@ -358,7 +351,7 @@ static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
                }
        }
 
-       list_add_tail(&process->list, &(*process_list)->list);
+       list_add_tail(&process->list, &process_list->list);
 
        return 1;
 free:
@@ -456,7 +449,7 @@ static int get_next_pid_by_name(DIR **dir, char *name)
 
 static int read_pageframe_with_threads(int pid,
                                struct pageframe *pageframe,
-                               struct process **process_list,
+                               struct process *process_list,
                                struct parse_opts *opts)
 {
        DIR *dir = NULL;
@@ -482,7 +475,7 @@ static int read_pageframe_with_threads(int pid,
        return count;
 }
 
-int scan_all_pids(struct pageframe *pf, struct process **process_list,
+int scan_all_pids(struct pageframe *pf, struct process *process_list,
                struct parse_opts *opts)
 {
        DIR *dir = NULL;
diff --git a/parse.h b/parse.h
index af904355f051c1f1f097503c61c54548857fa70c..83d0bcd09bd528ca040a8f9918514f532711e30b 100644 (file)
--- a/parse.h
+++ b/parse.h
@@ -3,7 +3,7 @@
 
 #include "pagemap.h"
 
-int scan_all_pids(struct pageframe *pf, struct process **process_list,
+int scan_all_pids(struct pageframe *pf, struct process *process_list,
                struct parse_opts *opts);
 
 #endif