]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/createthread.c
Prefer https to http for gnu.org and fsf.org URLs
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / createthread.c
CommitLineData
32fed10f 1/* Low-level thread creation for NPTL. Linux version.
04277e02 2 Copyright (C) 2002-2019 Free Software Foundation, Inc.
e6ebd2e4
UD
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5
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.
10
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.
15
16 You should have received a copy of the GNU Lesser General Public
59ba27a6 17 License along with the GNU C Library; if not, see
5a82c748 18 <https://www.gnu.org/licenses/>. */
e6ebd2e4
UD
19
20#include <sched.h>
21#include <setjmp.h>
22#include <signal.h>
23#include <stdlib.h>
24#include <atomic.h>
25#include <ldsodefs.h>
26#include <tls.h>
e054f494 27#include <stdint.h>
e6ebd2e4 28
ca08746f
RM
29#include <arch-fork.h>
30
3dc21497
AZ
31#ifdef __NR_clone2
32# define ARCH_CLONE __clone2
33#else
5d5d5969
RM
34# define ARCH_CLONE __clone
35#endif
36
32fed10f
RM
37/* See the comments in pthread_create.c for the requirements for these
38 two macros and the create_thread function. */
39
40#define START_THREAD_DEFN \
41 static int __attribute__ ((noreturn)) start_thread (void *arg)
42#define START_THREAD_SELF arg
43
44/* pthread_create.c defines this using START_THREAD_DEFN
45 We need a forward declaration here so we can take its address. */
46static int start_thread (void *arg) __attribute__ ((noreturn));
e6ebd2e4
UD
47
48static int
32fed10f 49create_thread (struct pthread *pd, const struct pthread_attr *attr,
f8bf15fe 50 bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
e6ebd2e4 51{
32fed10f
RM
52 /* Determine whether the newly created threads has to be started
53 stopped since we have to set the scheduling parameters or set the
54 affinity. */
55 if (attr != NULL
56 && (__glibc_unlikely (attr->cpuset != NULL)
57 || __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)))
f8bf15fe 58 *stopped_start = true;
e6ebd2e4 59
f8bf15fe
CD
60 pd->stopped_start = *stopped_start;
61 if (__glibc_unlikely (*stopped_start))
62 /* See CONCURRENCY NOTES in nptl/pthread_creat.c. */
e51deae7 63 lll_lock (pd->lock, LLL_PRIVATE);
f1205aa7 64
32fed10f 65 /* We rely heavily on various flags the CLONE function understands:
fd5d6a62 66
32fed10f
RM
67 CLONE_VM, CLONE_FS, CLONE_FILES
68 These flags select semantics with shared address space and
69 file descriptors according to what POSIX requires.
66f1b8ee 70
32fed10f
RM
71 CLONE_SIGHAND, CLONE_THREAD
72 This flag selects the POSIX signal semantics and various
73 other kinds of sharing (itimers, POSIX timers, etc.).
fd5d6a62 74
32fed10f
RM
75 CLONE_SETTLS
76 The sixth parameter to CLONE determines the TLS area for the
77 new thread.
1d78f299 78
32fed10f
RM
79 CLONE_PARENT_SETTID
80 The kernels writes the thread ID of the newly created thread
81 into the location pointed to by the fifth parameters to CLONE.
3f80a99b 82
32fed10f
RM
83 Note that it would be semantically equivalent to use
84 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
85
86 CLONE_CHILD_CLEARTID
87 The kernels clears the thread ID of a thread that has called
88 sys_exit() in the location pointed to by the seventh parameter
89 to CLONE.
90
91 The termination signal is chosen to be zero which means no signal
92 is sent. */
93 const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM
94 | CLONE_SIGHAND | CLONE_THREAD
95 | CLONE_SETTLS | CLONE_PARENT_SETTID
96 | CLONE_CHILD_CLEARTID
97 | 0);
98
99 TLS_DEFINE_INIT_TP (tp, pd);
100
101 if (__glibc_unlikely (ARCH_CLONE (&start_thread, STACK_VARIABLES_ARGS,
102 clone_flags, pd, &pd->tid, tp, &pd->tid)
103 == -1))
104 return errno;
105
106 /* It's started now, so if we fail below, we'll have to cancel it
107 and let it clean itself up. */
108 *thread_ran = true;
e6ebd2e4 109
80f536db 110 /* Now we have the possibility to set scheduling parameters etc. */
32fed10f 111 if (attr != NULL)
e6ebd2e4 112 {
80f536db 113 INTERNAL_SYSCALL_DECL (err);
32fed10f 114 int res;
e6ebd2e4 115
80f536db
UD
116 /* Set the affinity mask if necessary. */
117 if (attr->cpuset != NULL)
e6ebd2e4 118 {
f8bf15fe 119 assert (*stopped_start);
32fed10f 120
80f536db 121 res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
7c0ad164 122 attr->cpusetsize, attr->cpuset);
e6ebd2e4 123
a1ffb40e 124 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
32fed10f 125 err_out:
9c988b83 126 {
32fed10f
RM
127 /* The operation failed. We have to kill the thread.
128 We let the normal cancellation mechanism do the work. */
129
c579f48e 130 pid_t pid = __getpid ();
9c988b83 131 INTERNAL_SYSCALL_DECL (err2);
c579f48e
AZ
132 (void) INTERNAL_SYSCALL_CALL (tgkill, err2, pid, pd->tid,
133 SIGCANCEL);
9c988b83 134
32fed10f 135 return INTERNAL_SYSCALL_ERRNO (res, err);
9c988b83 136 }
80f536db
UD
137 }
138
139 /* Set the scheduling parameters. */
140 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
141 {
f8bf15fe 142 assert (*stopped_start);
32fed10f 143
5c5252bd
UD
144 res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
145 pd->schedpolicy, &pd->schedparam);
80f536db 146
a1ffb40e 147 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
5c5252bd 148 goto err_out;
80f536db 149 }
e6ebd2e4
UD
150 }
151
80f536db
UD
152 return 0;
153}