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