]> git.itanic.dy.fi Git - scan-pagemap/blobdiff - parse.c
Replace bintree with rbtree implementation
[scan-pagemap] / parse.c
diff --git a/parse.c b/parse.c
index 97d76aa1889ddf8cdf6fbc70ee40f24de00390b1..371abdb71cbf83fcb553c8f53b911c4aa70acc01 100644 (file)
--- a/parse.c
+++ b/parse.c
@@ -19,8 +19,6 @@
 #include <sys/stat.h>
 #include <stdio.h>
 #include <stdlib.h>
-#include <string.h>
-#include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
 
@@ -107,19 +105,6 @@ err:
        return pageframe;
 }
 
-static int compare_pageframe(struct bintree *at, struct bintree *bt)
-{
-       struct pageframe *a, *b;
-       a = tree_to_pageframe(at);
-       b = tree_to_pageframe(bt);
-
-       return a->pf - b->pf;
-}
-
-struct bintree_ops pageframe_ops = {
-       .compare = compare_pageframe,
-};
-
 static int pid_is_match(int pidn, struct list_head *pidlist)
 {
        struct pidlist *pid;
@@ -182,7 +167,7 @@ static int should_add_to_tree(struct parse_opts *opts, struct pageframe *pf,
 }
 
 /* Read data from the /proc/pid/pagemap file */
-static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
+static int parse_pageframe(FILE *file, struct rb_root *root,
                        struct maps *maps, struct parse_opts *opts)
 {
        struct maps *map;
@@ -190,7 +175,7 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
        struct pageframe *match, *pageframe = NULL;
        long start, len, i;
        unsigned long long pf[10240];
-       int ret, error;
+       int ret;
 
        if (maps == NULL)
                return 0;
@@ -205,9 +190,7 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
 
                ret = fseek(file, start, SEEK_SET);
                if (ret) {
-                       error = errno;
-                       fprintf(stderr, "Error seeking to %lx: %s\n", start,
-                               strerror(error));
+                       fprintf(stderr, "Error seeking to %lx: %m\n", start);
                        continue;
                }
 
@@ -217,7 +200,6 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                                        MIN(sizeof(pf), (len - i) * 8), file);
                        }
                        if (ret < 0) {
-                               error = errno;
                                continue;
                        }
                        if (!pageframe)
@@ -235,17 +217,10 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
                                        page_present(pageframe)))
                                continue;
 
-                       if (should_add_to_tree(opts, pageframe, map)) {
-                               match = tree_to_pageframe(
-                                       bintree_add(&pf_tree->tree,
-                                               &pageframe->tree,
-                                               &pageframe_ops));
-                       } else {
-                               match = tree_to_pageframe(
-                                       bintree_find(&pf_tree->tree,
-                                               &pageframe->tree,
-                                               &pageframe_ops));
-                       }
+                       if (should_add_to_tree(opts, pageframe, map))
+                               match = pf_insert(root, pageframe);
+                       else
+                               match = pf_search(root, pageframe);
 
                        if (match == NULL)
                                continue;
@@ -272,7 +247,7 @@ static int parse_pageframe(FILE *file, struct pageframe *pf_tree,
        return 0;
 }
 
-static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
+static int read_pageframe(int pid, int tid, struct rb_root *root,
                        struct process *process_list, struct parse_opts *opts)
 {
        struct maps *maps;
@@ -306,7 +281,7 @@ static int read_pageframe(int pid, int tid, struct pageframe *pageframe,
        if (!file)
                goto free;
 
-       parse_pageframe(file, pageframe, maps, opts);
+       parse_pageframe(file, root, maps, opts);
        fclose(file);
 
        if (read_cmdline(pid, tid, process->name, sizeof(process->name)))
@@ -344,7 +319,7 @@ free:
 }
 
 static int read_pageframe_with_threads(int pid,
-                               struct pageframe *pageframe,
+                               struct rb_root *root,
                                struct process *process_list,
                                struct parse_opts *opts)
 {
@@ -361,8 +336,7 @@ static int read_pageframe_with_threads(int pid,
                if (tid <= 0)
                        return count;
 
-               count += read_pageframe(pid, tid, pageframe, process_list,
-                                       opts);
+               count += read_pageframe(pid, tid, root, process_list, opts);
 
                if (!opts->with_threads)
                        break;
@@ -371,7 +345,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 rb_root *root, struct process *process_list,
                struct parse_opts *opts)
 {
        struct pidlist *pidlist, *n;
@@ -382,7 +356,7 @@ int scan_all_pids(struct pageframe *pf, struct process *process_list,
 
        if (is_parse_option(opts, PARSE_PID)) {
                list_for_each_entry_safe(pidlist, n, &opts->pidlist, list) {
-                       count += read_pageframe_with_threads(pidlist->pid, pf,
+                       count += read_pageframe_with_threads(pidlist->pid, root,
                                                        process_list, opts);
                }
        }
@@ -409,7 +383,7 @@ int scan_all_pids(struct pageframe *pf, struct process *process_list,
                        len = printf("% 5d", pid);
                        fflush(stdout);
 
-                       read_pageframe_with_threads(pid, pf, process_list,
+                       read_pageframe_with_threads(pid, root, process_list,
                                                opts);
                }
 
@@ -432,7 +406,7 @@ int scan_all_pids(struct pageframe *pf, struct process *process_list,
                len = printf("% 5d", pid);
                fflush(stdout);
 
-               read_pageframe_with_threads(pid, pf, process_list, opts);
+               read_pageframe_with_threads(pid, root, process_list, opts);
        }
        for (i = 0; i < len; i++)
                putchar('\b');
@@ -441,77 +415,57 @@ int scan_all_pids(struct pageframe *pf, struct process *process_list,
        return 0;
 }
 
-struct kpageflag_data {
-       struct bintree_ops ops;
-
+int update_kpageflags(struct rb_root *root)
+{
+       struct pageframe *pf;
        int kpageflags_fd;
        int kpagecount_fd;
-};
+       int ret;
 
-#define bintree_ops_to_kpfd(bintree_ops)                       \
-       container_of((bintree_ops), struct kpageflag_data, ops)
+       kpageflags_fd = open("/proc/kpageflags", O_RDONLY);
+       kpagecount_fd = open("/proc/kpagecount", O_RDONLY);
 
-static void _update_kpageflags(struct bintree *bt, struct bintree_ops *ops)
-{
-       struct pageframe *pf = tree_to_pageframe(bt);
-       struct kpageflag_data *kpfd = bintree_ops_to_kpfd(ops);
-       int ret, error;
-       long int pfnn = pfn(pf) * sizeof(pf->kpageflags);
-
-       ret = lseek(kpfd->kpageflags_fd, pfnn, SEEK_SET);
-       if (ret < 0) {
-               error = errno;
-               fprintf(stderr, "Error seeking to %lx: %s\n",
-                       pfnn, strerror(error));
-               return;
-       }
+       if (kpageflags_fd == -1 || kpagecount_fd == -1)
+               return -1;
 
-       ret = read(kpfd->kpageflags_fd, &pf->kpageflags,
-               sizeof(pf->kpageflags));
-       if (ret < 0) {
-               error = errno;
-               fprintf(stderr, "Error reading from %llx: %s\n",
-                       pf->pf * sizeof(pf->kpageflags),
-                       strerror(error));
-               return;
-       }
+       pf = rb_to_pageframe(rb_first(root));
 
-       ret = lseek(kpfd->kpagecount_fd, pfnn, SEEK_SET);
-       if (ret < 0) {
-               error = errno;
-               fprintf(stderr, "Error seeking to %lx: %s\n",
-                       pfnn, strerror(error));
-               return;
-       }
+       while(pf) {
+               long int pfnn = pfn(pf) * sizeof(pf->kpageflags);
 
-       ret = read(kpfd->kpagecount_fd, &pf->kpagecount,
-               sizeof(pf->kpagecount));
-       if (ret < 0) {
-               error = errno;
-               fprintf(stderr, "Error reading from %llx: %s\n",
-                       pf->pf * sizeof(pf->kpagecount),
-                       strerror(error));
-               return;
-       }
-}
+               ret = lseek(kpageflags_fd, pfnn, SEEK_SET);
+               if (ret < 0) {
+                       fprintf(stderr, "Error seeking to %lx: %m\n", pfnn);
+                       return -1;
+               }
 
-int update_kpageflags(struct pageframe *pf)
-{
-       struct kpageflag_data kpfd = {
-               .ops = {
-                       .callback = _update_kpageflags,
-               },
-               .kpageflags_fd = open("/proc/kpageflags", O_RDONLY),
-               .kpagecount_fd = open("/proc/kpagecount", O_RDONLY),
-       };
-
-       if (kpfd.kpageflags_fd == -1 || kpfd.kpagecount_fd == -1)
-               return -1;
+               ret = read(kpageflags_fd, &pf->kpageflags,
+                       sizeof(pf->kpageflags));
+               if (ret < 0) {
+                       fprintf(stderr, "Error reading from %llx: %m\n",
+                               pf->pf * sizeof(pf->kpageflags));
+                       return -1;
+               }
+
+               ret = lseek(kpagecount_fd, pfnn, SEEK_SET);
+               if (ret < 0) {
+                       fprintf(stderr, "Error seeking to %lx: %m\n", pfnn);
+                       return -1;
+               }
 
-       bintree_walk(&pf->tree, &kpfd.ops);
+               ret = read(kpagecount_fd, &pf->kpagecount,
+                       sizeof(pf->kpagecount));
+               if (ret < 0) {
+                       fprintf(stderr, "Error reading from %llx: %m\n",
+                               pf->pf * sizeof(pf->kpagecount));
+                       return -1;
+               }
+
+               pf = rb_to_pageframe(rb_next(&pf->tree));
+       }
 
-       close(kpfd.kpageflags_fd);
-       close(kpfd.kpagecount_fd);
+       close(kpageflags_fd);
+       close(kpagecount_fd);
 
        return 0;
 }