1 /* Copyright (C) 2002 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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
29 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
33 create_thread (struct pthread *pd, STACK_VARIABLES_PARMS)
35 union user_desc_init desc;
37 /* Describe the thread-local storage segment. */
39 /* The 'entry_number' field. The first three bits of the segment
40 register value select the GDT, ignore them. We get the index
41 from the value of the %gs register in the current thread. */
42 desc.vals[0] = TLS_GET_GS () >> 3;
43 /* The 'base_addr' field. Pointer to the TCB. */
44 desc.vals[1] = (unsigned long int) pd;
45 /* The 'limit' field. We use 4GB which is 0xfffff pages. */
46 desc.vals[2] = 0xfffff;
47 /* Collapsed value of the bitfield:
57 assert (pd->header.data.tcb != NULL);
60 if (__builtin_expect (THREAD_GETMEM (THREAD_SELF, report_events), 0))
62 /* The parent thread is supposed to report events. Check whether
63 the TD_CREATE event is needed, too. */
64 const int _idx = __td_eventword (TD_CREATE);
65 const uint32_t _mask = __td_eventmask (TD_CREATE);
67 if ((_mask & (__nptl_threads_events.event_bits[_idx]
68 | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
70 /* We have to report the new thread. Make sure the thread
71 does not run far by forcing it to get a lock. We lock it
72 here too so that the new thread cannot continue until we
76 /* Create the thread. */
77 if (__clone (start_thread_debug, STACK_VARIABLES_ARGS,
78 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
79 CLONE_SETTLS | CLONE_PARENT_SETTID |
80 CLONE_CHILD_CLEARTID | CLONE_DETACHED | 0,
81 pd, &pd->tid, &desc.desc, &pd->tid) == -1)
85 /* We now have for sure more than one thread. */
86 pd->header.data.multiple_threads = 1;
88 /* Now fill in the information about the new thread in
89 the newly created thread's data structure. We cannot let
90 the new thread do this since we don't know whether it was
91 already scheduled when we send the event. */
92 pd->eventbuf.eventnum = TD_CREATE;
93 pd->eventbuf.eventdata = pd;
95 /* Enqueue the descriptor. */
97 pd->nextevent = __nptl_last_event;
98 while (atomic_compare_and_exchange_acq (&__nptl_last_event, pd,
101 /* Now call the function which signals the event. */
102 __nptl_create_event ();
104 /* And finally restart the new thread. */
105 lll_unlock (pd->lock);
111 #ifdef NEED_DL_SYSINFO
112 assert (THREAD_GETMEM (THREAD_SELF, header.data.sysinfo)
113 == pd->header.data.sysinfo);
116 /* We rely heavily on various flags the CLONE function understands:
118 CLONE_VM, CLONE_FS, CLONE_FILES
119 These flags select semantics with shared address space and
120 file descriptors according to what POSIX requires.
123 This flag selects the POSIX signal semantics.
126 The sixth parameter to CLONE determines the TLS area for the
130 The kernels writes the thread ID of the newly created thread
131 into the location pointed to by the fifth parameters to CLONE.
133 Note that it would be semantically equivalent to use
134 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
137 The kernels clears the thread ID of a thread that has called
138 sys_exit() - using the same parameter as CLONE_SETTID.
141 No signal is generated if the thread exists and it is
142 automatically reaped.
144 The termination signal is chosen to be zero which means no signal
146 if (__clone (start_thread, STACK_VARIABLES_ARGS,
147 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL |
148 CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
149 CLONE_DETACHED | 0, pd, &pd->tid, &desc.desc, &pd->tid) == -1)
153 /* We now have for sure more than one thread. */
154 THREAD_SETMEM (THREAD_SELF, header.data.multiple_threads, 1);