mirror of
https://sourceware.org/git/glibc.git
synced 2025-08-01 10:06:57 +03:00
Consolidate pthread_attr value validation
Define inline functions that wrap around validation for each of the pthread attributes to reduce duplication in code.
This commit is contained in:
@ -1,3 +1,22 @@
|
|||||||
|
2013-04-22 Siddhesh Poyarekar <siddhesh@redhat.com>
|
||||||
|
|
||||||
|
* pthreadP.h (check_sched_policy_attr): New inline function.
|
||||||
|
(check_sched_priority_attr): Likewise.
|
||||||
|
(check_stacksize_attr): Likewise.
|
||||||
|
(__kernel_cpumask_size, __determine_cpumask_size): Declare
|
||||||
|
extern.
|
||||||
|
(check_cpuset_attr): New inline function.
|
||||||
|
* pthread_attr_setschedparam (__pthread_attr_setschedparam):
|
||||||
|
Use check_sched_priority_attr.
|
||||||
|
* pthread_attr_setschedpolicy.c
|
||||||
|
(__pthread_attr_setschedpolicy): Use check_sched_policy_attr.
|
||||||
|
* pthread_attr_setstack.c (__pthread_attr_setstack): Use
|
||||||
|
check_stacksize_attr.
|
||||||
|
* pthread_attr_setstacksize.c (__pthread_attr_setstacksize):
|
||||||
|
Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/pthread_attr_setaffinity.c
|
||||||
|
(__pthread_attr_setaffinity_new): Use check_cpuset_attr.
|
||||||
|
|
||||||
2013-04-11 Andreas Schwab <schwab@suse.de>
|
2013-04-11 Andreas Schwab <schwab@suse.de>
|
||||||
|
|
||||||
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
|
* sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
|
||||||
|
@ -31,7 +31,7 @@
|
|||||||
#include <pthread-functions.h>
|
#include <pthread-functions.h>
|
||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <kernel-features.h>
|
#include <kernel-features.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
/* Atomic operations on TLS memory. */
|
/* Atomic operations on TLS memory. */
|
||||||
#ifndef THREAD_ATOMIC_CMPXCHG_VAL
|
#ifndef THREAD_ATOMIC_CMPXCHG_VAL
|
||||||
@ -589,4 +589,66 @@ extern void __wait_lookup_done (void) attribute_hidden;
|
|||||||
# define USE_REQUEUE_PI(mut) 0
|
# define USE_REQUEUE_PI(mut) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Returns 0 if POL is a valid scheduling policy. */
|
||||||
|
static inline int
|
||||||
|
check_sched_policy_attr (int pol)
|
||||||
|
{
|
||||||
|
if (pol == SCHED_OTHER || pol == SCHED_FIFO || pol == SCHED_RR)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 0 if PR is within the accepted range of priority values for
|
||||||
|
the scheduling policy POL or EINVAL otherwise. */
|
||||||
|
static inline int
|
||||||
|
check_sched_priority_attr (int pr, int pol)
|
||||||
|
{
|
||||||
|
int min = __sched_get_priority_min (pol);
|
||||||
|
int max = __sched_get_priority_max (pol);
|
||||||
|
|
||||||
|
if (min >= 0 && max >= 0 && pr >= min && pr <= max)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Returns 0 if ST is a valid stack size for a thread stack and EINVAL
|
||||||
|
otherwise. */
|
||||||
|
static inline int
|
||||||
|
check_stacksize_attr (size_t st)
|
||||||
|
{
|
||||||
|
if (st >= PTHREAD_STACK_MIN)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Defined in pthread_setaffinity.c. */
|
||||||
|
extern size_t __kernel_cpumask_size attribute_hidden;
|
||||||
|
extern int __determine_cpumask_size (pid_t tid);
|
||||||
|
|
||||||
|
/* Returns 0 if CS and SZ are valid values for the cpuset and cpuset size
|
||||||
|
respectively. Otherwise it returns an error number. */
|
||||||
|
static inline int
|
||||||
|
check_cpuset_attr (const cpu_set_t *cs, const size_t sz)
|
||||||
|
{
|
||||||
|
if (__kernel_cpumask_size == 0)
|
||||||
|
{
|
||||||
|
int res = __determine_cpumask_size (THREAD_SELF->tid);
|
||||||
|
if (res)
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check whether the new bitmask has any bit set beyond the
|
||||||
|
last one the kernel accepts. */
|
||||||
|
for (size_t cnt = __kernel_cpumask_size; cnt < sz; ++cnt)
|
||||||
|
if (((char *) cs)[cnt] != '\0')
|
||||||
|
/* Found a nonzero byte. This means the user request cannot be
|
||||||
|
fulfilled. */
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* pthreadP.h */
|
#endif /* pthreadP.h */
|
||||||
|
@ -30,11 +30,10 @@ __pthread_attr_setschedparam (attr, param)
|
|||||||
assert (sizeof (*attr) >= sizeof (struct pthread_attr));
|
assert (sizeof (*attr) >= sizeof (struct pthread_attr));
|
||||||
struct pthread_attr *iattr = (struct pthread_attr *) attr;
|
struct pthread_attr *iattr = (struct pthread_attr *) attr;
|
||||||
|
|
||||||
int min = sched_get_priority_min (iattr->schedpolicy);
|
int ret = check_sched_priority_attr (param->sched_priority,
|
||||||
int max = sched_get_priority_max (iattr->schedpolicy);
|
iattr->schedpolicy);
|
||||||
if (min == -1 || max == -1
|
if (ret)
|
||||||
|| param->sched_priority > max || param->sched_priority < min)
|
return ret;
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
/* Copy the new values. */
|
/* Copy the new values. */
|
||||||
memcpy (&iattr->schedparam, param, sizeof (struct sched_param));
|
memcpy (&iattr->schedparam, param, sizeof (struct sched_param));
|
||||||
|
@ -32,8 +32,9 @@ __pthread_attr_setschedpolicy (attr, policy)
|
|||||||
iattr = (struct pthread_attr *) attr;
|
iattr = (struct pthread_attr *) attr;
|
||||||
|
|
||||||
/* Catch invalid values. */
|
/* Catch invalid values. */
|
||||||
if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
|
int ret = check_sched_policy_attr (policy);
|
||||||
return EINVAL;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
/* Store the new values. */
|
/* Store the new values. */
|
||||||
iattr->schedpolicy = policy;
|
iattr->schedpolicy = policy;
|
||||||
|
@ -39,8 +39,9 @@ __pthread_attr_setstack (attr, stackaddr, stacksize)
|
|||||||
iattr = (struct pthread_attr *) attr;
|
iattr = (struct pthread_attr *) attr;
|
||||||
|
|
||||||
/* Catch invalid sizes. */
|
/* Catch invalid sizes. */
|
||||||
if (stacksize < PTHREAD_STACK_MIN)
|
int ret = check_stacksize_attr (stacksize);
|
||||||
return EINVAL;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
#ifdef EXTRA_PARAM_CHECKS
|
#ifdef EXTRA_PARAM_CHECKS
|
||||||
EXTRA_PARAM_CHECKS;
|
EXTRA_PARAM_CHECKS;
|
||||||
|
@ -37,8 +37,9 @@ __pthread_attr_setstacksize (attr, stacksize)
|
|||||||
iattr = (struct pthread_attr *) attr;
|
iattr = (struct pthread_attr *) attr;
|
||||||
|
|
||||||
/* Catch invalid sizes. */
|
/* Catch invalid sizes. */
|
||||||
if (stacksize < PTHREAD_STACK_MIN)
|
int ret = check_stacksize_attr (stacksize);
|
||||||
return EINVAL;
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
iattr->stacksize = stacksize;
|
iattr->stacksize = stacksize;
|
||||||
|
|
||||||
|
@ -25,9 +25,6 @@
|
|||||||
#include <shlib-compat.h>
|
#include <shlib-compat.h>
|
||||||
|
|
||||||
|
|
||||||
/* Defined in pthread_setaffinity.c. */
|
|
||||||
extern size_t __kernel_cpumask_size attribute_hidden;
|
|
||||||
extern int __determine_cpumask_size (pid_t tid);
|
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -47,21 +44,10 @@ __pthread_attr_setaffinity_new (pthread_attr_t *attr, size_t cpusetsize,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (__kernel_cpumask_size == 0)
|
int ret = check_cpuset_attr (cpuset, cpusetsize);
|
||||||
{
|
|
||||||
int res = __determine_cpumask_size (THREAD_SELF->tid);
|
|
||||||
if (res != 0)
|
|
||||||
/* Some serious problem. */
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check whether the new bitmask has any bit set beyond the
|
if (ret)
|
||||||
last one the kernel accepts. */
|
return ret;
|
||||||
for (size_t cnt = __kernel_cpumask_size; cnt < cpusetsize; ++cnt)
|
|
||||||
if (((char *) cpuset)[cnt] != '\0')
|
|
||||||
/* Found a nonzero byte. This means the user request cannot be
|
|
||||||
fulfilled. */
|
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
if (iattr->cpusetsize != cpusetsize)
|
if (iattr->cpusetsize != cpusetsize)
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user