1 /* Low-level thread creation for NPTL. Linux version.
2 Copyright (C) 2002-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
29 #include <arch-fork.h>
33 # define ARCH_CLONE __clone
36 /* See the comments in pthread_create.c for the requirements for these
37 two macros and the create_thread function. */
39 #define START_THREAD_DEFN \
40 static int __attribute__ ((noreturn)) start_thread (void *arg)
41 #define START_THREAD_SELF arg
43 /* pthread_create.c defines this using START_THREAD_DEFN
44 We need a forward declaration here so we can take its address. */
45 static int start_thread (void *arg
) __attribute__ ((noreturn
));
48 create_thread (struct pthread
*pd
, const struct pthread_attr
*attr
,
49 bool *stopped_start
, STACK_VARIABLES_PARMS
, bool *thread_ran
)
51 /* Determine whether the newly created threads has to be started
52 stopped since we have to set the scheduling parameters or set the
55 && (__glibc_unlikely (attr
->cpuset
!= NULL
)
56 || __glibc_unlikely ((attr
->flags
& ATTR_FLAG_NOTINHERITSCHED
) != 0)))
57 *stopped_start
= true;
59 pd
->stopped_start
= *stopped_start
;
60 if (__glibc_unlikely (*stopped_start
))
61 /* See CONCURRENCY NOTES in nptl/pthread_creat.c. */
62 lll_lock (pd
->lock
, LLL_PRIVATE
);
64 /* We rely heavily on various flags the CLONE function understands:
66 CLONE_VM, CLONE_FS, CLONE_FILES
67 These flags select semantics with shared address space and
68 file descriptors according to what POSIX requires.
70 CLONE_SIGHAND, CLONE_THREAD
71 This flag selects the POSIX signal semantics and various
72 other kinds of sharing (itimers, POSIX timers, etc.).
75 The sixth parameter to CLONE determines the TLS area for the
79 The kernels writes the thread ID of the newly created thread
80 into the location pointed to by the fifth parameters to CLONE.
82 Note that it would be semantically equivalent to use
83 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
86 The kernels clears the thread ID of a thread that has called
87 sys_exit() in the location pointed to by the seventh parameter
90 The termination signal is chosen to be zero which means no signal
92 const int clone_flags
= (CLONE_VM
| CLONE_FS
| CLONE_FILES
| CLONE_SYSVSEM
93 | CLONE_SIGHAND
| CLONE_THREAD
94 | CLONE_SETTLS
| CLONE_PARENT_SETTID
95 | CLONE_CHILD_CLEARTID
98 TLS_DEFINE_INIT_TP (tp
, pd
);
100 if (__glibc_unlikely (ARCH_CLONE (&start_thread
, STACK_VARIABLES_ARGS
,
101 clone_flags
, pd
, &pd
->tid
, tp
, &pd
->tid
)
105 /* It's started now, so if we fail below, we'll have to cancel it
106 and let it clean itself up. */
109 /* Now we have the possibility to set scheduling parameters etc. */
112 INTERNAL_SYSCALL_DECL (err
);
115 /* Set the affinity mask if necessary. */
116 if (attr
->cpuset
!= NULL
)
118 assert (*stopped_start
);
120 res
= INTERNAL_SYSCALL (sched_setaffinity
, err
, 3, pd
->tid
,
121 attr
->cpusetsize
, attr
->cpuset
);
123 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res
, err
)))
126 /* The operation failed. We have to kill the thread.
127 We let the normal cancellation mechanism do the work. */
129 pid_t pid
= __getpid ();
130 INTERNAL_SYSCALL_DECL (err2
);
131 (void) INTERNAL_SYSCALL_CALL (tgkill
, err2
, pid
, pd
->tid
,
134 return INTERNAL_SYSCALL_ERRNO (res
, err
);
138 /* Set the scheduling parameters. */
139 if ((attr
->flags
& ATTR_FLAG_NOTINHERITSCHED
) != 0)
141 assert (*stopped_start
);
143 res
= INTERNAL_SYSCALL (sched_setscheduler
, err
, 3, pd
->tid
,
144 pd
->schedpolicy
, &pd
->schedparam
);
146 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res
, err
)))