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/syscall.h>
28 #include <lowlevellock.h>
29 #include <stackinfo.h>
30 #include <internaltypes.h>
31 #include <pthread-functions.h>
34 /* Internal variables. */
37 /* Default stack size. */
38 extern size_t __default_stacksize attribute_hidden
;
40 /* Size and alignment of static TLS block. */
41 extern size_t __static_tls_size attribute_hidden
;
42 extern size_t __static_tls_align_m1 attribute_hidden
;
44 /* Thread descriptor handling. */
45 extern list_t __stack_user
;
46 hidden_proto (__stack_user
)
48 /* Attribute handling. */
49 extern struct pthread_attr
*__attr_list attribute_hidden
;
50 extern lll_lock_t __attr_list_lock attribute_hidden
;
52 /* First available RT signal. */
53 extern int __current_sigrtmin attribute_hidden
;
54 /* Last available RT signal. */
55 extern int __current_sigrtmax attribute_hidden
;
57 /* Concurrency handling. */
58 extern int __concurrency_level attribute_hidden
;
60 /* Thread-local data key handling. */
61 extern struct pthread_key_struct __pthread_keys
[PTHREAD_KEYS_MAX
];
62 hidden_proto (__pthread_keys
)
64 /* Number of threads running. */
65 extern unsigned int __nptl_nthreads attribute_hidden
;
67 /* The library can run in debugging mode where it performs a lot more
69 extern int __pthread_debug attribute_hidden
;
70 /** For now disable debugging support. */
72 # define DEBUGGING_P __builtin_expect (__pthread_debug, 0)
73 # define INVALID_TD_P(pd) (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
74 # define INVALID_NOT_TERMINATED_TD_P(pd) INVALID_TD_P (pd)
76 # define DEBUGGING_P 0
77 /* Simplified test. This will not catch all invalid descriptors but
78 is better than nothing. And if the test triggers the thread
79 descriptor is guaranteed to be invalid. */
80 # define INVALID_TD_P(pd) __builtin_expect ((pd)->tid <= 0, 0)
81 # define INVALID_NOT_TERMINATED_TD_P(pd) __builtin_expect ((pd)->tid < 0, 0)
85 /* Cancellation test. */
86 #define CANCELLATION_P(self) \
88 int cancelhandling = THREAD_GETMEM (self, cancelhandling); \
89 if (CANCEL_ENABLED_AND_CANCELED (cancelhandling)) \
91 THREAD_SETMEM (self, result, PTHREAD_CANCELED); \
96 /* Set cancellation mode to asynchronous. */
97 #define CANCEL_ASYNC() \
98 __pthread_enable_asynccancel ()
99 /* Reset to previous cancellation mode. */
100 #define CANCEL_RESET(oldtype) \
101 __pthread_disable_asynccancel (oldtype)
103 #if !defined NOT_IN_libc
104 /* Same as CANCEL_ASYNC, but for use in libc.so. */
105 # define LIBC_CANCEL_ASYNC() \
106 __libc_enable_asynccancel ()
107 /* Same as CANCEL_RESET, but for use in libc.so. */
108 # define LIBC_CANCEL_RESET(oldtype) \
109 __libc_disable_asynccancel (oldtype)
110 # define LIBC_CANCEL_HANDLED() \
111 __asm (".globl " __SYMBOL_PREFIX "__libc_enable_asynccancel"); \
112 __asm (".globl " __SYMBOL_PREFIX "__libc_disable_asynccancel")
113 #elif defined NOT_IN_libc && defined IS_IN_libpthread
114 # define LIBC_CANCEL_ASYNC() CANCEL_ASYNC ()
115 # define LIBC_CANCEL_RESET(val) CANCEL_RESET (val)
116 # define LIBC_CANCEL_HANDLED() \
117 __asm (".globl " __SYMBOL_PREFIX "__pthread_enable_asynccancel"); \
118 __asm (".globl " __SYMBOL_PREFIX "__pthread_disable_asynccancel")
120 # define LIBC_CANCEL_ASYNC() 0 /* Just a dummy value. */
121 # define LIBC_CANCEL_RESET(val) ((void)(val)) /* Nothing, but evaluate it. */
122 # define LIBC_CANCEL_HANDLED() /* Nothing. */
126 /* This function is responsible for calling all registered cleanup
127 handlers and then terminate the thread. This includes dellocating
128 the thread-specific data. The implementation is complicated by the
129 fact that we have to handle to cancellation handler registration
130 methods: exceptions using try/finally and setjmp.
132 The setjmp method is always available. The user might compile some
133 code which uses this method because no modern compiler is
134 available. So we have to handle these first since we cannot call
135 the cleanup handlers if the stack frames are gone. At the same
136 time this opens a hole for the register exception handler blocks
137 since now they might be in danger of using an overwritten stack
138 frame. The advise is to only use new or only old style cancellation
143 struct pthread
*self
= THREAD_SELF
;
145 /* Throw an exception. */
148 /* If throwing an exception didn't work try the longjmp. */
149 __libc_longjmp (self
->cancelbuf
, 1);
155 /* Test whether stackframe is still active. */
156 #ifdef _STACK_GROWS_DOWN
157 # define FRAME_LEFT(frame, other) ((char *) frame >= (char *) other)
158 #elif _STACK_GROWS_UP
159 # define FRAME_LEFT(frame, other) ((char *) frame <= (char *) other)
161 # error "Define either _STACK_GROWS_DOWN or _STACK_GROWS_UP"
165 /* Internal prototypes. */
167 /* Thread list handling. */
168 extern struct pthread
*__find_in_stack_list (struct pthread
*pd
)
169 attribute_hidden internal_function
;
171 /* Deallocate a thread's stack after optionally making sure the thread
172 descriptor is still valid. */
173 extern void __free_tcb (struct pthread
*pd
) attribute_hidden internal_function
;
175 /* Free allocated stack. */
176 extern void __deallocate_stack (struct pthread
*pd
)
177 attribute_hidden internal_function
;
179 /* Mark all the stacks except for the current one as available. This
180 function also re-initializes the lock for the stack cache. */
181 extern void __reclaim_stacks (void) attribute_hidden
;
183 /* longjmp handling. */
184 extern void __pthread_cleanup_upto (__jmp_buf target
, char *targetframe
);
187 /* Functions with versioned interfaces. */
188 extern int __pthread_create_2_1 (pthread_t
*newthread
,
189 const pthread_attr_t
*attr
,
190 void *(*start_routine
) (void *), void *arg
);
191 extern int __pthread_create_2_0 (pthread_t
*newthread
,
192 const pthread_attr_t
*attr
,
193 void *(*start_routine
) (void *), void *arg
);
194 extern int __pthread_attr_init_2_1 (pthread_attr_t
*attr
);
195 extern int __pthread_attr_init_2_0 (pthread_attr_t
*attr
);
198 /* Event handlers for libthread_db interface. */
199 extern void __nptl_create_event (void);
200 extern void __nptl_death_event (void);
201 hidden_proto (__nptl_create_event
)
202 hidden_proto (__nptl_death_event
)
204 /* Register the generation counter in the libpthread with the libc. */
205 #ifdef TLS_MULTIPLE_THREADS_IN_TCB
206 extern void __libc_pthread_init (unsigned long int *ptr
,
207 void (*reclaim
) (void),
208 const struct pthread_functions
*functions
)
211 extern int *__libc_pthread_init (unsigned long int *ptr
,
212 void (*reclaim
) (void),
213 const struct pthread_functions
*functions
)
216 /* Variable set to a nonzero value if more than one thread runs or ran. */
217 extern int __pthread_multiple_threads attribute_hidden
;
218 /* Pointer to the corresponding variable in libc. */
219 extern int *__libc_multiple_threads_ptr attribute_hidden
;
223 /* Namespace save aliases. */
224 extern int __pthread_getschedparam (pthread_t thread_id
, int *policy
,
225 struct sched_param
*param
);
226 extern int __pthread_setschedparam (pthread_t thread_id
, int policy
,
227 const struct sched_param
*param
);
228 extern int __pthread_setcancelstate (int state
, int *oldstate
);
229 extern int __pthread_mutex_init (pthread_mutex_t
*__mutex
,
230 __const pthread_mutexattr_t
*__mutexattr
);
231 extern int __pthread_mutex_init_internal (pthread_mutex_t
*__mutex
,
232 __const pthread_mutexattr_t
*__mutexattr
);
233 extern int __pthread_mutex_destroy (pthread_mutex_t
*__mutex
);
234 extern int __pthread_mutex_destroy_internal (pthread_mutex_t
*__mutex
);
235 extern int __pthread_mutex_trylock (pthread_mutex_t
*_mutex
);
236 extern int __pthread_mutex_lock (pthread_mutex_t
*__mutex
);
237 extern int __pthread_mutex_lock_internal (pthread_mutex_t
*__mutex
);
238 extern int __pthread_mutex_unlock (pthread_mutex_t
*__mutex
);
239 extern int __pthread_mutex_unlock_internal (pthread_mutex_t
*__mutex
);
240 extern int __pthread_mutexattr_init (pthread_mutexattr_t
*attr
);
241 extern int __pthread_mutexattr_destroy (pthread_mutexattr_t
*attr
);
242 extern int __pthread_mutexattr_settype (pthread_mutexattr_t
*attr
, int kind
);
243 extern int __pthread_attr_destroy (pthread_attr_t
*attr
);
244 extern int __pthread_attr_getdetachstate (const pthread_attr_t
*attr
,
246 extern int __pthread_attr_setdetachstate (pthread_attr_t
*attr
,
248 extern int __pthread_attr_getinheritsched (const pthread_attr_t
*attr
,
250 extern int __pthread_attr_setinheritsched (pthread_attr_t
*attr
, int inherit
);
251 extern int __pthread_attr_getschedparam (const pthread_attr_t
*attr
,
252 struct sched_param
*param
);
253 extern int __pthread_attr_setschedparam (pthread_attr_t
*attr
,
254 const struct sched_param
*param
);
255 extern int __pthread_attr_getschedpolicy (const pthread_attr_t
*attr
,
257 extern int __pthread_attr_setschedpolicy (pthread_attr_t
*attr
, int policy
);
258 extern int __pthread_attr_getscope (const pthread_attr_t
*attr
, int *scope
);
259 extern int __pthread_attr_setscope (pthread_attr_t
*attr
, int scope
);
260 extern int __pthread_attr_getstackaddr (__const pthread_attr_t
*__restrict
261 __attr
, void **__restrict __stackaddr
);
262 extern int __pthread_attr_setstackaddr (pthread_attr_t
*__attr
,
264 extern int __pthread_attr_getstacksize (__const pthread_attr_t
*__restrict
266 size_t *__restrict __stacksize
);
267 extern int __pthread_attr_setstacksize (pthread_attr_t
*__attr
,
269 extern int __pthread_attr_getstack (__const pthread_attr_t
*__restrict __attr
,
270 void **__restrict __stackaddr
,
271 size_t *__restrict __stacksize
);
272 extern int __pthread_attr_setstack (pthread_attr_t
*__attr
, void *__stackaddr
,
274 extern int __pthread_rwlock_init (pthread_rwlock_t
*__restrict __rwlock
,
275 __const pthread_rwlockattr_t
*__restrict
277 extern int __pthread_rwlock_destroy (pthread_rwlock_t
*__rwlock
);
278 extern int __pthread_rwlock_rdlock (pthread_rwlock_t
*__rwlock
);
279 extern int __pthread_rwlock_rdlock_internal (pthread_rwlock_t
*__rwlock
);
280 extern int __pthread_rwlock_tryrdlock (pthread_rwlock_t
*__rwlock
);
281 extern int __pthread_rwlock_wrlock (pthread_rwlock_t
*__rwlock
);
282 extern int __pthread_rwlock_wrlock_internal (pthread_rwlock_t
*__rwlock
);
283 extern int __pthread_rwlock_trywrlock (pthread_rwlock_t
*__rwlock
);
284 extern int __pthread_rwlock_unlock (pthread_rwlock_t
*__rwlock
);
285 extern int __pthread_rwlock_unlock_internal (pthread_rwlock_t
*__rwlock
);
286 extern int __pthread_cond_broadcast (pthread_cond_t
*cond
);
287 extern int __pthread_cond_destroy (pthread_cond_t
*cond
);
288 extern int __pthread_cond_init (pthread_cond_t
*cond
,
289 const pthread_condattr_t
*cond_attr
);
290 extern int __pthread_cond_signal (pthread_cond_t
*cond
);
291 extern int __pthread_cond_wait (pthread_cond_t
*cond
, pthread_mutex_t
*mutex
);
292 extern int __pthread_cond_timedwait (pthread_cond_t
*cond
,
293 pthread_mutex_t
*mutex
,
294 const struct timespec
*abstime
);
295 extern int __pthread_condattr_destroy (pthread_condattr_t
*attr
);
296 extern int __pthread_condattr_init (pthread_condattr_t
*attr
);
297 extern int __pthread_key_create (pthread_key_t
*key
, void (*destr
) (void *));
298 extern int __pthread_key_create_internal (pthread_key_t
*key
,
299 void (*destr
) (void *));
300 extern void *__pthread_getspecific (pthread_key_t key
);
301 extern void *__pthread_getspecific_internal (pthread_key_t key
);
302 extern int __pthread_setspecific (pthread_key_t key
, const void *value
);
303 extern int __pthread_setspecific_internal (pthread_key_t key
,
305 extern int __pthread_once (pthread_once_t
*once_control
,
306 void (*init_routine
) (void));
307 extern int __pthread_once_internal (pthread_once_t
*once_control
,
308 void (*init_routine
) (void));
309 extern int __pthread_atfork (void (*prepare
) (void), void (*parent
) (void),
310 void (*child
) (void));
311 extern pthread_t
__pthread_self (void);
312 extern int __pthread_equal (pthread_t thread1
, pthread_t thread2
);
313 extern int __pthread_kill (pthread_t threadid
, int signo
);
314 extern void __pthread_exit (void *value
);
315 extern int __pthread_setcanceltype (int type
, int *oldtype
);
316 extern int __pthread_enable_asynccancel (void) attribute_hidden
;
317 extern void __pthread_enable_asynccancel_2 (int *oldvalp
)
318 internal_function attribute_hidden
;
319 extern void __pthread_disable_asynccancel (int oldtype
)
320 internal_function attribute_hidden
;
322 extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t
*cond
);
323 extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t
*cond
);
324 extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t
*cond
,
325 const pthread_condattr_t
*cond_attr
);
326 extern int __pthread_cond_signal_2_0 (pthread_cond_2_0_t
*cond
);
327 extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t
*cond
,
328 pthread_mutex_t
*mutex
,
329 const struct timespec
*abstime
);
330 extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t
*cond
,
331 pthread_mutex_t
*mutex
);
335 /* The two functions are in libc.so and not exported. */
336 extern int __libc_enable_asynccancel (void) attribute_hidden
;
337 extern void __libc_disable_asynccancel (int oldtype
)
338 internal_function attribute_hidden
;
340 #ifdef IS_IN_libpthread
341 /* Special versions which use non-exported functions. */
342 extern void __pthread_cleanup_push (struct _pthread_cleanup_buffer
*buffer
,
343 void (*routine
) (void *), void *arg
)
345 # undef pthread_cleanup_push
346 # define pthread_cleanup_push(routine,arg) \
347 { struct _pthread_cleanup_buffer _buffer; \
348 __pthread_cleanup_push (&_buffer, (routine), (arg));
350 extern void __pthread_cleanup_pop (struct _pthread_cleanup_buffer
*buffer
,
351 int execute
) attribute_hidden
;
352 # undef pthread_cleanup_pop
353 # define pthread_cleanup_pop(execute) \
354 __pthread_cleanup_pop (&_buffer, (execute)); }
357 extern void __pthread_cleanup_push_defer (struct _pthread_cleanup_buffer
*buffer
,
358 void (*routine
) (void *), void *arg
);
359 extern void __pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer
*buffer
,
362 #endif /* pthreadP.h */