Add -b / --use-bit option to display rates in bit/s instead of bytes/s

Signed-off-by: Thomas Graf <tgraf@suug.ch>
This commit is contained in:
Thomas Graf 2014-05-08 15:16:38 +02:00
parent 127ffda015
commit 46ec101b00
6 changed files with 56 additions and 20 deletions

View File

@ -33,17 +33,25 @@
* div = { 1, 1000, 1000000, 1000000000, 1000000000000 } * div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "B", "KB", "MB", "GB", "TB" } * txt = { "B", "KB", "MB", "GB", "TB" }
* } * }
* variant bit {
* div = { 0.125, 125, 125000, 125000000, 125000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* }
* } * }
* *
* unit bit { * unit bit {
* variant default { * variant default {
* div = { 1, 1024, 1048576, 1073741824, 1099511627776} * div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "b", "Kib", "Mib", "Gib", "TiB" } * txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* } * }
* variant si { * variant si {
* div = { 1, 1000, 1000000, 1000000000, 1000000000000 } * div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" } * txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* } * }
* variant bit {
* div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* }
* } * }
* *
* unit number { * unit number {

View File

@ -33,6 +33,7 @@
enum { enum {
UNIT_DEFAULT, UNIT_DEFAULT,
UNIT_SI, UNIT_SI,
UNIT_BIT,
__UNIT_MAX, __UNIT_MAX,
}; };
@ -42,7 +43,7 @@ enum {
#define UNIT_NUMBER "number" #define UNIT_NUMBER "number"
struct fraction { struct fraction {
uint64_t f_divisor; float f_divisor;
char * f_name; char * f_name;
struct list_head f_list; struct list_head f_list;
@ -58,7 +59,7 @@ struct unit {
extern struct unit * unit_lookup(const char *); extern struct unit * unit_lookup(const char *);
extern struct unit * unit_add(const char *name); extern struct unit * unit_add(const char *name);
extern void unit_add_div(struct unit *, int, const char *, float); extern void unit_add_div(struct unit *, int, const char *, float);
extern uint64_t unit_divisor(uint64_t, struct unit *, char **, int *); extern double unit_divisor(uint64_t, struct unit *, char **, int *);
extern double unit_value2str(uint64_t, struct unit *, char **, int *); extern double unit_value2str(uint64_t, struct unit *, char **, int *);
extern void fraction_free(struct fraction *); extern void fraction_free(struct fraction *);

View File

@ -59,6 +59,7 @@ static char *usage_text =
"\n" \ "\n" \
"Output:\n" \ "Output:\n" \
" -U, --use-si Use SI units\n" \ " -U, --use-si Use SI units\n" \
" -b, --use-bit Display in bits instead of btyes\n" \
"\n" \ "\n" \
"Module configuration:\n" \ "Module configuration:\n" \
" modparm := MODULE:optlist,MODULE:optlist,...\n" \ " modparm := MODULE:optlist,MODULE:optlist,...\n" \
@ -170,7 +171,7 @@ static int parse_args_post(int argc, char *argv[])
for (;;) for (;;)
{ {
char *gostr = "i:o:p:r:R:s:aU" \ char *gostr = "i:o:p:r:R:s:aUb" \
"L:hvVf:"; "L:hvVf:";
struct option long_opts[] = { struct option long_opts[] = {
@ -182,6 +183,7 @@ static int parse_args_post(int argc, char *argv[])
{"sleep-interval", 1, 0, 's'}, {"sleep-interval", 1, 0, 's'},
{"show-all", 0, 0, 'a'}, {"show-all", 0, 0, 'a'},
{"use-si", 0, 0, 'U'}, {"use-si", 0, 0, 'U'},
{"use-bit", 0, 0, 'b'},
{"lifetime", 1, 0, 'L'}, {"lifetime", 1, 0, 'L'},
{0, 0, 0, 0}, {0, 0, 0, 0},
}; };
@ -225,6 +227,10 @@ static int parse_args_post(int argc, char *argv[])
cfg_setbool(cfg, "use_si", cfg_true); cfg_setbool(cfg, "use_si", cfg_true);
break; break;
case 'b':
cfg_setbool(cfg, "use_bit", cfg_true);
break;
case 'L': case 'L':
cfg_setint(cfg, "lifetime", strtoul(optarg, NULL, 0)); cfg_setint(cfg, "lifetime", strtoul(optarg, NULL, 0));
break; break;

View File

@ -79,6 +79,7 @@ static cfg_opt_t global_opts[] = {
CFG_INT("unit_exp", -1, CFGF_NONE), CFG_INT("unit_exp", -1, CFGF_NONE),
CFG_INT("sleep_time", 20000UL, CFGF_NONE), CFG_INT("sleep_time", 20000UL, CFGF_NONE),
CFG_BOOL("use_si", 0, CFGF_NONE), CFG_BOOL("use_si", 0, CFGF_NONE),
CFG_BOOL("use_bit", 0, CFGF_NONE),
CFG_STR("uid", NULL, CFGF_NONE), CFG_STR("uid", NULL, CFGF_NONE),
CFG_STR("gid", NULL, CFGF_NONE), CFG_STR("gid", NULL, CFGF_NONE),
CFG_STR("policy", "", CFGF_NONE), CFG_STR("policy", "", CFGF_NONE),
@ -360,6 +361,8 @@ static void configfile_read_units(void)
add_div(u, UNIT_DEFAULT, variant); add_div(u, UNIT_DEFAULT, variant);
else if (!strcasecmp(vtitle, "si")) else if (!strcasecmp(vtitle, "si"))
add_div(u, UNIT_SI, variant); add_div(u, UNIT_SI, variant);
else if (!strcasecmp(vtitle, "bit"))
add_div(u, UNIT_BIT, variant);
else else
quit("Unknown unit variant \'%s\'\n", vtitle); quit("Unknown unit variant \'%s\'\n", vtitle);
} }
@ -459,16 +462,24 @@ static const char default_config[] = \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"B\", \"KB\", \"MB\", \"GB\", \"TB\" }" \ " txt = { \"B\", \"KB\", \"MB\", \"GB\", \"TB\" }" \
" }" \ " }" \
" variant bit {" \
" div = { 0.125, 125, 125000, 125000000, 125000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \
" }" \ " }" \
"unit bit {" \ "unit bit {" \
" variant default {" \ " variant default {" \
" div = { 1, 1024, 1048576, 1073741824, 1099511627776}" \ " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"b\", \"Kib\", \"Mib\", \"Gib\", \"TiB\" }" \ " txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \ " }" \
" variant si {" \ " variant si {" \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \ " div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \ " txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \ " }" \
" variant bit {" \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \
"}" \ "}" \
"unit number {" \ "unit number {" \
" variant default {" \ " variant default {" \

View File

@ -82,7 +82,8 @@ static void fill_table(struct graph *g, struct graph_table *tbl,
struct history *h, struct history_store *data) struct history *h, struct history_store *data)
{ {
struct graph_cfg *cfg = &g->g_cfg; struct graph_cfg *cfg = &g->g_cfg;
uint64_t max = 0, v; uint64_t max = 0;
double v;
int i, n, t; int i, n, t;
float half_step, step; float half_step, step;
@ -146,7 +147,7 @@ static void fill_table(struct graph *g, struct graph_table *tbl,
&tbl->gt_y_unit, NULL); &tbl->gt_y_unit, NULL);
for (i = 0; i < cfg->gc_height; i++) for (i = 0; i < cfg->gc_height; i++)
tbl->gt_scale[i] /= (double) v; tbl->gt_scale[i] /= v;
} }
struct graph *graph_alloc(struct history *h, struct graph_cfg *cfg) struct graph *graph_alloc(struct history *h, struct graph_cfg *cfg)

View File

@ -34,15 +34,23 @@ static LIST_HEAD(units);
static struct list_head *get_flist(struct unit *unit) static struct list_head *get_flist(struct unit *unit)
{ {
static int cached = 0, div = UNIT_DEFAULT; static struct list_head *cached_list = NULL;
int div = UNIT_DEFAULT;
if (!cached && cfg_getbool(cfg, "use_si")) if (cached_list)
return cached_list;
if (cfg_getbool(cfg, "use_bit"))
div = UNIT_BIT;
else if (cfg_getbool(cfg, "use_si"))
div = UNIT_SI; div = UNIT_SI;
if (!list_empty(&unit->u_div[UNIT_SI]) && div == UNIT_SI) if (!list_empty(&unit->u_div[div]))
return &unit->u_div[UNIT_SI]; cached_list = &unit->u_div[div];
else else
return &unit->u_div[UNIT_DEFAULT]; cached_list = &unit->u_div[UNIT_DEFAULT];
return cached_list;
} }
struct unit *unit_lookup(const char *name) struct unit *unit_lookup(const char *name)
@ -72,7 +80,7 @@ struct unit *unit_lookup(const char *name)
* If prec points to a vaild integer, a number of precision digits * If prec points to a vaild integer, a number of precision digits
* is suggested to avoid n.00 to make pretty printing easier. * is suggested to avoid n.00 to make pretty printing easier.
*/ */
uint64_t unit_divisor(uint64_t hint, struct unit *unit, char **name, double unit_divisor(uint64_t hint, struct unit *unit, char **name,
int *prec) int *prec)
{ {
struct list_head *flist = get_flist(unit); struct list_head *flist = get_flist(unit);
@ -98,7 +106,7 @@ uint64_t unit_divisor(uint64_t hint, struct unit *unit, char **name,
return 1; return 1;
found_it: found_it:
if (f->f_divisor == 1 && prec) if (f->f_divisor == 1.0f && prec)
*prec = 0; *prec = 0;
*name = f->f_name; *name = f->f_name;
@ -108,12 +116,13 @@ found_it:
double unit_value2str(uint64_t value, struct unit *unit, double unit_value2str(uint64_t value, struct unit *unit,
char **name, int *prec) char **name, int *prec)
{ {
uint64_t div = unit_divisor(value, unit, name, prec); double div = unit_divisor(value, unit, name, prec);
double v = (double) value;
if (value % div == 0 && prec) if (fmod(v, div) == 0.0f && prec)
*prec = 0; *prec = 0;
return (double) value / (double) div; return v / div;
} }
void fraction_free(struct fraction *f) void fraction_free(struct fraction *f)