]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/sysdeps/pthread/createthread.c
Fix two stray cases using #ifdef vs #if for TLS_TCB_AT_TP.
[thirdparty/glibc.git] / nptl / sysdeps / pthread / createthread.c
CommitLineData
d4697bc9 1/* Copyright (C) 2002-2014 Free Software Foundation, Inc.
e6ebd2e4
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
59ba27a6
PE
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
e6ebd2e4
UD
18
19#include <sched.h>
20#include <setjmp.h>
21#include <signal.h>
22#include <stdlib.h>
23#include <atomic.h>
24#include <ldsodefs.h>
25#include <tls.h>
e054f494 26#include <stdint.h>
e6ebd2e4 27
f1205aa7
UD
28#include "kernel-features.h"
29
e6ebd2e4 30
66f1b8ee 31#define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
e6ebd2e4
UD
32
33/* Unless otherwise specified, the thread "register" is going to be
34 initialized with a pointer to the TCB. */
35#ifndef TLS_VALUE
36# define TLS_VALUE pd
37#endif
38
5d5d5969
RM
39#ifndef ARCH_CLONE
40# define ARCH_CLONE __clone
41#endif
42
e6ebd2e4 43
5a03acfe 44#ifndef TLS_MULTIPLE_THREADS_IN_TCB
5a03acfe
UD
45/* Pointer to the corresponding variable in libc. */
46int *__libc_multiple_threads_ptr attribute_hidden;
47#endif
48
49
e6ebd2e4 50static int
9d79e037 51do_clone (struct pthread *pd, const struct pthread_attr *attr,
a2c33d5a
UD
52 int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
53 int stopped)
e6ebd2e4
UD
54{
55#ifdef PREPARE_CREATE
56 PREPARE_CREATE;
57#endif
58
a1ffb40e 59 if (__glibc_unlikely (stopped != 0))
0f7e0ee5 60 /* We make sure the thread does not run far by forcing it to get a
f1205aa7
UD
61 lock. We lock it here too so that the new thread cannot continue
62 until we tell it to. */
e51deae7 63 lll_lock (pd->lock, LLL_PRIVATE);
f1205aa7 64
fd5d6a62
RM
65 /* One more thread. We cannot have the thread do this itself, since it
66 might exist but not have been scheduled yet by the time we've returned
67 and need to check the value to behave correctly. We must do it before
68 creating the thread, in case it does get scheduled first and then
69 might mistakenly think it was the only thread. In the failure case,
70 we momentarily store a false value; this doesn't matter because there
71 is no kosher thing a signal handler interrupting us right here can do
72 that cares whether the thread count is correct. */
73 atomic_increment (&__nptl_nthreads);
74
66f1b8ee
UD
75 int rc = ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
76 pd, &pd->tid, TLS_VALUE, &pd->tid);
77
a1ffb40e 78 if (__glibc_unlikely (rc == -1))
3f80a99b 79 {
fd5d6a62
RM
80 atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */
81
1d78f299
UD
82 /* Perhaps a thread wants to change the IDs and if waiting
83 for this stillborn thread. */
84 if (__builtin_expect (atomic_exchange_acq (&pd->setxid_futex, 0)
85 == -2, 0))
86 lll_futex_wake (&pd->setxid_futex, 1, LLL_PRIVATE);
87
88 /* Free the resources. */
3f80a99b
UD
89 __deallocate_stack (pd);
90
0f7e0ee5
UD
91 /* We have to translate error codes. */
92 return errno == ENOMEM ? EAGAIN : errno;
3f80a99b 93 }
e6ebd2e4 94
80f536db 95 /* Now we have the possibility to set scheduling parameters etc. */
a1ffb40e 96 if (__glibc_unlikely (stopped != 0))
e6ebd2e4 97 {
80f536db
UD
98 INTERNAL_SYSCALL_DECL (err);
99 int res = 0;
e6ebd2e4 100
80f536db
UD
101 /* Set the affinity mask if necessary. */
102 if (attr->cpuset != NULL)
e6ebd2e4 103 {
80f536db 104 res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
7c0ad164 105 attr->cpusetsize, attr->cpuset);
e6ebd2e4 106
a1ffb40e 107 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
9c988b83
UD
108 {
109 /* The operation failed. We have to kill the thread. First
110 send it the cancellation signal. */
111 INTERNAL_SYSCALL_DECL (err2);
112 err_out:
14ffbc83
UD
113 (void) INTERNAL_SYSCALL (tgkill, err2, 3,
114 THREAD_GETMEM (THREAD_SELF, pid),
115 pd->tid, SIGCANCEL);
9c988b83 116
1d78f299
UD
117 /* We do not free the stack here because the canceled thread
118 itself will do this. */
119
3f80a99b
UD
120 return (INTERNAL_SYSCALL_ERROR_P (res, err)
121 ? INTERNAL_SYSCALL_ERRNO (res, err)
122 : 0);
9c988b83 123 }
80f536db
UD
124 }
125
126 /* Set the scheduling parameters. */
127 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
128 {
5c5252bd
UD
129 res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
130 pd->schedpolicy, &pd->schedparam);
80f536db 131
a1ffb40e 132 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
5c5252bd 133 goto err_out;
80f536db 134 }
e6ebd2e4
UD
135 }
136
80f536db
UD
137 /* We now have for sure more than one thread. The main thread might
138 not yet have the flag set. No need to set the global variable
139 again if this is what we use. */
140 THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
141
142 return 0;
143}
144
145
146static int
9d79e037 147create_thread (struct pthread *pd, const struct pthread_attr *attr,
80f536db
UD
148 STACK_VARIABLES_PARMS)
149{
d7329d4b 150#if TLS_TCB_AT_TP
80f536db 151 assert (pd->header.tcb != NULL);
e6ebd2e4
UD
152#endif
153
154 /* We rely heavily on various flags the CLONE function understands:
155
156 CLONE_VM, CLONE_FS, CLONE_FILES
157 These flags select semantics with shared address space and
158 file descriptors according to what POSIX requires.
159
160 CLONE_SIGNAL
161 This flag selects the POSIX signal semantics.
162
163 CLONE_SETTLS
164 The sixth parameter to CLONE determines the TLS area for the
165 new thread.
166
167 CLONE_PARENT_SETTID
168 The kernels writes the thread ID of the newly created thread
169 into the location pointed to by the fifth parameters to CLONE.
170
171 Note that it would be semantically equivalent to use
172 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
173
174 CLONE_CHILD_CLEARTID
175 The kernels clears the thread ID of a thread that has called
a05be180
UD
176 sys_exit() in the location pointed to by the seventh parameter
177 to CLONE.
e6ebd2e4 178
e6ebd2e4
UD
179 The termination signal is chosen to be zero which means no signal
180 is sent. */
80f536db
UD
181 int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
182 | CLONE_SETTLS | CLONE_PARENT_SETTID
5673ccc1 183 | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
80f536db
UD
184 | 0);
185
a1ffb40e 186 if (__glibc_unlikely (THREAD_GETMEM (THREAD_SELF, report_events)))
80f536db
UD
187 {
188 /* The parent thread is supposed to report events. Check whether
189 the TD_CREATE event is needed, too. */
190 const int _idx = __td_eventword (TD_CREATE);
191 const uint32_t _mask = __td_eventmask (TD_CREATE);
e6ebd2e4 192
80f536db
UD
193 if ((_mask & (__nptl_threads_events.event_bits[_idx]
194 | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
195 {
5f66b766
UD
196 /* We always must have the thread start stopped. */
197 pd->stopped_start = true;
198
f1205aa7
UD
199 /* Create the thread. We always create the thread stopped
200 so that it does not get far before we tell the debugger. */
a2c33d5a
UD
201 int res = do_clone (pd, attr, clone_flags, start_thread,
202 STACK_VARIABLES_ARGS, 1);
80f536db
UD
203 if (res == 0)
204 {
205 /* Now fill in the information about the new thread in
206 the newly created thread's data structure. We cannot let
207 the new thread do this since we don't know whether it was
208 already scheduled when we send the event. */
209 pd->eventbuf.eventnum = TD_CREATE;
210 pd->eventbuf.eventdata = pd;
211
212 /* Enqueue the descriptor. */
213 do
214 pd->nextevent = __nptl_last_event;
215 while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
216 pd, pd->nextevent)
217 != 0);
218
219 /* Now call the function which signals the event. */
220 __nptl_create_event ();
221
222 /* And finally restart the new thread. */
e51deae7 223 lll_unlock (pd->lock, LLL_PRIVATE);
80f536db
UD
224 }
225
226 return res;
227 }
228 }
229
230#ifdef NEED_DL_SYSINFO
a2c33d5a 231 assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd));
80f536db
UD
232#endif
233
a2c33d5a
UD
234 /* Determine whether the newly created threads has to be started
235 stopped since we have to set the scheduling parameters or set the
236 affinity. */
5f66b766 237 bool stopped = false;
a2c33d5a
UD
238 if (attr != NULL && (attr->cpuset != NULL
239 || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
5f66b766
UD
240 stopped = true;
241 pd->stopped_start = stopped;
b051fc44 242 pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
a2c33d5a 243
80f536db 244 /* Actually create the thread. */
f1205aa7 245 int res = do_clone (pd, attr, clone_flags, start_thread,
a2c33d5a 246 STACK_VARIABLES_ARGS, stopped);
f1205aa7 247
a2c33d5a
UD
248 if (res == 0 && stopped)
249 /* And finally restart the new thread. */
e51deae7 250 lll_unlock (pd->lock, LLL_PRIVATE);
f1205aa7
UD
251
252 return res;
e6ebd2e4 253}