diff options
Diffstat (limited to 'sysdeps/unix/sysv/linux/createthread.c')
-rw-r--r-- | sysdeps/unix/sysv/linux/createthread.c | 29 |
1 files changed, 14 insertions, 15 deletions
diff --git a/sysdeps/unix/sysv/linux/createthread.c b/sysdeps/unix/sysv/linux/createthread.c index 6d32cece48..5879e51bd2 100644 --- a/sysdeps/unix/sysv/linux/createthread.c +++ b/sysdeps/unix/sysv/linux/createthread.c @@ -1,5 +1,5 @@ /* Low-level thread creation for NPTL. Linux version. - Copyright (C) 2002-2016 Free Software Foundation, Inc. + Copyright (C) 2002-2018 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -28,8 +28,9 @@ #include <arch-fork.h> - -#ifndef ARCH_CLONE +#ifdef __NR_clone2 +# define ARCH_CLONE __clone2 +#else # define ARCH_CLONE __clone #endif @@ -46,7 +47,7 @@ static int start_thread (void *arg) __attribute__ ((noreturn)); static int create_thread (struct pthread *pd, const struct pthread_attr *attr, - bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran) + bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran) { /* Determine whether the newly created threads has to be started stopped since we have to set the scheduling parameters or set the @@ -54,13 +55,11 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, if (attr != NULL && (__glibc_unlikely (attr->cpuset != NULL) || __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))) - stopped_start = true; + *stopped_start = true; - pd->stopped_start = stopped_start; - if (__glibc_unlikely (stopped_start)) - /* We make sure the thread does not run far by forcing it to get a - lock. We lock it here too so that the new thread cannot continue - until we tell it to. */ + pd->stopped_start = *stopped_start; + if (__glibc_unlikely (*stopped_start)) + /* See CONCURRENCY NOTES in nptl/pthread_creat.c. */ lll_lock (pd->lock, LLL_PRIVATE); /* We rely heavily on various flags the CLONE function understands: @@ -117,7 +116,7 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, /* Set the affinity mask if necessary. */ if (attr->cpuset != NULL) { - assert (stopped_start); + assert (*stopped_start); res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid, attr->cpusetsize, attr->cpuset); @@ -128,10 +127,10 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, /* The operation failed. We have to kill the thread. We let the normal cancellation mechanism do the work. */ + pid_t pid = __getpid (); INTERNAL_SYSCALL_DECL (err2); - (void) INTERNAL_SYSCALL (tgkill, err2, 3, - THREAD_GETMEM (THREAD_SELF, pid), - pd->tid, SIGCANCEL); + (void) INTERNAL_SYSCALL_CALL (tgkill, err2, pid, pd->tid, + SIGCANCEL); return INTERNAL_SYSCALL_ERRNO (res, err); } @@ -140,7 +139,7 @@ create_thread (struct pthread *pd, const struct pthread_attr *attr, /* Set the scheduling parameters. */ if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0) { - assert (stopped_start); + assert (*stopped_start); res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid, pd->schedpolicy, &pd->schedparam); |