mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-30 22:43:12 +03:00
Set tunable value as well as min/max values
Some tunable values and their minimum/maximum values must be determinted at run-time. Add TUNABLE_SET_WITH_BOUNDS and TUNABLE_SET_WITH_BOUNDS_FULL to update tunable value together with minimum and maximum values. __tunable_set_val is updated to set tunable value as well as min/max values.
This commit is contained in:
@ -100,8 +100,42 @@ get_next_env (char **envp, char **name, size_t *namelen, char **val,
|
|||||||
} \
|
} \
|
||||||
})
|
})
|
||||||
|
|
||||||
|
#define TUNABLE_SET_BOUNDS_IF_VALID(__cur, __minp, __maxp, __type) \
|
||||||
|
({ \
|
||||||
|
if (__minp != NULL) \
|
||||||
|
{ \
|
||||||
|
/* MIN is specified. */ \
|
||||||
|
__type min = *((__type *) __minp); \
|
||||||
|
if (__maxp != NULL) \
|
||||||
|
{ \
|
||||||
|
/* Both MIN and MAX are specified. */ \
|
||||||
|
__type max = *((__type *) __maxp); \
|
||||||
|
if (max >= min \
|
||||||
|
&& max <= (__cur)->type.max \
|
||||||
|
&& min >= (__cur)->type.min) \
|
||||||
|
{ \
|
||||||
|
(__cur)->type.min = min; \
|
||||||
|
(__cur)->type.max = max; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if (min > (__cur)->type.min && min <= (__cur)->type.max) \
|
||||||
|
{ \
|
||||||
|
/* Only MIN is specified. */ \
|
||||||
|
(__cur)->type.min = min; \
|
||||||
|
} \
|
||||||
|
} \
|
||||||
|
else if (__maxp != NULL) \
|
||||||
|
{ \
|
||||||
|
/* Only MAX is specified. */ \
|
||||||
|
__type max = *((__type *) __maxp); \
|
||||||
|
if (max < (__cur)->type.max && max >= (__cur)->type.min) \
|
||||||
|
(__cur)->type.max = max; \
|
||||||
|
} \
|
||||||
|
})
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_tunable_update_val (tunable_t *cur, const void *valp)
|
do_tunable_update_val (tunable_t *cur, const void *valp,
|
||||||
|
const void *minp, const void *maxp)
|
||||||
{
|
{
|
||||||
uint64_t val;
|
uint64_t val;
|
||||||
|
|
||||||
@ -112,16 +146,19 @@ do_tunable_update_val (tunable_t *cur, const void *valp)
|
|||||||
{
|
{
|
||||||
case TUNABLE_TYPE_INT_32:
|
case TUNABLE_TYPE_INT_32:
|
||||||
{
|
{
|
||||||
|
TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, int64_t);
|
||||||
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t);
|
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, int64_t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TUNABLE_TYPE_UINT_64:
|
case TUNABLE_TYPE_UINT_64:
|
||||||
{
|
{
|
||||||
|
TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, uint64_t);
|
||||||
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
|
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TUNABLE_TYPE_SIZE_T:
|
case TUNABLE_TYPE_SIZE_T:
|
||||||
{
|
{
|
||||||
|
TUNABLE_SET_BOUNDS_IF_VALID (cur, minp, maxp, uint64_t);
|
||||||
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
|
TUNABLE_SET_VAL_IF_VALID_RANGE (cur, val, uint64_t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -153,15 +190,15 @@ tunable_initialize (tunable_t *cur, const char *strval)
|
|||||||
cur->initialized = true;
|
cur->initialized = true;
|
||||||
valp = strval;
|
valp = strval;
|
||||||
}
|
}
|
||||||
do_tunable_update_val (cur, valp);
|
do_tunable_update_val (cur, valp, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
__tunable_set_val (tunable_id_t id, void *valp)
|
__tunable_set_val (tunable_id_t id, void *valp, void *minp, void *maxp)
|
||||||
{
|
{
|
||||||
tunable_t *cur = &tunable_list[id];
|
tunable_t *cur = &tunable_list[id];
|
||||||
|
|
||||||
do_tunable_update_val (cur, valp);
|
do_tunable_update_val (cur, valp, minp, maxp);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring
|
#if TUNABLES_FRONTEND == TUNABLES_FRONTEND_valstring
|
||||||
|
@ -70,9 +70,10 @@ typedef struct _tunable tunable_t;
|
|||||||
|
|
||||||
extern void __tunables_init (char **);
|
extern void __tunables_init (char **);
|
||||||
extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
|
extern void __tunable_get_val (tunable_id_t, void *, tunable_callback_t);
|
||||||
extern void __tunable_set_val (tunable_id_t, void *);
|
extern void __tunable_set_val (tunable_id_t, void *, void *, void *);
|
||||||
rtld_hidden_proto (__tunables_init)
|
rtld_hidden_proto (__tunables_init)
|
||||||
rtld_hidden_proto (__tunable_get_val)
|
rtld_hidden_proto (__tunable_get_val)
|
||||||
|
rtld_hidden_proto (__tunable_set_val)
|
||||||
|
|
||||||
/* Define TUNABLE_GET and TUNABLE_SET in short form if TOP_NAMESPACE and
|
/* Define TUNABLE_GET and TUNABLE_SET in short form if TOP_NAMESPACE and
|
||||||
TUNABLE_NAMESPACE are defined. This is useful shorthand to get and set
|
TUNABLE_NAMESPACE are defined. This is useful shorthand to get and set
|
||||||
@ -82,11 +83,18 @@ rtld_hidden_proto (__tunable_get_val)
|
|||||||
TUNABLE_GET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __cb)
|
TUNABLE_GET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __cb)
|
||||||
# define TUNABLE_SET(__id, __type, __val) \
|
# define TUNABLE_SET(__id, __type, __val) \
|
||||||
TUNABLE_SET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __val)
|
TUNABLE_SET_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, __type, __val)
|
||||||
|
# define TUNABLE_SET_WITH_BOUNDS(__id, __type, __val, __min, __max) \
|
||||||
|
TUNABLE_SET_WITH_BOUNDS_FULL (TOP_NAMESPACE, TUNABLE_NAMESPACE, __id, \
|
||||||
|
__type, __val, __min, __max)
|
||||||
#else
|
#else
|
||||||
# define TUNABLE_GET(__top, __ns, __id, __type, __cb) \
|
# define TUNABLE_GET(__top, __ns, __id, __type, __cb) \
|
||||||
TUNABLE_GET_FULL (__top, __ns, __id, __type, __cb)
|
TUNABLE_GET_FULL (__top, __ns, __id, __type, __cb)
|
||||||
# define TUNABLE_SET(__top, __ns, __id, __type, __val) \
|
# define TUNABLE_SET(__top, __ns, __id, __type, __val) \
|
||||||
TUNABLE_SET_FULL (__top, __ns, __id, __type, __val)
|
TUNABLE_SET_FULL (__top, __ns, __id, __type, __val)
|
||||||
|
# define TUNABLE_SET_WITH_BOUNDS(__top, __ns, __id, __type, __val, \
|
||||||
|
__min, __max) \
|
||||||
|
TUNABLE_SET_WITH_BOUNDS_FULL (__top, __ns, __id, __type, __val, \
|
||||||
|
__min, __max)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Get and return a tunable value. If the tunable was set externally and __CB
|
/* Get and return a tunable value. If the tunable was set externally and __CB
|
||||||
@ -103,7 +111,16 @@ rtld_hidden_proto (__tunable_get_val)
|
|||||||
# define TUNABLE_SET_FULL(__top, __ns, __id, __type, __val) \
|
# define TUNABLE_SET_FULL(__top, __ns, __id, __type, __val) \
|
||||||
({ \
|
({ \
|
||||||
__tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id), \
|
__tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id), \
|
||||||
& (__type) {__val}); \
|
& (__type) {__val}, NULL, NULL); \
|
||||||
|
})
|
||||||
|
|
||||||
|
/* Set a tunable value together with min/max values. */
|
||||||
|
# define TUNABLE_SET_WITH_BOUNDS_FULL(__top, __ns, __id, __type, __val, \
|
||||||
|
__min, __max) \
|
||||||
|
({ \
|
||||||
|
__tunable_set_val (TUNABLE_ENUM_NAME (__top, __ns, __id), \
|
||||||
|
& (__type) {__val}, & (__type) {__min}, \
|
||||||
|
& (__type) {__max}); \
|
||||||
})
|
})
|
||||||
|
|
||||||
/* Namespace sanity for callback functions. Use this macro to keep the
|
/* Namespace sanity for callback functions. Use this macro to keep the
|
||||||
|
@ -67,7 +67,7 @@ The list of allowed attributes are:
|
|||||||
non-AT_SECURE subprocesses.
|
non-AT_SECURE subprocesses.
|
||||||
NONE: Read all the time.
|
NONE: Read all the time.
|
||||||
|
|
||||||
2. Use TUNABLE_GET/TUNABLE_SET to get and set tunables.
|
2. Use TUNABLE_GET/TUNABLE_SET/TUNABLE_SET_WITH_BOUNDS to get and set tunables.
|
||||||
|
|
||||||
3. OPTIONAL: If tunables in a namespace are being used multiple times within a
|
3. OPTIONAL: If tunables in a namespace are being used multiple times within a
|
||||||
specific module, set the TUNABLE_NAMESPACE macro to reduce the amount of
|
specific module, set the TUNABLE_NAMESPACE macro to reduce the amount of
|
||||||
@ -112,9 +112,29 @@ form of the macros as follows:
|
|||||||
where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
|
where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
|
||||||
remaining arguments are the same as the short form macros.
|
remaining arguments are the same as the short form macros.
|
||||||
|
|
||||||
|
The minimum and maximum values can updated together with the tunable value
|
||||||
|
using:
|
||||||
|
|
||||||
|
TUNABLE_SET_WITH_BOUNDS (check, int32_t, val, min, max)
|
||||||
|
|
||||||
|
where 'check' is the tunable name, 'int32_t' is the C type of the tunable,
|
||||||
|
'val' is a value of same type, 'min' and 'max' are the minimum and maximum
|
||||||
|
values of the tunable.
|
||||||
|
|
||||||
|
To set the minimum and maximum values of tunables in a different namespace
|
||||||
|
from that module, use the full form of the macros as follows:
|
||||||
|
|
||||||
|
val = TUNABLE_GET_FULL (glibc, cpu, hwcap_mask, uint64_t, NULL)
|
||||||
|
|
||||||
|
TUNABLE_SET_WITH_BOUNDS_FULL (glibc, cpu, hwcap_mask, uint64_t, val, min, max)
|
||||||
|
|
||||||
|
where 'glibc' is the top namespace, 'cpu' is the tunable namespace and the
|
||||||
|
remaining arguments are the same as the short form macros.
|
||||||
|
|
||||||
When TUNABLE_NAMESPACE is not defined in a module, TUNABLE_GET is equivalent to
|
When TUNABLE_NAMESPACE is not defined in a module, TUNABLE_GET is equivalent to
|
||||||
TUNABLE_GET_FULL, so you will need to provide full namespace information for
|
TUNABLE_GET_FULL, so you will need to provide full namespace information for
|
||||||
both macros. Likewise for TUNABLE_SET and TUNABLE_SET_FULL.
|
both macros. Likewise for TUNABLE_SET, TUNABLE_SET_FULL,
|
||||||
|
TUNABLE_SET_WITH_BOUNDS and TUNABLE_SET_WITH_BOUNDS_FULL.
|
||||||
|
|
||||||
** IMPORTANT NOTE **
|
** IMPORTANT NOTE **
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user