From 656536799a3c2ce6557175a4dd017b3c1bc7a0c1 Mon Sep 17 00:00:00 2001 From: Timo Kokkonen Date: Sun, 15 Aug 2010 20:45:57 +0300 Subject: [PATCH] Correct the usage of linked lists 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 --- analyze.c | 8 ++------ main.c | 10 +++++++--- pagemap.h | 2 +- parse.c | 23 ++++++++--------------- parse.h | 2 +- 5 files changed, 19 insertions(+), 26 deletions(-) diff --git a/analyze.c b/analyze.c index dda98bb..18e95c4 100644 --- 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 60efb67..c388da6 100644 --- 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); diff --git a/pagemap.h b/pagemap.h index 27e4918..b06afb6 100644 --- 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 7f62748..d13d4c7 100644 --- 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 af90435..83d0bcd 100644 --- 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 -- 2.44.0