9 #define SI_M (SI_k * SI_k)
10 #define SI_G (SI_M * SI_k)
12 #define PRETTY_THRESH 100
14 ((a) < SI_k * PRETTY_THRESH ? (a) : \
15 (a < SI_M * PRETTY_THRESH ? ((a) / SI_k) : \
16 (a < SI_G * PRETTY_THRESH ? ((a) / SI_M) : \
19 #define NICE_UNIT(a) \
20 ((a) < (SI_k * PRETTY_THRESH) ? " " : \
21 ((a) < (SI_M * PRETTY_THRESH) ? "k" : \
22 ((a) < (SI_G * PRETTY_THRESH) ? "M" : "G")))
24 #define PAGE_TO_NICE(a) NICE_DIV((long long)a * PAGE_SIZE)
25 #define PAGE_TO_NICE_UNIT(a) NICE_UNIT((long long)a * PAGE_SIZE)
27 struct analyze_frames {
28 struct bintree_ops ops;
29 long int pages_present;
30 long int pages_swapped;
34 #define bintree_ops_to_af(bintree_ops) \
35 container_of((bintree_ops), struct analyze_frames, ops)
37 static void count_pages(struct bintree *b, struct bintree_ops *ops)
39 struct pageframe *pf = tree_to_pageframe(b);
40 struct analyze_frames *af = bintree_ops_to_af(ops);
44 if (list_empty(&pf->ml.list)) {
47 list_for_each_entry(ml, &pf->ml.list, list) {
48 if (ml->map->pid == af->pid)
57 else if (pf->page_swapped)
62 * print_page_stats - Prints system wide page stats
64 void print_page_stats(struct pageframe *pf)
66 struct analyze_frames af;
68 memset(&af, 0, sizeof(af));
70 af.ops.callback = count_pages;
72 count = bintree_walk(&pf->tree, &af.ops);
73 printf("present pages: %ld, %lld %sB\n"
74 "Swapped pages: %ld, %lld %sB\n"
75 "Total %ld physical pages, %lld %sB\n",
77 PAGE_TO_NICE(af.pages_present),
78 PAGE_TO_NICE_UNIT(af.pages_present),
80 PAGE_TO_NICE(af.pages_swapped),
81 PAGE_TO_NICE_UNIT(af.pages_swapped),
84 PAGE_TO_NICE_UNIT(count));
87 void print_pid_stats(struct pageframe *pf, struct process *process_list,
88 struct parse_opts *opts)
90 struct analyze_frames af;
92 long int swapped, present, total;
93 long int biggest = 0, second_biggest;
94 int count, processes = 0;
97 * walk through all processes, find the one with most present
100 list_for_each_entry(ps, &process_list->list, list) {
101 memset(&af, 0, sizeof(af));
102 af.ops.callback = count_pages;
105 bintree_walk(&pf->tree, &af.ops);
106 ps->pages_present = af.pages_present;
107 ps->pages_swapped = af.pages_swapped;
108 biggest = MAX(biggest, ps->pages_present + ps->pages_swapped);
111 printf(" in ram swapped total pid");
112 if (opts->with_threads)
119 list_for_each_entry(ps, &process_list->list, list) {
121 present = ps->pages_present;
122 swapped = ps->pages_swapped;
123 total = present + swapped;
125 second_biggest = (total < biggest) &&
126 (second_biggest < total) ?
127 total : second_biggest;
129 if (total != biggest)
135 printf("%5lld %sB %5lld %sB %5lld %sB %5d ",
136 PAGE_TO_NICE(present), PAGE_TO_NICE_UNIT(present),
137 PAGE_TO_NICE(swapped), PAGE_TO_NICE_UNIT(swapped),
138 PAGE_TO_NICE(total), PAGE_TO_NICE_UNIT(total),
141 if (opts->with_threads)
142 printf("%5d ", ps->tid);
144 printf("%s\n", ps->name);
151 biggest = second_biggest;
155 printf("Total %d processes\n", processes);
158 static void _dump_process_maps(struct process *ps)
161 long int swapped, present, total;
162 long int biggest = 0, second_biggest;
163 int count, processes = 0;
165 list_for_each_entry(map, &ps->maps->list, list) {
166 biggest = MAX(biggest, map->pages_present + map->pages_swapped);
169 printf("process: [%d] %s\n", ps->pid, ps->name);
170 printf(" size in ram swapped total name\n");
174 list_for_each_entry(map, &ps->maps->list, list) {
176 present = map->pages_present;
177 swapped = map->pages_swapped;
178 total = present + swapped;
180 second_biggest = (total < biggest) &&
181 (second_biggest < total) ?
182 total : second_biggest;
184 if (total != biggest)
187 printf("%5lld %sB %5lld %sB %5lld %sB %5lld %sB %s\n",
188 NICE_DIV(map->size), NICE_UNIT(map->size),
189 PAGE_TO_NICE(present), PAGE_TO_NICE_UNIT(present),
190 PAGE_TO_NICE(swapped), PAGE_TO_NICE_UNIT(swapped),
191 PAGE_TO_NICE(total), PAGE_TO_NICE_UNIT(total),
198 if (count > 0 && biggest > 0) {
199 biggest = second_biggest;
205 void dump_process_maps(struct process *process_list)
209 if (list_empty(&process_list->list))
210 _dump_process_maps(process_list);
212 list_for_each_entry(ps, &process_list->list, list) {
213 _dump_process_maps(ps);