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
25 #include <sys/param.h>
26 #include <sys/resource.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
);
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
,
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
,
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
112 # define ptr_pthread_functions NULL
116 /* For asynchronous cancellation we use a signal. This is the handler. */
118 sigcancel_handler (int sig
__attribute ((unused
)))
120 struct pthread
*self
= THREAD_SELF
;
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. */
134 if (atomic_compare_and_exchange_acq (&self
->cancelhandling
, newval
,
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
159 __pthread_initialize_minimal_internal (void)
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
170 __asm
__volatile ("");
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
);
182 THREAD_SETMEM (pd
, cpuclock_offset
, GL(dl_cpuclock_offset
));
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. */
194 sa
.sa_handler
= sigcancel_handler
;
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. */
204 if (getrlimit (RLIMIT_STACK
, &limit
) != 0
205 || limit
.rlim_cur
== RLIM_INFINITY
)
206 /* The system limit is not usable. Use an architecture-specific
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
);
213 __default_stacksize
= MAX (limit
.rlim_cur
, PTHREAD_STACK_MIN
);
215 /* The maximum page size better should be a multiple of the page
217 assert (__default_stacksize
% __sysconf (_SC_PAGESIZE
) == 0);
219 /* Get the size of the static and alignment requirements for the TLS
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
)