1/* Low-level thread creation for NPTL. Linux version.
2 Copyright (C) 2002-2016 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, see
18 <http://www.gnu.org/licenses/>. */
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#include <stdint.h>
28
29#include <arch-fork.h>
30
31
32#ifndef ARCH_CLONE
33# define ARCH_CLONE __clone
34#endif
35
36/* See the comments in pthread_create.c for the requirements for these
37 two macros and the create_thread function. */
38
39#define START_THREAD_DEFN \
40 static int __attribute__ ((noreturn)) start_thread (void *arg)
41#define START_THREAD_SELF arg
42
43/* pthread_create.c defines this using START_THREAD_DEFN
44 We need a forward declaration here so we can take its address. */
45static int start_thread (void *arg) __attribute__ ((noreturn));
46
47static int
48create_thread (struct pthread *pd, const struct pthread_attr *attr,
49 bool stopped_start, STACK_VARIABLES_PARMS, bool *thread_ran)
50{
51 /* Determine whether the newly created threads has to be started
52 stopped since we have to set the scheduling parameters or set the
53 affinity. */
54 if (attr != NULL
55 && (__glibc_unlikely (attr->cpuset != NULL)
56 || __glibc_unlikely ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)))
57 stopped_start = true;
58
59 pd->stopped_start = stopped_start;
60 if (__glibc_unlikely (stopped_start))
61 /* We make sure the thread does not run far by forcing it to get a
62 lock. We lock it here too so that the new thread cannot continue
63 until we tell it to. */
64 lll_lock (pd->lock, LLL_PRIVATE);
65
66 /* We rely heavily on various flags the CLONE function understands:
67
68 CLONE_VM, CLONE_FS, CLONE_FILES
69 These flags select semantics with shared address space and
70 file descriptors according to what POSIX requires.
71
72 CLONE_SIGHAND, CLONE_THREAD
73 This flag selects the POSIX signal semantics and various
74 other kinds of sharing (itimers, POSIX timers, etc.).
75
76 CLONE_SETTLS
77 The sixth parameter to CLONE determines the TLS area for the
78 new thread.
79
80 CLONE_PARENT_SETTID
81 The kernels writes the thread ID of the newly created thread
82 into the location pointed to by the fifth parameters to CLONE.
83
84 Note that it would be semantically equivalent to use
85 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
86
87 CLONE_CHILD_CLEARTID
88 The kernels clears the thread ID of a thread that has called
89 sys_exit() in the location pointed to by the seventh parameter
90 to CLONE.
91
92 The termination signal is chosen to be zero which means no signal
93 is sent. */
94 const int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM
95 | CLONE_SIGHAND | CLONE_THREAD
96 | CLONE_SETTLS | CLONE_PARENT_SETTID
97 | CLONE_CHILD_CLEARTID
98 | 0);
99
100 TLS_DEFINE_INIT_TP (tp, pd);
101
102 if (__glibc_unlikely (ARCH_CLONE (&start_thread, STACK_VARIABLES_ARGS,
103 clone_flags, pd, &pd->tid, tp, &pd->tid)
104 == -1))
105 return errno;
106
107 /* It's started now, so if we fail below, we'll have to cancel it
108 and let it clean itself up. */
109 *thread_ran = true;
110
111 /* Now we have the possibility to set scheduling parameters etc. */
112 if (attr != NULL)
113 {
114 INTERNAL_SYSCALL_DECL (err);
115 int res;
116
117 /* Set the affinity mask if necessary. */
118 if (attr->cpuset != NULL)
119 {
120 assert (stopped_start);
121
122 res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
123 attr->cpusetsize, attr->cpuset);
124
125 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
126 err_out:
127 {
128 /* The operation failed. We have to kill the thread.
129 We let the normal cancellation mechanism do the work. */
130
131 INTERNAL_SYSCALL_DECL (err2);
132 (void) INTERNAL_SYSCALL (tgkill, err2, 3,
133 THREAD_GETMEM (THREAD_SELF, pid),
134 pd->tid, SIGCANCEL);
135
136 return INTERNAL_SYSCALL_ERRNO (res, err);
137 }
138 }
139
140 /* Set the scheduling parameters. */
141 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
142 {
143 assert (stopped_start);
144
145 res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
146 pd->schedpolicy, &pd->schedparam);
147
148 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
149 goto err_out;
150 }
151 }
152
153 return 0;
154}
155