Fix a few more problem with the recent setxid changes.
[glibc.git] / nptl / sysdeps / pthread / createthread.c
blob8d96387a9af67c43fafe2d5bc8bb661ccca04900
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.
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.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
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>
28 #include "kernel-features.h"
31 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
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
39 #ifndef ARCH_CLONE
40 # define ARCH_CLONE __clone
41 #endif
44 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
45 /* Pointer to the corresponding variable in libc. */
46 int *__libc_multiple_threads_ptr attribute_hidden;
47 #endif
50 static int
51 do_clone (struct pthread *pd, const struct pthread_attr *attr,
52 int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
53 int stopped)
55 #ifdef PREPARE_CREATE
56 PREPARE_CREATE;
57 #endif
59 if (__builtin_expect (stopped != 0, 0))
60 /* We make sure the thread does not run far by forcing it to get a
61 lock. We lock it here too so that the new thread cannot continue
62 until we tell it to. */
63 lll_lock (pd->lock, LLL_PRIVATE);
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);
75 int rc = ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
76 pd, &pd->tid, TLS_VALUE, &pd->tid);
78 if (__builtin_expect (rc == -1, 0))
80 atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */
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);
88 /* Free the resources. */
89 __deallocate_stack (pd);
91 /* We have to translate error codes. */
92 return errno == ENOMEM ? EAGAIN : errno;
95 /* Now we have the possibility to set scheduling parameters etc. */
96 if (__builtin_expect (stopped != 0, 0))
98 INTERNAL_SYSCALL_DECL (err);
99 int res = 0;
101 /* Set the affinity mask if necessary. */
102 if (attr->cpuset != NULL)
104 res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
105 attr->cpusetsize, attr->cpuset);
107 if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
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:
113 #if __ASSUME_TGKILL
114 (void) INTERNAL_SYSCALL (tgkill, err2, 3,
115 THREAD_GETMEM (THREAD_SELF, pid),
116 pd->tid, SIGCANCEL);
117 #else
118 (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
119 #endif
121 /* We do not free the stack here because the canceled thread
122 itself will do this. */
124 return (INTERNAL_SYSCALL_ERROR_P (res, err)
125 ? INTERNAL_SYSCALL_ERRNO (res, err)
126 : 0);
130 /* Set the scheduling parameters. */
131 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
133 res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
134 pd->schedpolicy, &pd->schedparam);
136 if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
137 goto err_out;
141 /* We now have for sure more than one thread. The main thread might
142 not yet have the flag set. No need to set the global variable
143 again if this is what we use. */
144 THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
146 return 0;
150 static int
151 create_thread (struct pthread *pd, const struct pthread_attr *attr,
152 STACK_VARIABLES_PARMS)
154 #ifdef TLS_TCB_AT_TP
155 assert (pd->header.tcb != NULL);
156 #endif
158 /* We rely heavily on various flags the CLONE function understands:
160 CLONE_VM, CLONE_FS, CLONE_FILES
161 These flags select semantics with shared address space and
162 file descriptors according to what POSIX requires.
164 CLONE_SIGNAL
165 This flag selects the POSIX signal semantics.
167 CLONE_SETTLS
168 The sixth parameter to CLONE determines the TLS area for the
169 new thread.
171 CLONE_PARENT_SETTID
172 The kernels writes the thread ID of the newly created thread
173 into the location pointed to by the fifth parameters to CLONE.
175 Note that it would be semantically equivalent to use
176 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
178 CLONE_CHILD_CLEARTID
179 The kernels clears the thread ID of a thread that has called
180 sys_exit() in the location pointed to by the seventh parameter
181 to CLONE.
183 CLONE_DETACHED
184 No signal is generated if the thread exists and it is
185 automatically reaped.
187 The termination signal is chosen to be zero which means no signal
188 is sent. */
189 int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
190 | CLONE_SETTLS | CLONE_PARENT_SETTID
191 | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
192 #if __ASSUME_NO_CLONE_DETACHED == 0
193 | CLONE_DETACHED
194 #endif
195 | 0);
197 if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
199 /* The parent thread is supposed to report events. Check whether
200 the TD_CREATE event is needed, too. */
201 const int _idx = __td_eventword (TD_CREATE);
202 const uint32_t _mask = __td_eventmask (TD_CREATE);
204 if ((_mask & (__nptl_threads_events.event_bits[_idx]
205 | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
207 /* We always must have the thread start stopped. */
208 pd->stopped_start = true;
210 /* Create the thread. We always create the thread stopped
211 so that it does not get far before we tell the debugger. */
212 int res = do_clone (pd, attr, clone_flags, start_thread,
213 STACK_VARIABLES_ARGS, 1);
214 if (res == 0)
216 /* Now fill in the information about the new thread in
217 the newly created thread's data structure. We cannot let
218 the new thread do this since we don't know whether it was
219 already scheduled when we send the event. */
220 pd->eventbuf.eventnum = TD_CREATE;
221 pd->eventbuf.eventdata = pd;
223 /* Enqueue the descriptor. */
225 pd->nextevent = __nptl_last_event;
226 while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
227 pd, pd->nextevent)
228 != 0);
230 /* Now call the function which signals the event. */
231 __nptl_create_event ();
233 /* And finally restart the new thread. */
234 lll_unlock (pd->lock, LLL_PRIVATE);
237 return res;
241 #ifdef NEED_DL_SYSINFO
242 assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd));
243 #endif
245 /* Determine whether the newly created threads has to be started
246 stopped since we have to set the scheduling parameters or set the
247 affinity. */
248 bool stopped = false;
249 if (attr != NULL && (attr->cpuset != NULL
250 || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
251 stopped = true;
252 pd->stopped_start = stopped;
253 pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
255 /* Actually create the thread. */
256 int res = do_clone (pd, attr, clone_flags, start_thread,
257 STACK_VARIABLES_ARGS, stopped);
259 if (res == 0 && stopped)
260 /* And finally restart the new thread. */
261 lll_unlock (pd->lock, LLL_PRIVATE);
263 return res;