OSDN Git Service

nptl: get rid of preprocessor warning when __ASSUME_TGKILL is not defined
[uclinux-h8/uClibc.git] / libpthread / nptl / sysdeps / pthread / createthread.c
1 /* Copyright (C) 2002-2007, 2008 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 <bits/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 /* Pointer to the corresponding variable in libc.  */
46 int *__libc_multiple_threads_ptr attribute_hidden;
47 #endif
48
49
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)
54 {
55 #ifdef PREPARE_CREATE
56   PREPARE_CREATE;
57 #endif
58
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);
64
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
75   if (ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
76                   pd, &pd->tid, TLS_VALUE, &pd->tid) == -1)
77     {
78       atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second.  */
79
80       /* Failed.  If the thread is detached, remove the TCB here since
81          the caller cannot do this.  The caller remembered the thread
82          as detached and cannot reverify that it is not since it must
83          not access the thread descriptor again.  */
84       if (IS_DETACHED (pd))
85         __deallocate_stack (pd);
86
87       /* We have to translate error codes.  */
88       return errno == ENOMEM ? EAGAIN : errno;
89     }
90
91   /* Now we have the possibility to set scheduling parameters etc.  */
92   if (__builtin_expect (stopped != 0, 0))
93     {
94       INTERNAL_SYSCALL_DECL (err);
95       int res = 0;
96
97       /* Set the affinity mask if necessary.  */
98       if (attr->cpuset != NULL)
99         {
100           res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
101                                   attr->cpusetsize, attr->cpuset);
102
103           if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
104             {
105               /* The operation failed.  We have to kill the thread.  First
106                  send it the cancellation signal.  */
107               INTERNAL_SYSCALL_DECL (err2);
108             err_out:
109 #if defined (__ASSUME_TGKILL) && __ASSUME_TGKILL
110               (void) INTERNAL_SYSCALL (tgkill, err2, 3,
111                                        THREAD_GETMEM (THREAD_SELF, pid),
112                                        pd->tid, SIGCANCEL);
113 #else
114               (void) INTERNAL_SYSCALL (tkill, err2, 2, pd->tid, SIGCANCEL);
115 #endif
116
117               return (INTERNAL_SYSCALL_ERROR_P (res, err)
118                       ? INTERNAL_SYSCALL_ERRNO (res, err)
119                       : 0);
120             }
121         }
122
123       /* Set the scheduling parameters.  */
124       if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
125         {
126           res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
127                                   pd->schedpolicy, &pd->schedparam);
128
129           if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (res, err), 0))
130             goto err_out;
131         }
132     }
133
134   /* We now have for sure more than one thread.  The main thread might
135      not yet have the flag set.  No need to set the global variable
136      again if this is what we use.  */
137   THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
138
139   return 0;
140 }
141
142
143 static int
144 create_thread (struct pthread *pd, const struct pthread_attr *attr,
145                STACK_VARIABLES_PARMS)
146 {
147 #ifdef TLS_TCB_AT_TP
148   assert (pd->header.tcb != NULL);
149 #endif
150
151   /* We rely heavily on various flags the CLONE function understands:
152
153      CLONE_VM, CLONE_FS, CLONE_FILES
154         These flags select semantics with shared address space and
155         file descriptors according to what POSIX requires.
156
157      CLONE_SIGNAL
158         This flag selects the POSIX signal semantics.
159
160      CLONE_SETTLS
161         The sixth parameter to CLONE determines the TLS area for the
162         new thread.
163
164      CLONE_PARENT_SETTID
165         The kernels writes the thread ID of the newly created thread
166         into the location pointed to by the fifth parameters to CLONE.
167
168         Note that it would be semantically equivalent to use
169         CLONE_CHILD_SETTID but it is be more expensive in the kernel.
170
171      CLONE_CHILD_CLEARTID
172         The kernels clears the thread ID of a thread that has called
173         sys_exit() in the location pointed to by the seventh parameter
174         to CLONE.
175
176      CLONE_DETACHED
177         No signal is generated if the thread exists and it is
178         automatically reaped.
179
180      The termination signal is chosen to be zero which means no signal
181      is sent.  */
182   int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
183                      | CLONE_SETTLS | CLONE_PARENT_SETTID
184                      | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
185 #if __ASSUME_NO_CLONE_DETACHED == 0
186                      | CLONE_DETACHED
187 #endif
188                      | 0);
189
190   if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
191     {
192       /* The parent thread is supposed to report events.  Check whether
193          the TD_CREATE event is needed, too.  */
194       const int _idx = __td_eventword (TD_CREATE);
195       const uint32_t _mask = __td_eventmask (TD_CREATE);
196
197       if ((_mask & (__nptl_threads_events.event_bits[_idx]
198                     | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
199         {
200           /* We always must have the thread start stopped.  */
201           pd->stopped_start = true;
202
203           /* Create the thread.  We always create the thread stopped
204              so that it does not get far before we tell the debugger.  */
205           int res = do_clone (pd, attr, clone_flags, start_thread,
206                               STACK_VARIABLES_ARGS, 1);
207           if (res == 0)
208             {
209               /* Now fill in the information about the new thread in
210                  the newly created thread's data structure.  We cannot let
211                  the new thread do this since we don't know whether it was
212                  already scheduled when we send the event.  */
213               pd->eventbuf.eventnum = TD_CREATE;
214               pd->eventbuf.eventdata = pd;
215
216               /* Enqueue the descriptor.  */
217               do
218                 pd->nextevent = __nptl_last_event;
219               while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
220                                                            pd, pd->nextevent)
221                      != 0);
222
223               /* Now call the function which signals the event.  */
224               __nptl_create_event ();
225
226               /* And finally restart the new thread.  */
227               lll_unlock (pd->lock, LLL_PRIVATE);
228             }
229
230           return res;
231         }
232     }
233
234 #ifdef NEED_DL_SYSINFO
235   assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd));
236 #endif
237
238   /* Determine whether the newly created threads has to be started
239      stopped since we have to set the scheduling parameters or set the
240      affinity.  */
241   bool stopped = false;
242   if (attr != NULL && (attr->cpuset != NULL
243                        || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
244     stopped = true;
245   pd->stopped_start = stopped;
246   pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
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, LLL_PRIVATE);
255
256   return res;
257 }