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