mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-21 12:30:06 +00:00
tunables: Add support for tunables of uint64_t type
Recognize the uint64_t type in addition to the current int32_t and size_t. This allows addition of tunables of uint64_t types. In addition to adding the uint64_t type, this patch also consolidates validation and reading of integer types in tunables. One notable change is that of overflow computation in tunables_strtoul. The function was lifted from __internal_strtoul, but it does not need the boundary condition check (i.e. result == ULONG_MAX) since it does not need to set errno. As a result the check can be simplified, which I have now done. * elf/dl-tunable-types.h (tunable_type_code_t): New type TUNABLE_TYPE_UINT_64. * elf/dl-tunables.c (tunables_strtoul): Return uint64_t. Simplify computation of overflow. (tunable_set_val_if_valid_range_signed, tunable_set_val_if_valid_range_unsigned): Remove and replace with this... (TUNABLE_SET_VAL_IF_VALID_RANGE): ... New macro. (tunable_initialize): Adjust. Add uint64_t support. (__tunable_set_val): Add uint64_t support. * README.tunables: Document it.
This commit is contained in:
parent
d13103074a
commit
ad2f35cb39
12
ChangeLog
12
ChangeLog
@ -1,5 +1,17 @@
|
||||
2017-05-17 Siddhesh Poyarekar <siddhesh@sourceware.org>
|
||||
|
||||
* elf/dl-tunable-types.h (tunable_type_code_t): New type
|
||||
TUNABLE_TYPE_UINT_64.
|
||||
* elf/dl-tunables.c (tunables_strtoul): Return uint64_t.
|
||||
Simplify computation of overflow.
|
||||
(tunable_set_val_if_valid_range_signed,
|
||||
tunable_set_val_if_valid_range_unsigned): Remove and replace
|
||||
with this...
|
||||
(TUNABLE_SET_VAL_IF_VALID_RANGE): ... New macro.
|
||||
(tunable_initialize): Adjust. Add uint64_t support.
|
||||
(__tunable_set_val): Add uint64_t support.
|
||||
* README.tunables: Document it.
|
||||
|
||||
* scripts/gen-tunables.awk: Recognize 'default' keyword in
|
||||
dl-tunables.list.
|
||||
* README.tunables: Document it.
|
||||
|
@ -48,7 +48,8 @@ TOP_NAMESPACE {
|
||||
The list of allowed attributes are:
|
||||
|
||||
- type: Data type. Defaults to STRING. Allowed types are:
|
||||
INT_32, SIZE_T and STRING.
|
||||
INT_32, UINT_64, SIZE_T and STRING. Numeric types may
|
||||
be in octal or hexadecimal format too.
|
||||
|
||||
- minval: Optional minimum acceptable value. For a string type
|
||||
this is the minimum length of the value.
|
||||
|
@ -24,6 +24,7 @@
|
||||
typedef enum
|
||||
{
|
||||
TUNABLE_TYPE_INT_32,
|
||||
TUNABLE_TYPE_UINT_64,
|
||||
TUNABLE_TYPE_SIZE_T,
|
||||
TUNABLE_TYPE_STRING
|
||||
} tunable_type_code_t;
|
||||
|
@ -105,10 +105,10 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val,
|
||||
/* A stripped down strtoul-like implementation for very early use. It does not
|
||||
set errno if the result is outside bounds because it gets called before
|
||||
errno may have been set up. */
|
||||
static unsigned long int
|
||||
static uint64_t
|
||||
tunables_strtoul (const char *nptr)
|
||||
{
|
||||
unsigned long int result = 0;
|
||||
uint64_t result = 0;
|
||||
long int sign = 1;
|
||||
unsigned max_digit;
|
||||
|
||||
@ -144,7 +144,7 @@ tunables_strtoul (const char *nptr)
|
||||
|
||||
while (1)
|
||||
{
|
||||
unsigned long int digval;
|
||||
int digval;
|
||||
if (*nptr >= '0' && *nptr <= '0' + max_digit)
|
||||
digval = *nptr - '0';
|
||||
else if (base == 16)
|
||||
@ -159,9 +159,8 @@ tunables_strtoul (const char *nptr)
|
||||
else
|
||||
break;
|
||||
|
||||
if (result > ULONG_MAX / base
|
||||
|| (result == ULONG_MAX / base && digval > ULONG_MAX % base))
|
||||
return ULONG_MAX;
|
||||
if (result >= (UINT64_MAX - digval) / base)
|
||||
return UINT64_MAX;
|
||||
result *= base;
|
||||
result += digval;
|
||||
++nptr;
|
||||
@ -170,68 +169,50 @@ tunables_strtoul (const char *nptr)
|
||||
return result * sign;
|
||||
}
|
||||
|
||||
/* Initialize the internal type if the value validates either using the
|
||||
explicit constraints of the tunable or with the implicit constraints of its
|
||||
type. */
|
||||
static void
|
||||
tunable_set_val_if_valid_range_signed (tunable_t *cur, const char *strval,
|
||||
int64_t default_min, int64_t default_max)
|
||||
{
|
||||
int64_t val = (int64_t) tunables_strtoul (strval);
|
||||
|
||||
int64_t min = cur->type.min;
|
||||
int64_t max = cur->type.max;
|
||||
|
||||
if (min == max)
|
||||
{
|
||||
min = default_min;
|
||||
max = default_max;
|
||||
}
|
||||
|
||||
if (val >= min && val <= max)
|
||||
{
|
||||
cur->val.numval = val;
|
||||
cur->strval = strval;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tunable_set_val_if_valid_range_unsigned (tunable_t *cur, const char *strval,
|
||||
uint64_t default_min, uint64_t default_max)
|
||||
{
|
||||
uint64_t val = (uint64_t) tunables_strtoul (strval);
|
||||
|
||||
uint64_t min = cur->type.min;
|
||||
uint64_t max = cur->type.max;
|
||||
|
||||
if (min == max)
|
||||
{
|
||||
min = default_min;
|
||||
max = default_max;
|
||||
}
|
||||
|
||||
if (val >= min && val <= max)
|
||||
{
|
||||
cur->val.numval = val;
|
||||
cur->strval = strval;
|
||||
}
|
||||
}
|
||||
#define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type, __default_min, \
|
||||
__default_max) \
|
||||
({ \
|
||||
__type min = (__cur)->type.min; \
|
||||
__type max = (__cur)->type.max; \
|
||||
\
|
||||
if (min == max) \
|
||||
{ \
|
||||
min = __default_min; \
|
||||
max = __default_max; \
|
||||
} \
|
||||
\
|
||||
if ((__type) (__val) >= min && (__type) (val) <= max) \
|
||||
{ \
|
||||
(__cur)->val.numval = val; \
|
||||
(__cur)->strval = strval; \
|
||||
} \
|
||||
})
|
||||
|
||||
/* Validate range of the input value and initialize the tunable CUR if it looks
|
||||
good. */
|
||||
static void
|
||||
tunable_initialize (tunable_t *cur, const char *strval)
|
||||
{
|
||||
uint64_t val;
|
||||
|
||||
if (cur->type.type_code != TUNABLE_TYPE_STRING)
|
||||
val = tunables_strtoul (strval);
|
||||
|
||||
switch (cur->type.type_code)
|
||||
{
|
||||
case TUNABLE_TYPE_INT_32:
|
||||
{
|
||||
tunable_set_val_if_valid_range_signed (cur, strval, INT32_MIN, INT32_MAX);
|
||||
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t, INT32_MIN, INT32_MAX);
|
||||
break;
|
||||
}
|
||||
case TUNABLE_TYPE_UINT_64:
|
||||
{
|
||||
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t, 0, UINT64_MAX);
|
||||
break;
|
||||
}
|
||||
case TUNABLE_TYPE_SIZE_T:
|
||||
{
|
||||
tunable_set_val_if_valid_range_unsigned (cur, strval, 0, SIZE_MAX);
|
||||
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t, 0, SIZE_MAX);
|
||||
break;
|
||||
}
|
||||
case TUNABLE_TYPE_STRING:
|
||||
@ -461,6 +442,11 @@ __tunable_set_val (tunable_id_t id, void *valp, tunable_callback_t callback)
|
||||
|
||||
switch (cur->type.type_code)
|
||||
{
|
||||
case TUNABLE_TYPE_UINT_64:
|
||||
{
|
||||
*((uint64_t *) valp) = (uint64_t) cur->val.numval;
|
||||
break;
|
||||
}
|
||||
case TUNABLE_TYPE_INT_32:
|
||||
{
|
||||
*((int32_t *) valp) = (int32_t) cur->val.numval;
|
||||
|
Loading…
Reference in New Issue
Block a user