Commit 6519159a authored by Poul-Henning Kamp's avatar Poul-Henning Kamp

Change how min/max/default values for parameters are managed.

Make min/max values strings, and test-convert them along with the
default value during startup, to see that we can.  At the same time
normalize the strings with the parameters tweak function.

List min/max values in .rst doc.

param.show will flag default values. (Better the other way around ?)

Add a new feature:

	param.show changed

will only list parameters with non-default values (in short format)
parent d36344d3
...@@ -204,34 +204,51 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) ...@@ -204,34 +204,51 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv)
{ {
int i; int i;
const struct parspec *pp; const struct parspec *pp;
int lfmt; int lfmt = 0, chg = 0;
struct vsb *vsb;
vsb = VSB_new_auto();
(void)priv; (void)priv;
if (av[2] == NULL)
lfmt = 0; if (av[2] != NULL && !strcmp(av[2], "changed"))
else chg = 1;
else if (av[2] != NULL)
lfmt = 1; lfmt = 1;
for (i = 0; i < nparspec; i++) { for (i = 0; i < nparspec; i++) {
pp = parspecs[i]; pp = parspecs[i];
if (av[2] != NULL && if (lfmt && strcmp(pp->name, av[2]) && strcmp("-l", av[2]))
strcmp(pp->name, av[2]) &&
strcmp("-l", av[2]))
continue; continue;
VSB_clear(vsb);
if (pp->func(vsb, pp, NULL))
VCLI_SetResult(cli, CLIS_PARAM);
AZ(VSB_finish(vsb));
if (chg && pp->def != NULL && !strcmp(pp->def, VSB_data(vsb)))
continue;
if (lfmt) { if (lfmt) {
VCLI_Out(cli, "%s\n", pp->name); VCLI_Out(cli, "%s\n", pp->name);
VCLI_Out(cli, "%-*sValue is: ", margin1, " "); VCLI_Out(cli, "%-*sValue is: ", margin1, " ");
} else { } else {
VCLI_Out(cli, "%-*s", margin2, pp->name); VCLI_Out(cli, "%-*s", margin2, pp->name);
} }
if (pp->func(cli->sb, pp, NULL)) VCLI_Out(cli, "%s", VSB_data(vsb));
VCLI_SetResult(cli, CLIS_PARAM);
if (pp->units != NULL && *pp->units != '\0') if (pp->units != NULL && *pp->units != '\0')
VCLI_Out(cli, " [%s]\n", pp->units); VCLI_Out(cli, " [%s]", pp->units);
else if (pp->def != NULL && !strcmp(pp->def, VSB_data(vsb)))
VCLI_Out(cli, "\n"); VCLI_Out(cli, " (default)");
if (av[2] != NULL) { VCLI_Out(cli, "\n");
VCLI_Out(cli, "%-*sDefault is: %s\n\n", if (lfmt) {
VCLI_Out(cli, "%-*sDefault is: %s\n",
margin1, "", pp->def); margin1, "", pp->def);
if (pp->min != NULL)
VCLI_Out(cli, "%-*sMinimum is: %s\n",
margin1, "", pp->min);
if (pp->max != NULL)
VCLI_Out(cli, "%-*sMaximum is: %s\n",
margin1, "", pp->max);
VCLI_Out(cli, "\n");
mcf_wrap(cli, pp->descr); mcf_wrap(cli, pp->descr);
if (pp->flags & OBJ_STICKY) if (pp->flags & OBJ_STICKY)
mcf_wrap(cli, OBJ_STICKY_TEXT); mcf_wrap(cli, OBJ_STICKY_TEXT);
...@@ -247,16 +264,14 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv) ...@@ -247,16 +264,14 @@ mcf_param_show(struct cli *cli, const char * const *av, void *priv)
mcf_wrap(cli, WIZARD_TEXT); mcf_wrap(cli, WIZARD_TEXT);
if (pp->flags & PROTECTED) if (pp->flags & PROTECTED)
mcf_wrap(cli, PROTECTED_TEXT); mcf_wrap(cli, PROTECTED_TEXT);
if (!lfmt) VCLI_Out(cli, "\n\n");
return;
else
VCLI_Out(cli, "\n\n");
} }
} }
if (av[2] != NULL && !lfmt) { if (av[2] != NULL && !lfmt && !chg) {
VCLI_SetResult(cli, CLIS_PARAM); VCLI_SetResult(cli, CLIS_PARAM);
VCLI_Out(cli, "Unknown parameter \"%s\".", av[2]); VCLI_Out(cli, "Unknown parameter \"%s\".", av[2]);
} }
VSB_delete(vsb);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -381,39 +396,60 @@ MCF_AddParams(struct parspec *ps) ...@@ -381,39 +396,60 @@ MCF_AddParams(struct parspec *ps)
qsort (parspecs, nparspec, sizeof parspecs[0], mcf_parspec_cmp); qsort (parspecs, nparspec, sizeof parspecs[0], mcf_parspec_cmp);
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
* Set defaults for all parameters * Wash a min/max/default value
*/
static void
mcf_wash_param(struct cli *cli, const struct parspec *pp, const char **val,
const char *name, struct vsb *vsb)
{
int err;
AN(*val);
VSB_clear(vsb);
VSB_printf(vsb, "FAILED to set %s for param %s = %s\n",
name, pp->name, *val);
err = pp->func(vsb, pp, *val);
AZ(VSB_finish(vsb));
if (err) {
VCLI_Out(cli, "%s", VSB_data(vsb));
VCLI_SetResult(cli, CLIS_CANT);
return;
}
VSB_clear(vsb);
err = pp->func(vsb, pp, NULL);
AZ(err);
AZ(VSB_finish(vsb));
if (strcmp(*val, VSB_data(vsb))) {
*val = strdup(VSB_data(vsb));
AN(*val);
}
}
/*--------------------------------------------------------------------
* Wash the min/max/default values, and leave the default set.
*/ */
void void
MCF_InitParams(struct cli *cli) MCF_InitParams(struct cli *cli)
{ {
const struct parspec *pp; struct parspec *pp;
int i, j, err; int i;
struct vsb *vsb; struct vsb *vsb;
/*
* We try to set the default twice, and only failures the
* second time around are fatal. This allows for trivial
* interdependencies.
*/
vsb = VSB_new_auto(); vsb = VSB_new_auto();
AN(vsb); AN(vsb);
for (j = 0; j < 2; j++) { for (i = 0; i < nparspec; i++) {
err = 0; pp = parspecs[i];
for (i = 0; i < nparspec; i++) {
pp = parspecs[i]; if (pp->min != NULL)
VSB_clear(vsb); mcf_wash_param(cli, pp, &pp->min, "Minimum", vsb);
VSB_printf(vsb, if (pp->max != NULL)
"FAILED to set default for param %s = %s\n", mcf_wash_param(cli, pp, &pp->max, "Maximum", vsb);
pp->name, pp->def); AN(pp->def);
err = pp->func(vsb, pp, pp->def); mcf_wash_param(cli, pp, &pp->def, "Default", vsb);
AZ(VSB_finish(vsb));
if (err && j) {
VCLI_Out(cli, "%s", VSB_data(vsb));
VCLI_SetResult(cli, CLIS_CANT);
}
}
} }
VSB_delete(vsb); VSB_delete(vsb);
} }
...@@ -462,6 +498,10 @@ MCF_DumpRstParam(void) ...@@ -462,6 +498,10 @@ MCF_DumpRstParam(void)
if (pp->units != NULL && *pp->units != '\0') if (pp->units != NULL && *pp->units != '\0')
printf("\t* Units: %s\n", pp->units); printf("\t* Units: %s\n", pp->units);
printf("\t* Default: %s\n", pp->def); printf("\t* Default: %s\n", pp->def);
if (pp->min != NULL)
printf("\t* Minimum: %s\n", pp->min);
if (pp->max != NULL)
printf("\t* Maximum: %s\n", pp->max);
/* /*
* XXX: we should mark the params with one/two flags * XXX: we should mark the params with one/two flags
* XXX: that say if ->min/->max are valid, so we * XXX: that say if ->min/->max are valid, so we
......
...@@ -36,8 +36,8 @@ struct parspec { ...@@ -36,8 +36,8 @@ struct parspec {
const char *name; const char *name;
tweak_t *func; tweak_t *func;
volatile void *priv; volatile void *priv;
double min; const char *min;
double max; const char *max;
const char *descr; const char *descr;
int flags; int flags;
#define DELAYED_EFFECT (1<<0) #define DELAYED_EFFECT (1<<0)
...@@ -54,7 +54,7 @@ struct parspec { ...@@ -54,7 +54,7 @@ struct parspec {
tweak_t tweak_bool; tweak_t tweak_bool;
tweak_t tweak_bytes; tweak_t tweak_bytes;
tweak_t tweak_bytes_u; tweak_t tweak_bytes_u;
tweak_t tweak_generic_double; tweak_t tweak_double;
tweak_t tweak_group; tweak_t tweak_group;
tweak_t tweak_listen_address; tweak_t tweak_listen_address;
tweak_t tweak_poolparam; tweak_t tweak_poolparam;
...@@ -65,8 +65,8 @@ tweak_t tweak_uint; ...@@ -65,8 +65,8 @@ tweak_t tweak_uint;
tweak_t tweak_user; tweak_t tweak_user;
tweak_t tweak_waiter; tweak_t tweak_waiter;
int tweak_generic_uint(struct vsb *vsb, int tweak_generic_uint(struct vsb *vsb, volatile unsigned *dest,
volatile unsigned *dest, const char *arg, unsigned min, unsigned max); const char *arg, const char *min, const char *max);
/* mgt_param_tbl.c */ /* mgt_param_tbl.c */
extern struct parspec mgt_parspec[]; extern struct parspec mgt_parspec[];
......
...@@ -235,13 +235,13 @@ tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg) ...@@ -235,13 +235,13 @@ tweak_feature(struct vsb *vsb, const struct parspec *par, const char *arg)
*/ */
struct parspec VSL_parspec[] = { struct parspec VSL_parspec[] = {
{ "vsl_mask", tweak_vsl_mask, NULL, 0, 0, { "vsl_mask", tweak_vsl_mask, NULL, NULL, NULL,
"Mask individual VSL messages from being logged.\n" "Mask individual VSL messages from being logged.\n"
"\tdefault\tSet default value\n" "\tdefault\tSet default value\n"
"\nUse +/- prefixe in front of VSL tag name, to mask/unmask " "\nUse +/- prefixe in front of VSL tag name, to mask/unmask "
"individual VSL messages.", "individual VSL messages.",
0, "default", "" }, 0, "default", "" },
{ "debug", tweak_debug, NULL, 0, 0, { "debug", tweak_debug, NULL, NULL, NULL,
"Enable/Disable various kinds of debugging.\n" "Enable/Disable various kinds of debugging.\n"
"\tnone\tDisable all debugging\n\n" "\tnone\tDisable all debugging\n\n"
"Use +/- prefix to set/reset individual bits:" "Use +/- prefix to set/reset individual bits:"
...@@ -249,7 +249,7 @@ struct parspec VSL_parspec[] = { ...@@ -249,7 +249,7 @@ struct parspec VSL_parspec[] = {
#include "tbl/debug_bits.h" #include "tbl/debug_bits.h"
#undef DEBUG_BIT #undef DEBUG_BIT
, 0, "none", "" }, , 0, "none", "" },
{ "feature", tweak_feature, NULL, 0, 0, { "feature", tweak_feature, NULL, NULL, NULL,
"Enable/Disable various minor features.\n" "Enable/Disable various minor features.\n"
"\tnone\tDisable all features.\n\n" "\tnone\tDisable all features.\n\n"
"Use +/- prefix to enable/disable individual feature:" "Use +/- prefix to enable/disable individual feature:"
......
This diff is collapsed.
...@@ -56,68 +56,77 @@ ...@@ -56,68 +56,77 @@
#include "mgt_cli.h" #include "mgt_cli.h"
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------
* Generic handling of double typed parameters
*/
static int static int
tweak_generic_timeout(struct vsb *vsb, volatile unsigned *dst, const char *arg) tweak_generic_double(struct vsb *vsb, volatile double *dest,
const char *arg, const char *min, const char *max, const char *fmt)
{ {
unsigned u; double u, minv = 0, maxv = 0;
char *p;
if (arg != NULL) { if (arg != NULL) {
u = strtoul(arg, NULL, 0); if (min != NULL) {
if (u == 0) { p = NULL;
VSB_printf(vsb, "Timeout must be greater than zero\n"); minv = strtod(min, &p);
return (-1); if (*arg == '\0' || *p != '\0') {
VSB_printf(vsb, "Illegal Min: %s\n", min);
return (-1);
}
}
if (max != NULL) {
p = NULL;
maxv = strtod(max, &p);
if (*arg == '\0' || *p != '\0') {
VSB_printf(vsb, "Illegal Max: %s\n", max);
return (-1);
}
} }
*dst = u;
} else
VSB_printf(vsb, "%u", *dst);
return (0);
}
/*--------------------------------------------------------------------*/
int
tweak_timeout(struct vsb *vsb, const struct parspec *par, const char *arg)
{
volatile unsigned *dest;
dest = par->priv;
return (tweak_generic_timeout(vsb, dest, arg));
}
/*--------------------------------------------------------------------*/
static int
tweak_generic_timeout_double(struct vsb *vsb, volatile double *dest,
const char *arg, double min, double max)
{
double u;
char *p;
if (arg != NULL) {
p = NULL; p = NULL;
u = strtod(arg, &p); u = strtod(arg, &p);
if (*arg == '\0' || *p != '\0') { if (*arg == '\0' || *p != '\0') {
VSB_printf(vsb, "Not a number(%s)\n", arg); VSB_printf(vsb, "Not a number(%s)\n", arg);
return (-1); return (-1);
} }
if (u < min) { if (min != NULL && u < minv) {
VSB_printf(vsb, VSB_printf(vsb,
"Timeout must be greater or equal to %.g\n", min); "Timeout must be greater or equal to %s\n", min);
return (-1); return (-1);
} }
if (u > max) { if (max != NULL && u > maxv) {
VSB_printf(vsb, VSB_printf(vsb,
"Timeout must be less than or equal to %.g\n", max); "Timeout must be less than or equal to %s\n", max);
return (-1); return (-1);
} }
*dest = u; *dest = u;
} else } else
VSB_printf(vsb, "%.6f", *dest); VSB_printf(vsb, fmt, *dest);
return (0); return (0);
} }
/*--------------------------------------------------------------------*/
int
tweak_timeout(struct vsb *vsb, const struct parspec *par, const char *arg)
{
int i;
double d;
volatile unsigned *dest;
dest = par->priv;
d = *dest;
i = tweak_generic_double(vsb, &d, arg, par->min, par->max, "%.0f");
if (!i) {
*dest = (unsigned)ceil(d);
}
return (i);
}
/*--------------------------------------------------------------------*/
int int
tweak_timeout_double(struct vsb *vsb, const struct parspec *par, tweak_timeout_double(struct vsb *vsb, const struct parspec *par,
const char *arg) const char *arg)
...@@ -125,45 +134,20 @@ tweak_timeout_double(struct vsb *vsb, const struct parspec *par, ...@@ -125,45 +134,20 @@ tweak_timeout_double(struct vsb *vsb, const struct parspec *par,
volatile double *dest; volatile double *dest;
dest = par->priv; dest = par->priv;
return (tweak_generic_timeout_double(vsb, dest, arg, return (tweak_generic_double(vsb, dest, arg,
par->min, par->max)); par->min, par->max, "%.3f"));
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
int int
tweak_generic_double(struct vsb *vsb, const struct parspec *par, tweak_double(struct vsb *vsb, const struct parspec *par, const char *arg)
const char *arg)
{ {
volatile double *dest; volatile double *dest;
char *p;
double u;
dest = par->priv; dest = par->priv;
if (arg != NULL) { return (tweak_generic_double(vsb, dest, arg,
p = NULL; par->min, par->max, "%g"));
u = strtod(arg, &p);
if (*p != '\0') {
VSB_printf(vsb,
"Not a number (%s)\n", arg);
return (-1);
}
if (u < par->min) {
VSB_printf(vsb,
"Must be greater or equal to %.g\n",
par->min);
return (-1);
}
if (u > par->max) {
VSB_printf(vsb,
"Must be less than or equal to %.g\n",
par->max);
return (-1);
}
*dest = u;
} else
VSB_printf(vsb, "%f", *dest);
return (0);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -214,12 +198,28 @@ tweak_bool(struct vsb *vsb, const struct parspec *par, const char *arg) ...@@ -214,12 +198,28 @@ tweak_bool(struct vsb *vsb, const struct parspec *par, const char *arg)
int int
tweak_generic_uint(struct vsb *vsb, volatile unsigned *dest, const char *arg, tweak_generic_uint(struct vsb *vsb, volatile unsigned *dest, const char *arg,
unsigned min, unsigned max) const char *min, const char *max)
{ {
unsigned u; unsigned u, minv = 0, maxv = 0;
char *p; char *p;
if (arg != NULL) { if (arg != NULL) {
if (min != NULL) {
p = NULL;
minv = strtoul(min, &p, 0);
if (*arg == '\0' || *p != '\0') {
VSB_printf(vsb, "Illegal Min: %s\n", min);
return (-1);
}
}
if (max != NULL) {
p = NULL;
maxv = strtoul(max, &p, 0);
if (*arg == '\0' || *p != '\0') {
VSB_printf(vsb, "Illegal Max: %s\n", max);
return (-1);
}
}
p = NULL; p = NULL;
if (!strcasecmp(arg, "unlimited")) if (!strcasecmp(arg, "unlimited"))
u = UINT_MAX; u = UINT_MAX;
...@@ -230,12 +230,12 @@ tweak_generic_uint(struct vsb *vsb, volatile unsigned *dest, const char *arg, ...@@ -230,12 +230,12 @@ tweak_generic_uint(struct vsb *vsb, volatile unsigned *dest, const char *arg,
return (-1); return (-1);
} }
} }
if (u < min) { if (min != NULL && u < minv) {
VSB_printf(vsb, "Must be at least %u\n", min); VSB_printf(vsb, "Must be at least %s\n", min);
return (-1); return (-1);
} }
if (u > max) { if (max != NULL && u > maxv) {
VSB_printf(vsb, "Must be no more than %u\n", max); VSB_printf(vsb, "Must be no more than %s\n", max);
return (-1); return (-1);
} }
*dest = u; *dest = u;
...@@ -255,9 +255,7 @@ tweak_uint(struct vsb *vsb, const struct parspec *par, const char *arg) ...@@ -255,9 +255,7 @@ tweak_uint(struct vsb *vsb, const struct parspec *par, const char *arg)
volatile unsigned *dest; volatile unsigned *dest;
dest = par->priv; dest = par->priv;
(void)tweak_generic_uint(vsb, dest, arg, return (tweak_generic_uint(vsb, dest, arg, par->min, par->max));
(uint)par->min, (uint)par->max);
return (0);
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
...@@ -287,12 +285,26 @@ fmt_bytes(struct vsb *vsb, uintmax_t t) ...@@ -287,12 +285,26 @@ fmt_bytes(struct vsb *vsb, uintmax_t t)
static int static int
tweak_generic_bytes(struct vsb *vsb, volatile ssize_t *dest, const char *arg, tweak_generic_bytes(struct vsb *vsb, volatile ssize_t *dest, const char *arg,
double min, double max) const char *min, const char *max)
{ {
uintmax_t r; uintmax_t r, rmin = 0, rmax = 0;
const char *p; const char *p;
if (arg != NULL) { if (arg != NULL) {
if (min != NULL) {
p = VNUM_2bytes(min, &rmin, 0);
if (p != NULL) {
VSB_printf(vsb, "Invalid min-val: %s\n", min);
return (-1);
}
}
if (max != NULL) {
p = VNUM_2bytes(max, &rmax, 0);
if (p != NULL) {
VSB_printf(vsb, "Invalid max-val: %s\n", max);
return (-1);
}
}
p = VNUM_2bytes(arg, &r, 0); p = VNUM_2bytes(arg, &r, 0);
if (p != NULL) { if (p != NULL) {
VSB_printf(vsb, "Could not convert to bytes.\n"); VSB_printf(vsb, "Could not convert to bytes.\n");
...@@ -303,19 +315,17 @@ tweak_generic_bytes(struct vsb *vsb, volatile ssize_t *dest, const char *arg, ...@@ -303,19 +315,17 @@ tweak_generic_bytes(struct vsb *vsb, volatile ssize_t *dest, const char *arg,
} }
if ((uintmax_t)((ssize_t)r) != r) { if ((uintmax_t)((ssize_t)r) != r) {
fmt_bytes(vsb, r); fmt_bytes(vsb, r);
VSB_printf(vsb, " is too large for this architecture.\n"); VSB_printf(vsb,
" is too large for this architecture.\n");
return (-1); return (-1);
} }
if (max != 0. && r > max) { if (max != NULL && r > rmax) {
VSB_printf(vsb, "Must be no more than "); VSB_printf(vsb, "Must be no more than %s\n", max);
fmt_bytes(vsb, (uintmax_t)max);
VSB_printf(vsb, "\n"); VSB_printf(vsb, "\n");
return (-1); return (-1);
} }
if (r < min) { if (min != NULL && r < rmin) {
VSB_printf(vsb, "Must be at least "); VSB_printf(vsb, "Must be at least %s\n", min);
fmt_bytes(vsb, (uintmax_t)min);
VSB_printf(vsb, "\n");
return (-1); return (-1);
} }
*dest = r; *dest = r;
...@@ -332,12 +342,10 @@ tweak_bytes(struct vsb *vsb, const struct parspec *par, const char *arg) ...@@ -332,12 +342,10 @@ tweak_bytes(struct vsb *vsb, const struct parspec *par, const char *arg)
{ {
volatile ssize_t *dest; volatile ssize_t *dest;
assert(par->min >= 0);
dest = par->priv; dest = par->priv;
return (tweak_generic_bytes(vsb, dest, arg, par->min, par->max)); return (tweak_generic_bytes(vsb, dest, arg, par->min, par->max));
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
int int
...@@ -346,8 +354,6 @@ tweak_bytes_u(struct vsb *vsb, const struct parspec *par, const char *arg) ...@@ -346,8 +354,6 @@ tweak_bytes_u(struct vsb *vsb, const struct parspec *par, const char *arg)
volatile unsigned *d1; volatile unsigned *d1;
volatile ssize_t dest; volatile ssize_t dest;
assert(par->max <= UINT_MAX);
assert(par->min >= 0);
d1 = par->priv; d1 = par->priv;
dest = *d1; dest = *d1;
if (tweak_generic_bytes(vsb, &dest, arg, par->min, par->max)) if (tweak_generic_bytes(vsb, &dest, arg, par->min, par->max))
...@@ -568,15 +574,15 @@ tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg) ...@@ -568,15 +574,15 @@ tweak_poolparam(struct vsb *vsb, const struct parspec *par, const char *arg)
} }
px = *pp; px = *pp;
retval = tweak_generic_uint(vsb, &px.min_pool, av[1], retval = tweak_generic_uint(vsb, &px.min_pool, av[1],
(uint)par->min, (uint)par->max); par->min, par->max);
if (retval) if (retval)
break; break;
retval = tweak_generic_uint(vsb, &px.max_pool, av[2], retval = tweak_generic_uint(vsb, &px.max_pool, av[2],
(uint)par->min, (uint)par->max); par->min, par->max);
if (retval) if (retval)
break; break;
retval = tweak_generic_timeout_double(vsb, retval = tweak_generic_double(vsb,
&px.max_age, av[3], 0, 1e6); &px.max_age, av[3], "0", "1e6", "%.0f");
if (retval) if (retval)
break; break;
if (px.min_pool > px.max_pool) { if (px.min_pool > px.max_pool) {
......
...@@ -42,7 +42,6 @@ ...@@ -42,7 +42,6 @@
#include "config.h" #include "config.h"
#include <limits.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <unistd.h> #include <unistd.h>
...@@ -60,7 +59,8 @@ tweak_thread_pool_min(struct vsb *vsb, const struct parspec *par, ...@@ -60,7 +59,8 @@ tweak_thread_pool_min(struct vsb *vsb, const struct parspec *par,
{ {
return (tweak_generic_uint(vsb, &mgt_param.wthread_min, arg, return (tweak_generic_uint(vsb, &mgt_param.wthread_min, arg,
(unsigned)par->min, mgt_param.wthread_max)); // par->min, mgt_param.wthread_max));
par->min, NULL));
} }
/*-------------------------------------------------------------------- /*--------------------------------------------------------------------
...@@ -93,14 +93,15 @@ tweak_thread_pool_max(struct vsb *vsb, const struct parspec *par, ...@@ -93,14 +93,15 @@ tweak_thread_pool_max(struct vsb *vsb, const struct parspec *par,
(void)par; (void)par;
return (tweak_generic_uint(vsb, &mgt_param.wthread_max, arg, return (tweak_generic_uint(vsb, &mgt_param.wthread_max, arg,
mgt_param.wthread_min, UINT_MAX)); //mgt_param.wthread_min, NULL));
NULL, NULL));
} }
/*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*/
struct parspec WRK_parspec[] = { struct parspec WRK_parspec[] = {
{ "thread_pools", tweak_uint, &mgt_param.wthread_pools, { "thread_pools", tweak_uint, &mgt_param.wthread_pools,
1, UINT_MAX, "1", NULL,
"Number of worker thread pools.\n" "Number of worker thread pools.\n"
"\n" "\n"
"Increasing number of worker pools decreases lock " "Increasing number of worker pools decreases lock "
...@@ -113,7 +114,8 @@ struct parspec WRK_parspec[] = { ...@@ -113,7 +114,8 @@ struct parspec WRK_parspec[] = {
"restart to take effect.", "restart to take effect.",
EXPERIMENTAL | DELAYED_EFFECT, EXPERIMENTAL | DELAYED_EFFECT,
"2", "pools" }, "2", "pools" },
{ "thread_pool_max", tweak_thread_pool_max, NULL, 10, 0, { "thread_pool_max", tweak_thread_pool_max, NULL,
"10", NULL,
"The maximum number of worker threads in each pool.\n" "The maximum number of worker threads in each pool.\n"
"\n" "\n"
"Do not set this higher than you have to, since excess " "Do not set this higher than you have to, since excess "
...@@ -123,7 +125,8 @@ struct parspec WRK_parspec[] = { ...@@ -123,7 +125,8 @@ struct parspec WRK_parspec[] = {
"Minimum is 10 threads.", "Minimum is 10 threads.",
DELAYED_EFFECT, DELAYED_EFFECT,
"5000", "threads" }, "5000", "threads" },
{ "thread_pool_min", tweak_thread_pool_min, NULL, 10, 0, { "thread_pool_min", tweak_thread_pool_min, NULL,
"10", NULL,
"The minimum number of worker threads in each pool.\n" "The minimum number of worker threads in each pool.\n"
"\n" "\n"
"Increasing this may help ramp up faster from low load " "Increasing this may help ramp up faster from low load "
...@@ -134,7 +137,7 @@ struct parspec WRK_parspec[] = { ...@@ -134,7 +137,7 @@ struct parspec WRK_parspec[] = {
"100", "threads" }, "100", "threads" },
{ "thread_pool_timeout", { "thread_pool_timeout",
tweak_timeout_double, &mgt_param.wthread_timeout, tweak_timeout_double, &mgt_param.wthread_timeout,
10, UINT_MAX, "10", NULL,
"Thread idle threshold.\n" "Thread idle threshold.\n"
"\n" "\n"
"Threads in excess of thread_pool_min, which have been idle " "Threads in excess of thread_pool_min, which have been idle "
...@@ -145,7 +148,7 @@ struct parspec WRK_parspec[] = { ...@@ -145,7 +148,7 @@ struct parspec WRK_parspec[] = {
"300", "seconds" }, "300", "seconds" },
{ "thread_pool_destroy_delay", { "thread_pool_destroy_delay",
tweak_timeout_double, &mgt_param.wthread_destroy_delay, tweak_timeout_double, &mgt_param.wthread_destroy_delay,
0.01, UINT_MAX, "0.01", NULL,
"Wait this long after destroying a thread.\n" "Wait this long after destroying a thread.\n"
"\n" "\n"
"This controls the decay of thread pools when idle(-ish).\n" "This controls the decay of thread pools when idle(-ish).\n"
...@@ -155,7 +158,7 @@ struct parspec WRK_parspec[] = { ...@@ -155,7 +158,7 @@ struct parspec WRK_parspec[] = {
"1", "seconds" }, "1", "seconds" },
{ "thread_pool_add_delay", { "thread_pool_add_delay",
tweak_timeout_double, &mgt_param.wthread_add_delay, tweak_timeout_double, &mgt_param.wthread_add_delay,
0, UINT_MAX, "0", NULL,
"Wait at least this long after creating a thread.\n" "Wait at least this long after creating a thread.\n"
"\n" "\n"
"Some (buggy) systems may need a short (sub-second) " "Some (buggy) systems may need a short (sub-second) "
...@@ -168,7 +171,7 @@ struct parspec WRK_parspec[] = { ...@@ -168,7 +171,7 @@ struct parspec WRK_parspec[] = {
"0", "seconds" }, "0", "seconds" },
{ "thread_pool_fail_delay", { "thread_pool_fail_delay",
tweak_timeout_double, &mgt_param.wthread_fail_delay, tweak_timeout_double, &mgt_param.wthread_fail_delay,
10e-3, UINT_MAX, "10e-3", NULL,
"Wait at least this long after a failed thread creation " "Wait at least this long after a failed thread creation "
"before trying to create another thread.\n" "before trying to create another thread.\n"
"\n" "\n"
...@@ -186,7 +189,8 @@ struct parspec WRK_parspec[] = { ...@@ -186,7 +189,8 @@ struct parspec WRK_parspec[] = {
EXPERIMENTAL, EXPERIMENTAL,
"0.2", "seconds" }, "0.2", "seconds" },
{ "thread_stats_rate", { "thread_stats_rate",
tweak_uint, &mgt_param.wthread_stats_rate, 0, UINT_MAX, tweak_uint, &mgt_param.wthread_stats_rate,
"0", NULL,
"Worker threads accumulate statistics, and dump these into " "Worker threads accumulate statistics, and dump these into "
"the global stats counters if the lock is free when they " "the global stats counters if the lock is free when they "
"finish a request.\n" "finish a request.\n"
...@@ -196,7 +200,7 @@ struct parspec WRK_parspec[] = { ...@@ -196,7 +200,7 @@ struct parspec WRK_parspec[] = {
EXPERIMENTAL, EXPERIMENTAL,
"10", "requests" }, "10", "requests" },
{ "thread_queue_limit", tweak_uint, &mgt_param.wthread_queue_limit, { "thread_queue_limit", tweak_uint, &mgt_param.wthread_queue_limit,
0, UINT_MAX, "0", NULL,
"Permitted queue length per thread-pool.\n" "Permitted queue length per thread-pool.\n"
"\n" "\n"
"This sets the number of requests we will queue, waiting " "This sets the number of requests we will queue, waiting "
...@@ -204,7 +208,8 @@ struct parspec WRK_parspec[] = { ...@@ -204,7 +208,8 @@ struct parspec WRK_parspec[] = {
"be dropped instead of queued.", "be dropped instead of queued.",
EXPERIMENTAL, EXPERIMENTAL,
"20", "" }, "20", "" },
{ "rush_exponent", tweak_uint, &mgt_param.rush_exponent, 2, UINT_MAX, { "rush_exponent", tweak_uint, &mgt_param.rush_exponent,
"2", NULL,
"How many parked request we start for each completed " "How many parked request we start for each completed "
"request on the object.\n" "request on the object.\n"
"NB: Even with the implict delay of delivery, " "NB: Even with the implict delay of delivery, "
...@@ -213,7 +218,8 @@ struct parspec WRK_parspec[] = { ...@@ -213,7 +218,8 @@ struct parspec WRK_parspec[] = {
EXPERIMENTAL, EXPERIMENTAL,
"3", "requests per request" }, "3", "requests per request" },
{ "thread_pool_stack", { "thread_pool_stack",
tweak_stack_size, &mgt_param.wthread_stacksize, 0, UINT_MAX, tweak_stack_size, &mgt_param.wthread_stacksize,
"0", NULL,
"Worker thread stack size.\n" "Worker thread stack size.\n"
"This is likely rounded up to a multiple of 4k by the kernel.\n" "This is likely rounded up to a multiple of 4k by the kernel.\n"
"The kernel/OS has a lower limit which will be enforced.", "The kernel/OS has a lower limit which will be enforced.",
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment