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 }
* txt = { "B", "KB", "MB", "GB", "TB" }
* }
* variant bit {
* div = { 0.125, 125, 125000, 125000000, 125000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* }
* }
*
* unit bit {
* variant default {
* div = { 1, 1024, 1048576, 1073741824, 1099511627776}
* txt = { "b", "Kib", "Mib", "Gib", "TiB" }
* div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* }
* variant si {
* div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* }
* variant bit {
* div = { 1, 1000, 1000000, 1000000000, 1000000000000 }
* txt = { "b", "Kb", "Mb", "Gb", "Tb" }
* }
* }
*
* unit number {

View File

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

View File

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

View File

@ -79,6 +79,7 @@ static cfg_opt_t global_opts[] = {
CFG_INT("unit_exp", -1, CFGF_NONE),
CFG_INT("sleep_time", 20000UL, CFGF_NONE),
CFG_BOOL("use_si", 0, CFGF_NONE),
CFG_BOOL("use_bit", 0, CFGF_NONE),
CFG_STR("uid", NULL, CFGF_NONE),
CFG_STR("gid", NULL, CFGF_NONE),
CFG_STR("policy", "", CFGF_NONE),
@ -360,6 +361,8 @@ static void configfile_read_units(void)
add_div(u, UNIT_DEFAULT, variant);
else if (!strcasecmp(vtitle, "si"))
add_div(u, UNIT_SI, variant);
else if (!strcasecmp(vtitle, "bit"))
add_div(u, UNIT_BIT, variant);
else
quit("Unknown unit variant \'%s\'\n", vtitle);
}
@ -459,16 +462,24 @@ static const char default_config[] = \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"B\", \"KB\", \"MB\", \"GB\", \"TB\" }" \
" }" \
" variant bit {" \
" div = { 0.125, 125, 125000, 125000000, 125000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \
" }" \
"unit bit {" \
" variant default {" \
" div = { 1, 1024, 1048576, 1073741824, 1099511627776}" \
" txt = { \"b\", \"Kib\", \"Mib\", \"Gib\", \"TiB\" }" \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \
" variant si {" \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \
" variant bit {" \
" div = { 1, 1000, 1000000, 1000000000, 1000000000000 }" \
" txt = { \"b\", \"Kb\", \"Mb\", \"Gb\", \"Tb\" }" \
" }" \
"}" \
"unit number {" \
" 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 graph_cfg *cfg = &g->g_cfg;
uint64_t max = 0, v;
uint64_t max = 0;
double v;
int i, n, t;
float half_step, step;
@ -146,7 +147,7 @@ static void fill_table(struct graph *g, struct graph_table *tbl,
&tbl->gt_y_unit, NULL);
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)

View File

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