]>
Commit | Line | Data |
---|---|---|
d4697bc9 | 1 | /* Copyright (C) 2002-2014 Free Software Foundation, Inc. |
e6ebd2e4 UD |
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 | |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
e6ebd2e4 UD |
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> | |
e054f494 | 26 | #include <stdint.h> |
e6ebd2e4 | 27 | |
f1205aa7 UD |
28 | #include "kernel-features.h" |
29 | ||
e6ebd2e4 | 30 | |
66f1b8ee | 31 | #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD) |
e6ebd2e4 UD |
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 | ||
5d5d5969 RM |
39 | #ifndef ARCH_CLONE |
40 | # define ARCH_CLONE __clone | |
41 | #endif | |
42 | ||
e6ebd2e4 | 43 | |
5a03acfe | 44 | #ifndef TLS_MULTIPLE_THREADS_IN_TCB |
5a03acfe UD |
45 | /* Pointer to the corresponding variable in libc. */ |
46 | int *__libc_multiple_threads_ptr attribute_hidden; | |
47 | #endif | |
48 | ||
49 | ||
e6ebd2e4 | 50 | static int |
9d79e037 | 51 | do_clone (struct pthread *pd, const struct pthread_attr *attr, |
a2c33d5a UD |
52 | int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS, |
53 | int stopped) | |
e6ebd2e4 UD |
54 | { |
55 | #ifdef PREPARE_CREATE | |
56 | PREPARE_CREATE; | |
57 | #endif | |
58 | ||
a1ffb40e | 59 | if (__glibc_unlikely (stopped != 0)) |
0f7e0ee5 | 60 | /* We make sure the thread does not run far by forcing it to get a |
f1205aa7 UD |
61 | lock. We lock it here too so that the new thread cannot continue |
62 | until we tell it to. */ | |
e51deae7 | 63 | lll_lock (pd->lock, LLL_PRIVATE); |
f1205aa7 | 64 | |
fd5d6a62 RM |
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 | ||
66f1b8ee UD |
75 | int rc = ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags, |
76 | pd, &pd->tid, TLS_VALUE, &pd->tid); | |
77 | ||
a1ffb40e | 78 | if (__glibc_unlikely (rc == -1)) |
3f80a99b | 79 | { |
fd5d6a62 RM |
80 | atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */ |
81 | ||
1d78f299 UD |
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); | |
87 | ||
88 | /* Free the resources. */ | |
3f80a99b UD |
89 | __deallocate_stack (pd); |
90 | ||
0f7e0ee5 UD |
91 | /* We have to translate error codes. */ |
92 | return errno == ENOMEM ? EAGAIN : errno; | |
3f80a99b | 93 | } |
e6ebd2e4 | 94 | |
80f536db | 95 | /* Now we have the possibility to set scheduling parameters etc. */ |
a1ffb40e | 96 | if (__glibc_unlikely (stopped != 0)) |
e6ebd2e4 | 97 | { |
80f536db UD |
98 | INTERNAL_SYSCALL_DECL (err); |
99 | int res = 0; | |
e6ebd2e4 | 100 | |
80f536db UD |
101 | /* Set the affinity mask if necessary. */ |
102 | if (attr->cpuset != NULL) | |
e6ebd2e4 | 103 | { |
80f536db | 104 | res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid, |
7c0ad164 | 105 | attr->cpusetsize, attr->cpuset); |
e6ebd2e4 | 106 | |
a1ffb40e | 107 | if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err))) |
9c988b83 UD |
108 | { |
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: | |
14ffbc83 UD |
113 | (void) INTERNAL_SYSCALL (tgkill, err2, 3, |
114 | THREAD_GETMEM (THREAD_SELF, pid), | |
115 | pd->tid, SIGCANCEL); | |
9c988b83 | 116 | |
1d78f299 UD |
117 | /* We do not free the stack here because the canceled thread |
118 | itself will do this. */ | |
119 | ||
3f80a99b UD |
120 | return (INTERNAL_SYSCALL_ERROR_P (res, err) |
121 | ? INTERNAL_SYSCALL_ERRNO (res, err) | |
122 | : 0); | |
9c988b83 | 123 | } |
80f536db UD |
124 | } |
125 | ||
126 | /* Set the scheduling parameters. */ | |
127 | if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0) | |
128 | { | |
5c5252bd UD |
129 | res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid, |
130 | pd->schedpolicy, &pd->schedparam); | |
80f536db | 131 | |
a1ffb40e | 132 | if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err))) |
5c5252bd | 133 | goto err_out; |
80f536db | 134 | } |
e6ebd2e4 UD |
135 | } |
136 | ||
80f536db UD |
137 | /* We now have for sure more than one thread. The main thread might |
138 | not yet have the flag set. No need to set the global variable | |
139 | again if this is what we use. */ | |
140 | THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1); | |
141 | ||
142 | return 0; | |
143 | } | |
144 | ||
145 | ||
146 | static int | |
9d79e037 | 147 | create_thread (struct pthread *pd, const struct pthread_attr *attr, |
80f536db UD |
148 | STACK_VARIABLES_PARMS) |
149 | { | |
d7329d4b | 150 | #if TLS_TCB_AT_TP |
80f536db | 151 | assert (pd->header.tcb != NULL); |
e6ebd2e4 UD |
152 | #endif |
153 | ||
154 | /* We rely heavily on various flags the CLONE function understands: | |
155 | ||
156 | CLONE_VM, CLONE_FS, CLONE_FILES | |
157 | These flags select semantics with shared address space and | |
158 | file descriptors according to what POSIX requires. | |
159 | ||
160 | CLONE_SIGNAL | |
161 | This flag selects the POSIX signal semantics. | |
162 | ||
163 | CLONE_SETTLS | |
164 | The sixth parameter to CLONE determines the TLS area for the | |
165 | new thread. | |
166 | ||
167 | CLONE_PARENT_SETTID | |
168 | The kernels writes the thread ID of the newly created thread | |
169 | into the location pointed to by the fifth parameters to CLONE. | |
170 | ||
171 | Note that it would be semantically equivalent to use | |
172 | CLONE_CHILD_SETTID but it is be more expensive in the kernel. | |
173 | ||
174 | CLONE_CHILD_CLEARTID | |
175 | The kernels clears the thread ID of a thread that has called | |
a05be180 UD |
176 | sys_exit() in the location pointed to by the seventh parameter |
177 | to CLONE. | |
e6ebd2e4 | 178 | |
e6ebd2e4 UD |
179 | The termination signal is chosen to be zero which means no signal |
180 | is sent. */ | |
80f536db UD |
181 | int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
182 | | CLONE_SETTLS | CLONE_PARENT_SETTID | |
5673ccc1 | 183 | | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM |
80f536db UD |
184 | | 0); |
185 | ||
a1ffb40e | 186 | if (__glibc_unlikely (THREAD_GETMEM (THREAD_SELF, report_events))) |
80f536db UD |
187 | { |
188 | /* The parent thread is supposed to report events. Check whether | |
189 | the TD_CREATE event is needed, too. */ | |
190 | const int _idx = __td_eventword (TD_CREATE); | |
191 | const uint32_t _mask = __td_eventmask (TD_CREATE); | |
e6ebd2e4 | 192 | |
80f536db UD |
193 | if ((_mask & (__nptl_threads_events.event_bits[_idx] |
194 | | pd->eventbuf.eventmask.event_bits[_idx])) != 0) | |
195 | { | |
5f66b766 UD |
196 | /* We always must have the thread start stopped. */ |
197 | pd->stopped_start = true; | |
198 | ||
f1205aa7 UD |
199 | /* Create the thread. We always create the thread stopped |
200 | so that it does not get far before we tell the debugger. */ | |
a2c33d5a UD |
201 | int res = do_clone (pd, attr, clone_flags, start_thread, |
202 | STACK_VARIABLES_ARGS, 1); | |
80f536db UD |
203 | if (res == 0) |
204 | { | |
205 | /* Now fill in the information about the new thread in | |
206 | the newly created thread's data structure. We cannot let | |
207 | the new thread do this since we don't know whether it was | |
208 | already scheduled when we send the event. */ | |
209 | pd->eventbuf.eventnum = TD_CREATE; | |
210 | pd->eventbuf.eventdata = pd; | |
211 | ||
212 | /* Enqueue the descriptor. */ | |
213 | do | |
214 | pd->nextevent = __nptl_last_event; | |
215 | while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event, | |
216 | pd, pd->nextevent) | |
217 | != 0); | |
218 | ||
219 | /* Now call the function which signals the event. */ | |
220 | __nptl_create_event (); | |
221 | ||
222 | /* And finally restart the new thread. */ | |
e51deae7 | 223 | lll_unlock (pd->lock, LLL_PRIVATE); |
80f536db UD |
224 | } |
225 | ||
226 | return res; | |
227 | } | |
228 | } | |
229 | ||
230 | #ifdef NEED_DL_SYSINFO | |
a2c33d5a | 231 | assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd)); |
80f536db UD |
232 | #endif |
233 | ||
a2c33d5a UD |
234 | /* Determine whether the newly created threads has to be started |
235 | stopped since we have to set the scheduling parameters or set the | |
236 | affinity. */ | |
5f66b766 | 237 | bool stopped = false; |
a2c33d5a UD |
238 | if (attr != NULL && (attr->cpuset != NULL |
239 | || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)) | |
5f66b766 UD |
240 | stopped = true; |
241 | pd->stopped_start = stopped; | |
b051fc44 | 242 | pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling); |
a2c33d5a | 243 | |
80f536db | 244 | /* Actually create the thread. */ |
f1205aa7 | 245 | int res = do_clone (pd, attr, clone_flags, start_thread, |
a2c33d5a | 246 | STACK_VARIABLES_ARGS, stopped); |
f1205aa7 | 247 | |
a2c33d5a UD |
248 | if (res == 0 && stopped) |
249 | /* And finally restart the new thread. */ | |
e51deae7 | 250 | lll_unlock (pd->lock, LLL_PRIVATE); |
f1205aa7 UD |
251 | |
252 | return res; | |
e6ebd2e4 | 253 | } |