1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-07-30 22:43:12 +03: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:
Siddhesh Poyarekar
2017-05-17 13:11:55 +05:30
parent d13103074a
commit ad2f35cb39
4 changed files with 55 additions and 55 deletions

View File

@ -1,5 +1,17 @@
2017-05-17 Siddhesh Poyarekar <siddhesh@sourceware.org> 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 * scripts/gen-tunables.awk: Recognize 'default' keyword in
dl-tunables.list. dl-tunables.list.
* README.tunables: Document it. * README.tunables: Document it.

View File

@ -48,7 +48,8 @@ TOP_NAMESPACE {
The list of allowed attributes are: The list of allowed attributes are:
- type: Data type. Defaults to STRING. Allowed types 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 - minval: Optional minimum acceptable value. For a string type
this is the minimum length of the value. this is the minimum length of the value.

View File

@ -24,6 +24,7 @@
typedef enum typedef enum
{ {
TUNABLE_TYPE_INT_32, TUNABLE_TYPE_INT_32,
TUNABLE_TYPE_UINT_64,
TUNABLE_TYPE_SIZE_T, TUNABLE_TYPE_SIZE_T,
TUNABLE_TYPE_STRING TUNABLE_TYPE_STRING
} tunable_type_code_t; } tunable_type_code_t;

View File

@ -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 /* 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 set errno if the result is outside bounds because it gets called before
errno may have been set up. */ errno may have been set up. */
static unsigned long int static uint64_t
tunables_strtoul (const char *nptr) tunables_strtoul (const char *nptr)
{ {
unsigned long int result = 0; uint64_t result = 0;
long int sign = 1; long int sign = 1;
unsigned max_digit; unsigned max_digit;
@ -144,7 +144,7 @@ tunables_strtoul (const char *nptr)
while (1) while (1)
{ {
unsigned long int digval; int digval;
if (*nptr >= '0' && *nptr <= '0' + max_digit) if (*nptr >= '0' && *nptr <= '0' + max_digit)
digval = *nptr - '0'; digval = *nptr - '0';
else if (base == 16) else if (base == 16)
@ -159,9 +159,8 @@ tunables_strtoul (const char *nptr)
else else
break; break;
if (result > ULONG_MAX / base if (result >= (UINT64_MAX - digval) / base)
|| (result == ULONG_MAX / base && digval > ULONG_MAX % base)) return UINT64_MAX;
return ULONG_MAX;
result *= base; result *= base;
result += digval; result += digval;
++nptr; ++nptr;
@ -170,68 +169,50 @@ tunables_strtoul (const char *nptr)
return result * sign; return result * sign;
} }
/* Initialize the internal type if the value validates either using the #define TUNABLE_SET_VAL_IF_VALID_RANGE(__cur, __val, __type, __default_min, \
explicit constraints of the tunable or with the implicit constraints of its __default_max) \
type. */ ({ \
static void __type min = (__cur)->type.min; \
tunable_set_val_if_valid_range_signed (tunable_t *cur, const char *strval, __type max = (__cur)->type.max; \
int64_t default_min, int64_t default_max) \
{ if (min == max) \
int64_t val = (int64_t) tunables_strtoul (strval); { \
min = __default_min; \
int64_t min = cur->type.min; max = __default_max; \
int64_t max = cur->type.max; } \
\
if (min == max) if ((__type) (__val) >= min && (__type) (val) <= max) \
{ { \
min = default_min; (__cur)->val.numval = val; \
max = default_max; (__cur)->strval = strval; \
} } \
})
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;
}
}
/* Validate range of the input value and initialize the tunable CUR if it looks /* Validate range of the input value and initialize the tunable CUR if it looks
good. */ good. */
static void static void
tunable_initialize (tunable_t *cur, const char *strval) 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) switch (cur->type.type_code)
{ {
case TUNABLE_TYPE_INT_32: 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; break;
} }
case TUNABLE_TYPE_SIZE_T: 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; break;
} }
case TUNABLE_TYPE_STRING: 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) switch (cur->type.type_code)
{ {
case TUNABLE_TYPE_UINT_64:
{
*((uint64_t *) valp) = (uint64_t) cur->val.numval;
break;
}
case TUNABLE_TYPE_INT_32: case TUNABLE_TYPE_INT_32:
{ {
*((int32_t *) valp) = (int32_t) cur->val.numval; *((int32_t *) valp) = (int32_t) cur->val.numval;