]> git.ipfire.org Git - thirdparty/glibc.git/blob - sysdeps/unix/sysv/linux/createthread.c
Update copyright dates with scripts/update-copyrights
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / createthread.c
1 /* Low-level thread creation for NPTL. Linux version.
2 Copyright (C) 2002-2021 Free Software Foundation, Inc.
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
17 License along with the GNU C Library; if not, see
18 <https://www.gnu.org/licenses/>. */
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>
27 #include <stdint.h>
28
29 #include <arch-fork.h>
30
31 #ifdef __NR_clone2
32 # define ARCH_CLONE __clone2
33 #else
34 # define ARCH_CLONE __clone
35 #endif
36
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. */
46 static int start_thread (void *arg) __attribute__ ((noreturn));
47
48 static int
49 create_thread (struct pthread *pd, const struct pthread_attr *attr,
50 bool *stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
51 {
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 bool need_setaffinity = (attr != NULL && attr->extension != NULL
56 && attr->extension->cpuset != 0);
57 if (attr != NULL
58 && (__glibc_unlikely (need_setaffinity)
59 || __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)))
60 *stopped_start = true;
61
62 pd->stopped_start = *stopped_start;
63 if (__glibc_unlikely (*stopped_start))
64 /* See CONCURRENCY NOTES in nptl/pthread_creat.c. */
65 lll_lock (pd->lock, LLL_PRIVATE);
66
67 /* We rely heavily on various flags the CLONE function understands:
68
69 CLONE_VM, CLONE_FS, CLONE_FILES
70 These flags select semantics with shared address space and
71 file descriptors according to what POSIX requires.
72
73 CLONE_SIGHAND, CLONE_THREAD
74 This flag selects the POSIX signal semantics and various
75 other kinds of sharing (itimers, POSIX timers, etc.).
76
77 CLONE_SETTLS
78 The sixth parameter to CLONE determines the TLS area for the
79 new thread.
80
81 CLONE_PARENT_SETTID
82 The kernels writes the thread ID of the newly created thread
83 into the location pointed to by the fifth parameters to CLONE.
84
85 Note that it would be semantically equivalent to use
86 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
87
88 CLONE_CHILD_CLEARTID
89 The kernels clears the thread ID of a thread that has called
90 sys_exit() in the location pointed to by the seventh parameter
91 to CLONE.
92
93 The termination signal is chosen to be zero which means no signal
94 is sent. */
95 const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM
96 | CLONE_SIGHAND | CLONE_THREAD
97 | CLONE_SETTLS | CLONE_PARENT_SETTID
98 | CLONE_CHILD_CLEARTID
99 | 0);
100
101 TLS_DEFINE_INIT_TP (tp, pd);
102
103 if (__glibc_unlikely (ARCH_CLONE (&start_thread, STACK_VARIABLES_ARGS,
104 clone_flags, pd, &pd->tid, tp, &pd->tid)
105 == -1))
106 return errno;
107
108 /* It's started now, so if we fail below, we'll have to cancel it
109 and let it clean itself up. */
110 *thread_ran = true;
111
112 /* Now we have the possibility to set scheduling parameters etc. */
113 if (attr != NULL)
114 {
115 int res;
116
117 /* Set the affinity mask if necessary. */
118 if (need_setaffinity)
119 {
120 assert (*stopped_start);
121
122 res = INTERNAL_SYSCALL_CALL (sched_setaffinity, pd->tid,
123 attr->extension->cpusetsize,
124 attr->extension->cpuset);
125
126 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res)))
127 err_out:
128 {
129 /* The operation failed. We have to kill the thread.
130 We let the normal cancellation mechanism do the work. */
131
132 pid_t pid = __getpid ();
133 INTERNAL_SYSCALL_CALL (tgkill, pid, pd->tid, SIGCANCEL);
134
135 return INTERNAL_SYSCALL_ERRNO (res);
136 }
137 }
138
139 /* Set the scheduling parameters. */
140 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
141 {
142 assert (*stopped_start);
143
144 res = INTERNAL_SYSCALL_CALL (sched_setscheduler, pd->tid,
145 pd->schedpolicy, &pd->schedparam);
146
147 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res)))
148 goto err_out;
149 }
150 }
151
152 return 0;
153 }