#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
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;
}
/* 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;
struct pageframe *match, *pageframe = NULL;
long start, len, i;
unsigned long long pf[10240];
- int ret, error;
+ int ret;
if (maps == NULL)
return 0;
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;
}
MIN(sizeof(pf), (len - i) * 8), file);
}
if (ret < 0) {
- error = errno;
continue;
}
if (!pageframe)
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;
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;
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)))
}
static int read_pageframe_with_threads(int pid,
- struct pageframe *pageframe,
+ struct rb_root *root,
struct process *process_list,
struct parse_opts *opts)
{
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;
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;
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);
}
}
len = printf("% 5d", pid);
fflush(stdout);
- read_pageframe_with_threads(pid, pf, process_list,
+ read_pageframe_with_threads(pid, root, process_list,
opts);
}
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');
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;
}