showslab.c revision e16cb84e2324f05334d18dcf5956f20f44262b62
1e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdlib.h>
2e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <stdio.h>
3e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <string.h>
4e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <unistd.h>
5e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <errno.h>
6e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <ctype.h>
7e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#include <limits.h>
8e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
9e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define STRINGIFY_ARG(a)        #a
10e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define STRINGIFY(a)            STRINGIFY_ARG(a)
11e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
12e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define DEF_SORT_FUNC		sort_nr_objs
13e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define SLABINFO_LINE_LEN	512	/* size of longest line */
14e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define SLABINFO_NAME_LEN	32	/* cache name size (will truncate) */
15e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define SLABINFO_FILE		"/proc/slabinfo"
16e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define DEF_NR_ROWS		15	/* default nr of caches to show */
17e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
18e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* object representing a slab cache (each line of slabinfo) */
19e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct slab_info {
20e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	char name[SLABINFO_NAME_LEN];	/* name of this cache */
21e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_info *next;
22e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_pages;		/* size of cache in pages */
23e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_objs;		/* number of objects in this cache */
24e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_active_objs;	/* number of active objects */
25e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long obj_size;		/* size of each object */
26e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long objs_per_slab;	/* number of objects per slab */
27e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_slabs;		/* number of slabs in this cache */
28e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long use;		/* percent full: total / active */
29e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project};
30e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
31e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/* object representing system-wide statistics */
32e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstruct slab_stat {
33e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long total_size;	/* size of all objects */
34e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long active_size;	/* size of all active objects */
35e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_objs;		/* total number of objects */
36e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_active_objs;	/* total number of active objects */
37e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_slabs;		/* total number of slabs */
38e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_active_slabs;	/* total number of active slabs*/
39e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_caches;	/* number of caches */
40e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long nr_active_caches;	/* number of active caches */
41e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long avg_obj_size;	/* average object size */
42e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long min_obj_size;	/* size of smallest object */
43e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned long max_obj_size;	/* size of largest object */
44e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project};
45e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
46e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projecttypedef int (*sort_t)(const struct slab_info *, const struct slab_info *);
47e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic sort_t sort_func;
48e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
49e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
50e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * get_slabinfo - open, read, and parse a slabinfo 2.x file, which has the
51e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * following format:
52e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
53e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * slabinfo - version: 2.1
54e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * <name>  <active_objs> <num_objs> <objsize> <objperslab> <pagesperslab>
55e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * : tunables <limit> <batchcount> <sharedfactor>
56e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * : slabdata <active_slabs> <num_slabs> <sharedavail>
57e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
58e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Returns the head of the new list of slab_info structures, or NULL on error.
59e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
60e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic struct slab_info * get_slabinfo(struct slab_stat *stats)
61e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
62e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_info *head = NULL, *p = NULL, *prev = NULL;
63e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	FILE *slabfile;
64e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	char line[SLABINFO_LINE_LEN];
65e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned int major, minor;
66e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
67e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	slabfile = fopen(SLABINFO_FILE, "r");
68e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (!slabfile) {
69e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		perror("fopen");
70e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return NULL;
71e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
72e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
73e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (!fgets(line, SLABINFO_LINE_LEN, slabfile)) {
74e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		fprintf(stderr, "cannot read from " SLABINFO_FILE "\n");
75e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return NULL;
76e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
77e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
78e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (sscanf(line, "slabinfo - version: %u.%u", &major, &minor) != 2) {
79e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		fprintf(stderr, "unable to parse slabinfo version!\n");
80e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return NULL;
81e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
82e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
83e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (major != 2 || minor > 1) {
84e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		fprintf(stderr, "we only support slabinfo 2.0 and 2.1!\n");
85e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return NULL;
86e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
87e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
88e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	stats->min_obj_size = INT_MAX;
89e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
90e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	while (fgets(line, SLABINFO_LINE_LEN, slabfile)) {
91e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		unsigned long nr_active_slabs, pages_per_slab;
92e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		int ret;
93e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
94e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (line[0] == '#')
95e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			continue;
96e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
97e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		p = malloc(sizeof (struct slab_info));
98e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (!p) {
99e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			perror("malloc");
100e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			head = NULL;
101e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			break;
102e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		}
103e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (stats->nr_caches++ == 0)
104e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			head = prev = p;
105e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
106e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		ret = sscanf(line, "%" STRINGIFY(SLABINFO_NAME_LEN) "s"
107e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     " %lu %lu %lu %lu %lu : tunables %*d %*d %*d : \
108e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     slabdata %lu %lu %*d", p->name,
109e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     &p->nr_active_objs, &p->nr_objs,
110e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     &p->obj_size, &p->objs_per_slab,
111e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     &pages_per_slab,
112e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     &nr_active_slabs,
113e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			     &p->nr_slabs);
114e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
115e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (ret != 8) {
116e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "unrecognizable data in slabinfo!\n");
117e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			head = NULL;
118e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			break;
119e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		}
120e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
121e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (p->obj_size < stats->min_obj_size)
122e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			stats->min_obj_size = p->obj_size;
123e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (p->obj_size > stats->max_obj_size)
124e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			stats->max_obj_size = p->obj_size;
125e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
126e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		p->nr_pages = p->nr_slabs * pages_per_slab;
127e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
128e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (p->nr_objs) {
129e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			p->use = 100 * p->nr_active_objs / p->nr_objs;
130e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			stats->nr_active_caches++;
131e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		} else
132e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			p->use = 0;
133e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
134e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->nr_objs += p->nr_objs;
135e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->nr_active_objs += p->nr_active_objs;
136e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->total_size += p->nr_objs * p->obj_size;
137e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->active_size += p->nr_active_objs * p->obj_size;
138e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->nr_slabs += p->nr_slabs;
139e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->nr_active_slabs += nr_active_slabs;
140e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
141e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		prev->next = p;
142e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		prev = p;
143e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
144e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
145e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (fclose(slabfile))
146e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		perror("fclose");
147e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
148e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (p)
149e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		p->next = NULL;
150e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (stats->nr_objs)
151e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		stats->avg_obj_size = stats->total_size / stats->nr_objs;
152e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
153e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	return head;
154e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
155e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
156e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
157e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * free_slablist - deallocate the memory associated with each node in the
158e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * provided slab_info linked list
159e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
160e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void free_slablist(struct slab_info *list)
161e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
162e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	while (list) {
163e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		struct slab_info *temp = list->next;
164e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		free(list);
165e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		list = temp;
166e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
167e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
168e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
169e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic struct slab_info *merge_objs(struct slab_info *a, struct slab_info *b)
170e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
171e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_info list;
172e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_info *p = &list;
173e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
174e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	while (a && b) {
175e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (sort_func(a, b)) {
176e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			p->next = a;
177e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			p = a;
178e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			a = a->next;
179e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		} else {
180e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			p->next = b;
181e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			p = b;
182e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			b = b->next;
183e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		}
184e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
185e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
186e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	p->next = (a == NULL) ? b : a;
187e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	return list.next;
188e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
189e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
190e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
191e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * slabsort - merge sort the slab_info linked list based on sort_func
192e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
193e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic struct slab_info *slabsort(struct slab_info *list)
194e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
195e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_info *a, *b;
196e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
197e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (!list || !list->next)
198e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return list;
199e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
200e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	a = list;
201e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	b = list->next;
202e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
203e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	while (b && b->next) {
204e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		list = list->next;
205e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		b = b->next->next;
206e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
207e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
208e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	b = list->next;
209e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	list->next = NULL;
210e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
211e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	return merge_objs(slabsort(a), slabsort(b));
212e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
213e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
214e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
215e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Sort Routines.  Each of these should be associated with a command-line
216e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * search option.  The functions should fit the prototype:
217e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
218e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *	int sort_foo(const struct slab_info *a, const struct slab_info *b)
219e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project *
220e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * They return zero if the first parameter is smaller than the second.
221e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * Otherwise, they return nonzero.
222e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
223e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
224e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic int sort_name(const struct slab_info *a, const struct slab_info *b)
225e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
226e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	return (strcmp(a->name, b->name) < 0 ) ? 1: 0;
227e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
228e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
229e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project#define BUILD_SORT_FUNC(VAL) \
230e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	static int sort_ ## VAL \
231e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		(const struct slab_info *a, const struct slab_info *b) { \
232e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			return (a-> VAL > b-> VAL); }
233e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
234e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(nr_objs)
235e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(nr_active_objs)
236e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(obj_size)
237e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(objs_per_slab)
238e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(nr_slabs)
239e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(use)
240e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source ProjectBUILD_SORT_FUNC(nr_pages)
241e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
242e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project/*
243e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * set_sort_func - return the slab_sort_func that matches the given key.
244e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project * On unrecognizable key, the call returns NULL.
245e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project */
246e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectstatic void * set_sort_func(char key)
247e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
248e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	switch (tolower(key)) {
249e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'a':
250e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_nr_active_objs;
251e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'c':
252e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_nr_pages;
253e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'l':
254e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_nr_slabs;
255e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'n':
256e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_name;
257e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'o':
258e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_nr_objs;
259e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'p':
260e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_objs_per_slab;
261e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 's':
262e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_obj_size;
263e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	case 'u':
264e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return sort_use;
265e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	default:
266e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		return NULL;
267e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
268e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
269e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
270e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Projectint main(int argc, char *argv[])
271e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project{
272e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_info *list, *p;
273e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	struct slab_stat stats = { .nr_objs = 0 };
274e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	unsigned int page_size = getpagesize() / 1024, nr_rows = DEF_NR_ROWS, i;
275e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
276e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	sort_func = DEF_SORT_FUNC;
277e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
278e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (argc > 1) {
279e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		/* FIXME: Ugh. */
280e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		if (argc == 3 && !strcmp(argv[1], "-n")) {
281e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			errno = 0;
282e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			nr_rows = (unsigned int) strtoul(argv[2], NULL, 0);
283e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			if (errno) {
284e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project				perror("strtoul");
285e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project				exit(EXIT_FAILURE);
286e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			}
287e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		}
288e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		else if (argc == 3 && !strcmp(argv[1], "-s"))
289e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			sort_func = set_sort_func(argv[2][0]) ? : DEF_SORT_FUNC;
290e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		else {
291e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "usage: %s [options]\n\n", argv[0]);
292e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "options:\n");
293e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  -s S   specify sort criteria S\n");
294e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  -h     display this help\n\n");
295e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "Valid sort criteria:\n");
296e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  a: number of Active objects\n");
297e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  c: Cache size\n");
298e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  l: number of sLabs\n");
299e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  n: Name\n");
300e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  o: number of Objects\n");
301e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  p: objects Per slab\n");
302e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  s: object Size\n");
303e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			fprintf(stderr, "  u: cache Utilization\n");
304e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project			exit(EXIT_FAILURE);
305e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		}
306e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
307e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
308e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	list = get_slabinfo (&stats);
309e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	if (!list)
310e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		exit(EXIT_FAILURE);
311e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
312e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	printf(" Active / Total Objects (%% used) : %lu / %lu (%.1f%%)\n"
313e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       " Active / Total Slabs (%% used)   : %lu / %lu (%.1f%%)\n"
314e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       " Active / Total Caches (%% used)  : %lu / %lu (%.1f%%)\n"
315e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       " Active / Total Size (%% used)    : %.2fK / %.2fK (%.1f%%)\n"
316e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       " Min / Avg / Max Object Size     : %.2fK / %.2fK / %.2fK\n\n",
317e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.nr_active_objs,
318e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.nr_objs,
319e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       100.0 * stats.nr_active_objs / stats.nr_objs,
320e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.nr_active_slabs,
321e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.nr_slabs,
322e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       100.0 * stats.nr_active_slabs / stats.nr_slabs,
323e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.nr_active_caches,
324e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.nr_caches,
325e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       100.0 * stats.nr_active_caches / stats.nr_caches,
326e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.active_size / 1024.0,
327e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.total_size / 1024.0,
328e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       100.0 * stats.active_size / stats.total_size,
329e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.min_obj_size / 1024.0,
330e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.avg_obj_size / 1024.0,
331e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       stats.max_obj_size / 1024.0);
332e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
333e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	printf("%6s %6s %4s %8s %6s %8s %10s %-23s\n",
334e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       "OBJS", "ACTIVE", "USE", "OBJ SIZE", "SLABS",
335e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	       "OBJ/SLAB", "CACHE SIZE", "NAME");
336e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
337e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	p = list = slabsort(list);
338e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	for (i = 0; i < nr_rows && p; i++) {
339e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		printf("%6lu %6lu %3lu%% %7.2fK %6lu %8lu %9luK %-23s\n",
340e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		       p->nr_objs, p->nr_active_objs, p->use,
341e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		       p->obj_size / 1024.0, p->nr_slabs,
342e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		       p->objs_per_slab,
343e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		       p->nr_pages * page_size,
344e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		       p->name);
345e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project		p = p->next;
346e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	}
347e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
348e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	free_slablist(list);
349e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project
350e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project	return 0;
351e16cb84e2324f05334d18dcf5956f20f44262b62The Android Open Source Project}
352