2
Copyright (C) 2000, 2002, 2005, 2007 Free Software Foundation, Inc.
3
This file is part of the GNU C Library.
5
The GNU C Library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Library General Public License as
7
published by the Free Software Foundation; either version 2 of the
8
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
Library General Public License for more details.
15
You should have received a copy of the GNU Library General Public
16
License along with the GNU C Library; see the file COPYING.LIB. If not,
17
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18
Boston, MA 02111-1307, USA. */
25
#include <bits/pt-atomic.h>
27
#include <pt-internal.h>
33
/* The total number of pthreads currently active. This is defined
34
here since it would be really stupid to have a threads-using
35
program that doesn't call `pthread_create'. */
36
__atomic_t __pthread_total;
39
/* The entry-point for new threads. */
41
entry_point (void *(*start_routine)(void *), void *arg)
44
/* A fresh thread needs to be bound to the global locale. */
45
uselocale (LC_GLOBAL_LOCALE);
50
pthread_exit (start_routine (arg));
53
/* Create a thread with attributes given by ATTR, executing
54
START_ROUTINE with argument ARG. */
56
pthread_create (pthread_t *thread, const pthread_attr_t *attr,
57
void *(*start_routine)(void *), void *arg)
60
struct __pthread *pthread;
62
err = __pthread_create_internal (&pthread, attr, start_routine, arg);
64
*thread = pthread->thread;
69
/* Internal version of pthread_create. See comment in
72
__pthread_create_internal (struct __pthread **thread,
73
const pthread_attr_t *attr,
74
void *(*start_routine)(void *), void *arg)
77
struct __pthread *pthread;
78
const struct __pthread_attr *setup;
81
/* Allocate a new thread structure. */
82
err = __pthread_alloc (&pthread);
86
/* Use the default attributes if ATTR is NULL. */
87
setup = attr ? attr : &__pthread_default_attr;
89
/* Initialize the thread state. */
90
pthread->state = (setup->detachstate == PTHREAD_CREATE_DETACHED
91
? PTHREAD_DETACHED : PTHREAD_JOINABLE);
93
/* If the user supplied a stack, it is not our responsibility to
94
setup a stack guard. */
96
pthread->guardsize = 0;
98
pthread->guardsize = (setup->guardsize <= setup->stacksize
99
? setup->guardsize : setup->stacksize);
101
/* Find a stack. There are several scenarios: if a detached thread
102
kills itself, it has no way to deallocate its stack, thus it
103
leaves PTHREAD->stack set to true. We try to reuse it here,
104
however, if the user supplied a stack, we cannot use the old one.
105
Right now, we simply deallocate it. */
108
if (setup->stackaddr != __pthread_default_attr.stackaddr)
110
__pthread_stack_dealloc (pthread->stackaddr,
112
pthread->stackaddr = setup->stackaddr;
113
pthread->stacksize = setup->stacksize;
118
err = __pthread_stack_alloc (&pthread->stackaddr,
121
goto failed_stack_alloc;
123
pthread->stacksize = setup->stacksize;
127
/* Allocate the kernel thread and other required resources. */
128
err = __pthread_thread_alloc (pthread);
130
goto failed_thread_alloc;
133
pthread->tcb = _dl_allocate_tls (NULL);
135
goto failed_thread_tls_alloc;
136
pthread->tcb->tcb = pthread->tcb;
137
#endif /* ENABLE_TLS */
139
/* And initialize the rest of the machine context. This may include
140
additional machine- and system-specific initializations that
142
err = __pthread_setup (pthread, entry_point, start_routine, arg);
146
/* Initialize the system-specific signal state for the new
148
err = __pthread_sigstate_init (pthread);
150
goto failed_sigstate;
152
/* Set the new thread's signal mask and set the pending signals to
153
empty. POSIX says: "The signal mask shall be inherited from the
154
creating thread. The set of signals pending for the new thread
155
shall be empty." If the currnet thread is not a pthread then we
156
just inherit the process' sigmask. */
157
if (__pthread_num_threads == 1)
158
err = sigprocmask (0, 0, &sigset);
160
err = __pthread_sigstate (_pthread_self (), 0, 0, &sigset, 0);
163
err = __pthread_sigstate (pthread, SIG_SETMASK, &sigset, 0, 1);
166
/* Increase the total number of threads. We do this before actually
167
starting the new thread, since the new thread might immediately
168
call `pthread_exit' which decreases the number of threads and
169
calls `exit' if the number of threads reaches zero. Increasing
170
the number of threads from within the new thread isn't an option
171
since this thread might return and call `pthread_exit' before the
173
__atomic_inc (&__pthread_total);
175
/* Store a pointer to this thread in the thread ID lookup table. We
176
could use __thread_setid, however, we only lock for reading as no
177
other thread should be using this entry (we also assume that the
179
pthread_rwlock_rdlock (&__pthread_threads_lock);
180
__pthread_threads[pthread->thread - 1] = pthread;
181
pthread_rwlock_unlock (&__pthread_threads_lock);
183
/* At this point it is possible to guess our pthread ID. We have to
184
make sure that all functions taking a pthread_t argument can
185
handle the fact that this thread isn't really running yet. */
187
/* Schedule the new thread. */
188
err = __pthread_thread_start (pthread);
190
goto failed_starting;
192
/* At this point the new thread is up and running. */
199
__pthread_setid (pthread->thread, NULL);
200
__atomic_dec (&__pthread_total);
202
__pthread_sigstate_destroy (pthread);
205
_dl_deallocate_tls (pthread->tcb, 1);
206
failed_thread_tls_alloc:
207
#endif /* ENABLE_TLS */
208
__pthread_thread_dealloc (pthread);
209
__pthread_thread_halt (pthread);
211
__pthread_stack_dealloc (pthread->stackaddr, pthread->stacksize);
214
__pthread_dealloc (pthread);