1
0
mirror of https://sourceware.org/git/glibc.git synced 2025-08-08 17:42:12 +03:00

nptl: Use exit_lock when accessing TID on pthread_setschedparam

Also return EINVAL if the thread is already terminated at the time
of the call.

The sched_getparam call is also replaced with a INTERNAL_SYSCALL_CALL
to avoid clobbering errno.

Checked on x86_64-linux-gnu.
This commit is contained in:
Adhemerval Zanella
2021-08-23 14:48:30 -03:00
parent 71a2526d28
commit f303d285c8
2 changed files with 34 additions and 23 deletions

View File

@@ -15,26 +15,15 @@
License along with the GNU C Library; if not, see License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */ <https://www.gnu.org/licenses/>. */
#include <errno.h> #include <libc-lock.h>
#include <sched.h> #include <kernel-posix-cpu-timers.h>
#include <string.h> #include <pthreadP.h>
#include "pthreadP.h"
#include <lowlevellock.h>
int static int
__pthread_setschedparam (pthread_t threadid, int policy, setschedparam (struct pthread *pd, int policy,
const struct sched_param *param) const struct sched_param *param)
{ {
struct pthread *pd = (struct pthread *) threadid;
/* Make sure the descriptor is valid. */
if (INVALID_TD_P (pd))
/* Not a valid thread handle. */
return ESRCH;
int result = 0;
/* See CREATE THREAD NOTES in nptl/pthread_create.c. */ /* See CREATE THREAD NOTES in nptl/pthread_create.c. */
lll_lock (pd->lock, LLL_PRIVATE); lll_lock (pd->lock, LLL_PRIVATE);
@@ -43,8 +32,7 @@ __pthread_setschedparam (pthread_t threadid, int policy,
/* If the thread should have higher priority because of some /* If the thread should have higher priority because of some
PTHREAD_PRIO_PROTECT mutexes it holds, adjust the priority. */ PTHREAD_PRIO_PROTECT mutexes it holds, adjust the priority. */
if (__builtin_expect (pd->tpp != NULL, 0) if (pd->tpp != NULL && pd->tpp->priomax > param->sched_priority)
&& pd->tpp->priomax > param->sched_priority)
{ {
p = *param; p = *param;
p.sched_priority = pd->tpp->priomax; p.sched_priority = pd->tpp->priomax;
@@ -52,10 +40,8 @@ __pthread_setschedparam (pthread_t threadid, int policy,
} }
/* Try to set the scheduler information. */ /* Try to set the scheduler information. */
if (__builtin_expect (__sched_setscheduler (pd->tid, policy, int r = INTERNAL_SYSCALL_CALL (sched_setscheduler, pd->tid, policy, param);
param) == -1, 0)) if (r == 0)
result = errno;
else
{ {
/* We succeeded changing the kernel information. Reflect this /* We succeeded changing the kernel information. Reflect this
change in the thread descriptor. */ change in the thread descriptor. */
@@ -66,6 +52,25 @@ __pthread_setschedparam (pthread_t threadid, int policy,
lll_unlock (pd->lock, LLL_PRIVATE); lll_unlock (pd->lock, LLL_PRIVATE);
return -r;
}
int
__pthread_setschedparam (pthread_t threadid, int policy,
const struct sched_param *param)
{
struct pthread *pd = (struct pthread *) threadid;
/* Block all signals, as required by pd->exit_lock. */
internal_sigset_t old_mask;
internal_signal_block_all (&old_mask);
__libc_lock_lock (pd->exit_lock);
int result = pd->tid != 0 ? setschedparam (pd, policy, param) : EINVAL;
__libc_lock_unlock (pd->exit_lock);
internal_signal_restore_set (&old_mask);
return result; return result;
} }
strong_alias (__pthread_setschedparam, pthread_setschedparam) strong_alias (__pthread_setschedparam, pthread_setschedparam)

View File

@@ -50,6 +50,12 @@ do_test (void)
TEST_COMPARE (r, EINVAL); TEST_COMPARE (r, EINVAL);
} }
{
struct sched_param sch = { 0 };
int r = pthread_setschedparam (thr, SCHED_FIFO, &sch);
TEST_COMPARE (r, EINVAL);
}
xpthread_join (thr); xpthread_join (thr);
return 0; return 0;