NPTL: Clean up gratuitous Linuxism in libpthread.so entry point.
[glibc.git] / nptl / createthread.c
blob0980a7748b43bf245cbaba5d41a7aac56f7d7180
1 /* Copyright (C) 2002-2014 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, see
17 <http://www.gnu.org/licenses/>. */
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 #include <stdint.h>
28 #include <arch-fork.h>
31 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
34 #ifndef ARCH_CLONE
35 # define ARCH_CLONE __clone
36 #endif
39 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
40 /* Pointer to the corresponding variable in libc. */
41 int *__libc_multiple_threads_ptr attribute_hidden;
42 #endif
45 static int
46 do_clone (struct pthread *pd, const struct pthread_attr *attr,
47 int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
48 int stopped)
50 TLS_DEFINE_INIT_TP (tp, pd);
52 if (__glibc_unlikely (stopped != 0))
53 /* We make sure the thread does not run far by forcing it to get a
54 lock. We lock it here too so that the new thread cannot continue
55 until we tell it to. */
56 lll_lock (pd->lock, LLL_PRIVATE);
58 /* One more thread. We cannot have the thread do this itself, since it
59 might exist but not have been scheduled yet by the time we've returned
60 and need to check the value to behave correctly. We must do it before
61 creating the thread, in case it does get scheduled first and then
62 might mistakenly think it was the only thread. In the failure case,
63 we momentarily store a false value; this doesn't matter because there
64 is no kosher thing a signal handler interrupting us right here can do
65 that cares whether the thread count is correct. */
66 atomic_increment (&__nptl_nthreads);
68 int rc = ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
69 pd, &pd->tid, tp, &pd->tid);
71 if (__glibc_unlikely (rc == -1))
73 atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */
75 /* Perhaps a thread wants to change the IDs and if waiting
76 for this stillborn thread. */
77 if (__builtin_expect (atomic_exchange_acq (&pd->setxid_futex, 0)
78 == -2, 0))
79 lll_futex_wake (&pd->setxid_futex, 1, LLL_PRIVATE);
81 /* Free the resources. */
82 __deallocate_stack (pd);
84 /* We have to translate error codes. */
85 return errno == ENOMEM ? EAGAIN : errno;
88 /* Now we have the possibility to set scheduling parameters etc. */
89 if (__glibc_unlikely (stopped != 0))
91 INTERNAL_SYSCALL_DECL (err);
92 int res = 0;
94 /* Set the affinity mask if necessary. */
95 if (attr->cpuset != NULL)
97 res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
98 attr->cpusetsize, attr->cpuset);
100 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
102 /* The operation failed. We have to kill the thread. First
103 send it the cancellation signal. */
104 INTERNAL_SYSCALL_DECL (err2);
105 err_out:
106 (void) INTERNAL_SYSCALL (tgkill, err2, 3,
107 THREAD_GETMEM (THREAD_SELF, pid),
108 pd->tid, SIGCANCEL);
110 /* We do not free the stack here because the canceled thread
111 itself will do this. */
113 return (INTERNAL_SYSCALL_ERROR_P (res, err)
114 ? INTERNAL_SYSCALL_ERRNO (res, err)
115 : 0);
119 /* Set the scheduling parameters. */
120 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
122 res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
123 pd->schedpolicy, &pd->schedparam);
125 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
126 goto err_out;
130 /* We now have for sure more than one thread. The main thread might
131 not yet have the flag set. No need to set the global variable
132 again if this is what we use. */
133 THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
135 return 0;
139 static int
140 create_thread (struct pthread *pd, const struct pthread_attr *attr,
141 STACK_VARIABLES_PARMS)
143 #if TLS_TCB_AT_TP
144 assert (pd->header.tcb != NULL);
145 #endif
147 /* We rely heavily on various flags the CLONE function understands:
149 CLONE_VM, CLONE_FS, CLONE_FILES
150 These flags select semantics with shared address space and
151 file descriptors according to what POSIX requires.
153 CLONE_SIGNAL
154 This flag selects the POSIX signal semantics.
156 CLONE_SETTLS
157 The sixth parameter to CLONE determines the TLS area for the
158 new thread.
160 CLONE_PARENT_SETTID
161 The kernels writes the thread ID of the newly created thread
162 into the location pointed to by the fifth parameters to CLONE.
164 Note that it would be semantically equivalent to use
165 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
167 CLONE_CHILD_CLEARTID
168 The kernels clears the thread ID of a thread that has called
169 sys_exit() in the location pointed to by the seventh parameter
170 to CLONE.
172 The termination signal is chosen to be zero which means no signal
173 is sent. */
174 int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
175 | CLONE_SETTLS | CLONE_PARENT_SETTID
176 | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
177 | 0);
179 if (__glibc_unlikely (THREAD_GETMEM (THREAD_SELF, report_events)))
181 /* The parent thread is supposed to report events. Check whether
182 the TD_CREATE event is needed, too. */
183 const int _idx = __td_eventword (TD_CREATE);
184 const uint32_t _mask = __td_eventmask (TD_CREATE);
186 if ((_mask & (__nptl_threads_events.event_bits[_idx]
187 | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
189 /* We always must have the thread start stopped. */
190 pd->stopped_start = true;
192 /* Create the thread. We always create the thread stopped
193 so that it does not get far before we tell the debugger. */
194 int res = do_clone (pd, attr, clone_flags, start_thread,
195 STACK_VARIABLES_ARGS, 1);
196 if (res == 0)
198 /* Now fill in the information about the new thread in
199 the newly created thread's data structure. We cannot let
200 the new thread do this since we don't know whether it was
201 already scheduled when we send the event. */
202 pd->eventbuf.eventnum = TD_CREATE;
203 pd->eventbuf.eventdata = pd;
205 /* Enqueue the descriptor. */
207 pd->nextevent = __nptl_last_event;
208 while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
209 pd, pd->nextevent)
210 != 0);
212 /* Now call the function which signals the event. */
213 __nptl_create_event ();
215 /* And finally restart the new thread. */
216 lll_unlock (pd->lock, LLL_PRIVATE);
219 return res;
223 #ifdef NEED_DL_SYSINFO
224 CHECK_THREAD_SYSINFO (pd);
225 #endif
227 /* Determine whether the newly created threads has to be started
228 stopped since we have to set the scheduling parameters or set the
229 affinity. */
230 bool stopped = false;
231 if (attr != NULL && (attr->cpuset != NULL
232 || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
233 stopped = true;
234 pd->stopped_start = stopped;
235 pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
237 /* Actually create the thread. */
238 int res = do_clone (pd, attr, clone_flags, start_thread,
239 STACK_VARIABLES_ARGS, stopped);
241 if (res == 0 && stopped)
242 /* And finally restart the new thread. */
243 lll_unlock (pd->lock, LLL_PRIVATE);
245 return res;