Optimize for kernels which are known to have the vfork syscall.
[glibc/pb-stable.git] / nptl / init.c
blob7704e9f507664f13d64702c8bb4f5961ddbcb429
1 /* Copyright (C) 2002, 2003 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
18 02111-1307 USA. */
20 #include <assert.h>
21 #include <limits.h>
22 #include <signal.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25 #include <sys/param.h>
26 #include <sys/resource.h>
27 #include <pthreadP.h>
28 #include <atomic.h>
29 #include <ldsodefs.h>
30 #include <tls.h>
31 #include <fork.h>
32 #include <version.h>
33 #include <shlib-compat.h>
36 /* XXX For the time being... */
37 #define __NR_set_tid_address 258
40 /* Default stack size. */
41 size_t __default_stacksize attribute_hidden;
43 /* Size and alignment of static TLS block. */
44 size_t __static_tls_size;
45 size_t __static_tls_align;
47 /* Version of the library, used in libthread_db to detect mismatches. */
48 static const char nptl_version[] = VERSION;
51 #if defined USE_TLS && !defined SHARED
52 extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
53 #endif
56 #ifdef SHARED
57 static struct pthread_functions pthread_functions =
59 .ptr_pthread_attr_destroy = __pthread_attr_destroy,
60 # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
61 .ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0,
62 # endif
63 .ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1,
64 .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
65 .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
66 .ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,
67 .ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched,
68 .ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam,
69 .ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam,
70 .ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy,
71 .ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy,
72 .ptr_pthread_attr_getscope = __pthread_attr_getscope,
73 .ptr_pthread_attr_setscope = __pthread_attr_setscope,
74 .ptr_pthread_condattr_destroy = __pthread_condattr_destroy,
75 .ptr_pthread_condattr_init = __pthread_condattr_init,
76 .ptr___pthread_cond_broadcast = __pthread_cond_broadcast,
77 .ptr___pthread_cond_destroy = __pthread_cond_destroy,
78 .ptr___pthread_cond_init = __pthread_cond_init,
79 .ptr___pthread_cond_signal = __pthread_cond_signal,
80 .ptr___pthread_cond_wait = __pthread_cond_wait,
81 # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
82 .ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
83 .ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,
84 .ptr___pthread_cond_init_2_0 = __pthread_cond_init_2_0,
85 .ptr___pthread_cond_signal_2_0 = __pthread_cond_signal_2_0,
86 .ptr___pthread_cond_wait_2_0 = __pthread_cond_wait_2_0,
87 # endif
88 .ptr_pthread_equal = __pthread_equal,
89 .ptr___pthread_exit = __pthread_exit,
90 .ptr_pthread_getschedparam = __pthread_getschedparam,
91 .ptr_pthread_setschedparam = __pthread_setschedparam,
92 .ptr_pthread_mutex_destroy = INTUSE(__pthread_mutex_destroy),
93 .ptr_pthread_mutex_init = INTUSE(__pthread_mutex_init),
94 .ptr_pthread_mutex_lock = INTUSE(__pthread_mutex_lock),
95 .ptr_pthread_mutex_unlock = INTUSE(__pthread_mutex_unlock),
96 .ptr_pthread_self = __pthread_self,
97 .ptr_pthread_setcancelstate = __pthread_setcancelstate,
98 .ptr_pthread_setcanceltype = __pthread_setcanceltype,
99 .ptr___pthread_cleanup_upto = __pthread_cleanup_upto,
100 .ptr___pthread_once = __pthread_once_internal,
101 .ptr___pthread_rwlock_rdlock = __pthread_rwlock_rdlock_internal,
102 .ptr___pthread_rwlock_wrlock = __pthread_rwlock_wrlock_internal,
103 .ptr___pthread_rwlock_unlock = __pthread_rwlock_unlock_internal,
104 .ptr___pthread_key_create = __pthread_key_create_internal,
105 .ptr___pthread_getspecific = __pthread_getspecific_internal,
106 .ptr___pthread_setspecific = __pthread_setspecific_internal,
107 .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer,
108 .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore
110 # define ptr_pthread_functions &pthread_functions
111 #else
112 # define ptr_pthread_functions NULL
113 #endif
116 /* For asynchronous cancellation we use a signal. This is the handler. */
117 static void
118 sigcancel_handler (int sig __attribute ((unused)))
120 struct pthread *self = THREAD_SELF;
122 while (1)
124 /* We are canceled now. When canceled by another thread this flag
125 is already set but if the signal is directly send (internally or
126 from another process) is has to be done here. */
127 int oldval = THREAD_GETMEM (self, cancelhandling);
128 int newval = oldval | CANCELED_BITMASK;
130 if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
131 /* Already canceled or exiting. */
132 break;
134 if (atomic_compare_and_exchange_acq (&self->cancelhandling, newval,
135 oldval) == 0)
137 /* Set the return value. */
138 THREAD_SETMEM (self, result, PTHREAD_CANCELED);
140 /* Make sure asynchronous cancellation is still enabled. */
141 if ((newval & CANCELTYPE_BITMASK) != 0)
143 /* The thread is exiting now. */
144 atomic_bit_set (&self->cancelhandling, EXITING_BIT);
146 /* Run the registered destructors and terminate the
147 thread. */
148 __do_cancel ();
151 break;
158 void
159 __pthread_initialize_minimal_internal (void)
161 #ifndef SHARED
162 /* Unlike in the dynamically linked case the dynamic linker has not
163 taken care of initializing the TLS data structures. */
164 __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
166 /* We must prevent gcc from being clever and move any of the
167 following code ahead of the __libc_setup_tls call. This function
168 will initialize the thread register which is subsequently
169 used. */
170 __asm __volatile ("");
171 #endif
173 /* Minimal initialization of the thread descriptor. */
174 struct pthread *pd = THREAD_SELF;
175 INTERNAL_SYSCALL_DECL (err);
176 pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
177 THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]);
178 THREAD_SETMEM (pd, user_stack, true);
179 if (LLL_LOCK_INITIALIZER != 0)
180 THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER);
181 #if HP_TIMING_AVAIL
182 THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
183 #endif
185 /* Initialize the list of all running threads with the main thread. */
186 INIT_LIST_HEAD (&__stack_user);
187 list_add (&pd->header.data.list, &__stack_user);
190 /* Install the cancellation signal handler. If for some reason we
191 cannot install the handler we do not abort. Maybe we should, but
192 it is only asynchronous cancellation which is affected. */
193 struct sigaction sa;
194 sa.sa_handler = sigcancel_handler;
195 sa.sa_flags = 0;
196 sigemptyset (&sa.sa_mask);
198 (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
201 /* Determine the default allowed stack size. This is the size used
202 in case the user does not specify one. */
203 struct rlimit limit;
204 if (getrlimit (RLIMIT_STACK, &limit) != 0
205 || limit.rlim_cur == RLIM_INFINITY)
206 /* The system limit is not usable. Use an architecture-specific
207 default. */
208 limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
210 #ifdef NEED_SEPARATE_REGISTER_STACK
211 __default_stacksize = MAX (limit.rlim_cur / 2, PTHREAD_STACK_MIN);
212 #else
213 __default_stacksize = MAX (limit.rlim_cur, PTHREAD_STACK_MIN);
214 #endif
215 /* The maximum page size better should be a multiple of the page
216 size. */
217 assert (__default_stacksize % __sysconf (_SC_PAGESIZE) == 0);
219 /* Get the size of the static and alignment requirements for the TLS
220 block. */
221 _dl_get_tls_static_info (&__static_tls_size, &__static_tls_align);
223 /* Make sure the size takes all the alignments into account. */
224 if (STACK_ALIGN > __static_tls_align)
225 __static_tls_align = STACK_ALIGN;
226 __static_tls_size = roundup (__static_tls_size, __static_tls_align);
228 /* Register the fork generation counter with the libc. */
229 __libc_pthread_init (&__fork_generation, __reclaim_stacks,
230 ptr_pthread_functions);
232 strong_alias (__pthread_initialize_minimal_internal,
233 __pthread_initialize_minimal)