slabtop: new usage & fix coding style

Coding style fixed and more readable help output.

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2011-06-04 18:58:25 +02:00
parent 4f7b9c661b
commit 61db37d48f

137
slabtop.c
View File

@ -24,12 +24,12 @@
#include <sys/time.h> #include <sys/time.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include <err.h>
#include "proc/slab.h" #include "proc/slab.h"
#include "proc/version.h" #include "proc/version.h"
#define DEF_SORT_FUNC sort_nr_objs #define DEF_SORT_FUNC sort_nr_objs
#define SLAB_STAT_ZERO { nr_objs: 0 }
static unsigned short cols, rows; static unsigned short cols, rows;
static struct termios saved_tty; static struct termios saved_tty;
@ -149,12 +149,11 @@ static int sort_cache_size(const struct slab_info *a, const struct slab_info *b)
/* /*
* term_size - set the globals 'cols' and 'rows' to the current terminal size * term_size - set the globals 'cols' and 'rows' to the current terminal size
*/ */
static void term_size(int unused) static void term_size(int unusused __attribute__ ((__unused__)))
{ {
struct winsize ws; struct winsize ws;
(void) unused;
if ((ioctl(1, TIOCGWINSZ, &ws) != -1) && ws.ws_row > 10) { if ((ioctl(STDOUT_FILENO, TIOCGWINSZ, &ws) != -1) && ws.ws_row > 10) {
cols = ws.ws_col; cols = ws.ws_col;
rows = ws.ws_row; rows = ws.ws_row;
} else { } else {
@ -163,37 +162,34 @@ static void term_size(int unused)
} }
} }
static void sigint_handler(int unused) static void sigint_handler(int unused __attribute__ ((__unused__)))
{ {
(void) unused;
delay = 0; delay = 0;
} }
static void usage(const char *cmd) static void __attribute__((__noreturn__)) usage(FILE *out)
{ {
fprintf(stderr, "usage: %s [options]\n\n", cmd); fprintf(out, "Usage: %s [options]\n\n", program_invocation_short_name);
fprintf(stderr, "options:\n"); fprintf(out, "Options:\n");
fprintf(stderr, " --delay=n, -d n " fprintf(out, " -d, --delay <secs> delay updates\n");
"delay n seconds between updates\n"); fprintf(out, " -o, --once only display once, then exit\n");
fprintf(stderr, " --once, -o " fprintf(out, " -s, --sort <char> specify sort criteria by character (see below)\n");
"only display once, then exit\n"); fprintf(out, " -V, --version display version information and exit\n");
fprintf(stderr, " --sort=S, -s S " fprintf(out, " -h, --help display this help and exit\n\n");
"specify sort criteria S (see below)\n");
fprintf(stderr, " --version, -V " fprintf(out, "The following are valid sort criteria:\n");
"display version information and exit\n"); fprintf(out, " a: sort by number of active objects\n");
fprintf(stderr, " --help display this help and exit\n\n"); fprintf(out, " b: sort by objects per slab\n");
fprintf(stderr, "The following are valid sort criteria:\n"); fprintf(out, " c: sort by cache size\n");
fprintf(stderr, " a: sort by number of active objects\n"); fprintf(out, " l: sort by number of slabs\n");
fprintf(stderr, " b: sort by objects per slab\n"); fprintf(out, " v: sort by number of active slabs\n");
fprintf(stderr, " c: sort by cache size\n"); fprintf(out, " n: sort by name\n");
fprintf(stderr, " l: sort by number of slabs\n"); fprintf(out, " o: sort by number of objects (the default)\n");
fprintf(stderr, " v: sort by number of active slabs\n"); fprintf(out, " p: sort by pages per slab\n");
fprintf(stderr, " n: sort by name\n"); fprintf(out, " s: sort by object size\n");
fprintf(stderr, " o: sort by number of objects\n"); fprintf(out, " u: sort by cache utilization\n\n");
fprintf(stderr, " p: sort by pages per slab\n");
fprintf(stderr, " s: sort by object size\n"); exit(out == stderr ? EXIT_FAILURE : EXIT_SUCCESS);
fprintf(stderr, " u: sort by cache utilization\n");
} }
/* /*
@ -204,27 +200,27 @@ static void * set_sort_func(char key)
{ {
switch (key) { switch (key) {
case 'n': case 'n':
return sort_name; return (void *) sort_name;
case 'o': case 'o':
return sort_nr_objs; return (void *) sort_nr_objs;
case 'a': case 'a':
return sort_nr_active_objs; return (void *) sort_nr_active_objs;
case 's': case 's':
return sort_obj_size; return (void *) sort_obj_size;
case 'b': case 'b':
return sort_objs_per_slab; return (void *) sort_objs_per_slab;
case 'p': case 'p':
return sort_pages_per_slab; return (void *) sort_pages_per_slab;
case 'l': case 'l':
return sort_nr_slabs; return (void *) sort_nr_slabs;
case 'v': case 'v':
return sort_nr_active_slabs; return (void *) sort_nr_active_slabs;
case 'c': case 'c':
return sort_cache_size; return (void *) sort_cache_size;
case 'u': case 'u':
return sort_use; return (void *) sort_use;
default: default:
return DEF_SORT_FUNC; return (void *) DEF_SORT_FUNC;
} }
} }
@ -276,36 +272,34 @@ int main(int argc, char *argv[])
struct slab_info *slab_list = NULL; struct slab_info *slab_list = NULL;
int run_once=0; int run_once=0;
struct option longopts[] = { static const struct option longopts[] = {
{ "delay", 1, NULL, 'd' }, { "delay", required_argument, NULL, 'd' },
{ "sort", 1, NULL, 's' }, { "sort", required_argument, NULL, 's' },
{ "once", 0, NULL, 'o' }, { "once", no_argument, NULL, 'o' },
{ "help", 0, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ "version", 0, NULL, 'V' }, { "version", no_argument, NULL, 'V' },
{ NULL, 0, NULL, 0 } { NULL, 0, NULL, 0 }
}; };
sort_func = DEF_SORT_FUNC; sort_func = DEF_SORT_FUNC;
while ((o = getopt_long(argc, argv, "d:s:ohV", longopts, NULL)) != -1) { while ((o = getopt_long(argc, argv, "d:s:ohV", longopts, NULL)) != -1) {
int ret = 1;
switch (o) { switch (o) {
char *end;
case 'd': case 'd':
errno = 0; errno = 0;
delay = strtol(optarg, NULL, 10); delay = strtol(optarg, &end, 10);
if (errno) { if (errno || optarg == end || (end && *end))
perror("strtoul"); errx(EXIT_FAILURE, "illegal delay `%s'",
return 1; optarg);
} if (delay < 0)
if (delay < 0) { errx(EXIT_FAILURE,
fprintf(stderr, "error: can't have a "\ "delay can not have a "
"negative delay\n"); "negative value");
exit(1);
}
break; break;
case 's': case 's':
sort_func = set_sort_func(optarg[0]); sort_func = (int (*)(const struct slab_info*,
const struct slab_info *)) set_sort_func(optarg[0]);
break; break;
case 'o': case 'o':
run_once=1; run_once=1;
@ -313,17 +307,16 @@ int main(int argc, char *argv[])
break; break;
case 'V': case 'V':
display_version(); display_version();
return 0; return EXIT_SUCCESS;
case 'h': case 'h':
ret = 0; usage(stdout);
default: default:
usage(argv[0]); usage(stderr);
return ret;
} }
} }
if (tcgetattr(0, &saved_tty) == -1) if (tcgetattr(STDIN_FILENO, &saved_tty) == -1)
perror("tcgetattr"); warn("tcgetattr");
old_rows = rows; old_rows = rows;
term_size(0); term_size(0);
@ -336,11 +329,12 @@ int main(int argc, char *argv[])
do { do {
struct slab_info *curr; struct slab_info *curr;
struct slab_stat stats = SLAB_STAT_ZERO; struct slab_stat stats;
struct timeval tv; struct timeval tv;
fd_set readfds; fd_set readfds;
char c; char c;
int i; int i;
memset(&stats, 0, sizeof(struct slab_stat));
if (get_slabinfo(&slab_list, &stats)) if (get_slabinfo(&slab_list, &stats))
break; break;
@ -382,14 +376,13 @@ int main(int argc, char *argv[])
} }
put_slabinfo(slab_list); put_slabinfo(slab_list);
if (!run_once) { if (!run_once) {
refresh(); refresh();
FD_ZERO(&readfds); FD_ZERO(&readfds);
FD_SET(0, &readfds); FD_SET(STDIN_FILENO, &readfds);
tv.tv_sec = delay; tv.tv_sec = delay;
tv.tv_usec = 0; tv.tv_usec = 0;
if (select(1, &readfds, NULL, NULL, &tv) > 0) { if (select(STDOUT_FILENO, &readfds, NULL, NULL, &tv) > 0) {
if (read(0, &c, 1) != 1) if (read(0, &c, 1) != 1)
break; break;
parse_input(c); parse_input(c);
@ -397,8 +390,8 @@ int main(int argc, char *argv[])
} }
} while (delay); } while (delay);
tcsetattr(0, TCSAFLUSH, &saved_tty); tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_tty);
free_slabinfo(slab_list); free_slabinfo(slab_list);
if (!run_once) endwin(); if (!run_once) endwin();
return 0; return EXIT_SUCCESS;
} }