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