1 /* Linuxthreads - a simple clone()-based implementation of Posix */
2 /* threads for Linux. */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
5 /* This program is free software; you can redistribute it and/or */
6 /* modify it under the terms of the GNU Library General Public License */
7 /* as published by the Free Software Foundation; either version 2 */
8 /* of the License, or (at your option) any later version. */
10 /* This program 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 */
13 /* GNU Library General Public License for more details. */
15 /* Thread creation, initialization, and basic low-level routines */
25 #include "internals.h"
29 /* Descriptor of the initial thread */
31 struct _pthread_descr_struct __pthread_initial_thread = {
32 &__pthread_initial_thread, /* pthread_descr p_nextlive */
33 &__pthread_initial_thread, /* pthread_descr p_prevlive */
34 NULL, /* pthread_descr p_nextwaiting */
35 PTHREAD_THREADS_MAX, /* pthread_t p_tid */
37 0, /* int p_priority */
38 &__pthread_handles[0].h_spinlock, /* int * p_spinlock */
40 NULL, /* sigjmp_buf * p_signal_buf */
41 NULL, /* sigjmp_buf * p_cancel_buf */
42 0, /* char p_terminated */
43 0, /* char p_detached */
44 0, /* char p_exited */
45 NULL, /* void * p_retval */
47 NULL, /* pthread_descr p_joining */
48 NULL, /* struct _pthread_cleanup_buffer * p_cleanup */
49 0, /* char p_cancelstate */
50 0, /* char p_canceltype */
51 0, /* char p_canceled */
52 NULL, /* int *p_errnop */
54 NULL, /* int *p_h_errnop */
55 0, /* int p_h_errno */
56 PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
57 {NULL} /* void * p_specific[PTHREAD_KEYS_MAX] */
60 /* Descriptor of the manager thread; none of this is used but the error
61 variables and the address for identification. */
63 struct _pthread_descr_struct __pthread_manager_thread = {
64 NULL, /* pthread_descr p_nextlive */
65 NULL, /* pthread_descr p_prevlive */
66 NULL, /* pthread_descr p_nextwaiting */
69 0, /* int p_priority */
70 NULL, /* int * p_spinlock */
72 NULL, /* sigjmp_buf * p_signal_buf */
73 NULL, /* sigjmp_buf * p_cancel_buf */
74 0, /* char p_terminated */
75 0, /* char p_detached */
76 0, /* char p_exited */
77 NULL, /* void * p_retval */
79 NULL, /* pthread_descr p_joining */
80 NULL, /* struct _pthread_cleanup_buffer * p_cleanup */
81 0, /* char p_cancelstate */
82 0, /* char p_canceltype */
83 0, /* char p_canceled */
84 NULL, /* int *p_errnop */
86 NULL, /* int *p_h_errnop */
87 0, /* int p_h_errno */
88 PTHREAD_START_ARGS_INITIALIZER, /* struct pthread_start_args p_start_args */
89 {NULL} /* void * p_specific[PTHREAD_KEYS_MAX] */
92 /* Pointer to the main thread (the father of the thread manager thread) */
93 /* Originally, this is the initial thread, but this changes after fork() */
95 pthread_descr __pthread_main_thread = &__pthread_initial_thread;
97 /* Limit between the stack of the initial thread (above) and the
98 stacks of other threads (below). Aligned on a STACK_SIZE boundary. */
100 char *__pthread_initial_thread_bos = NULL;
102 /* File descriptor for sending requests to the thread manager. */
103 /* Initially -1, meaning that the thread manager is not running. */
105 int __pthread_manager_request = -1;
107 /* Other end of the pipe for sending requests to the thread manager. */
109 int __pthread_manager_reader;
111 /* PID of thread manager */
113 static int __pthread_manager_pid;
115 /* Limits of the thread manager stack */
117 char *__pthread_manager_thread_bos = NULL;
118 char *__pthread_manager_thread_tos = NULL;
120 /* For process-wide exit() */
122 int __pthread_exit_requested = 0;
123 int __pthread_exit_code = 0;
125 /* Signal numbers used for the communication. */
126 int __pthread_sig_restart;
127 int __pthread_sig_cancel;
129 /* These variables are used by the setup code. */
133 /* Forward declarations */
135 static void pthread_exit_process(int retcode, void *arg);
136 static void pthread_handle_sigcancel(int sig);
138 /* Initialize the pthread library.
139 Initialization is split in two functions:
140 - a constructor function that blocks the PTHREAD_SIG_RESTART signal
141 (must do this very early, since the program could capture the signal
142 mask with e.g. sigsetjmp before creating the first thread);
143 - a regular function called from pthread_create when needed. */
145 static void pthread_initialize(void) __attribute__((constructor));
147 static void pthread_initialize(void)
152 /* If already done (e.g. by a constructor called earlier!), bail out */
153 if (__pthread_initial_thread_bos != NULL) return;
154 /* For the initial stack, reserve at least STACK_SIZE bytes of stack
155 below the current stack address, and align that on a
156 STACK_SIZE boundary. */
157 __pthread_initial_thread_bos =
158 (char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
159 /* Update the descriptor for the initial thread. */
160 __pthread_initial_thread.p_pid = __getpid();
161 /* If we have special thread_self processing, initialize that for the
163 #ifdef INIT_THREAD_SELF
164 INIT_THREAD_SELF(&__pthread_initial_thread);
166 /* The errno/h_errno variable of the main thread are the global ones. */
167 __pthread_initial_thread.p_errnop = &_errno;
168 __pthread_initial_thread.p_h_errnop = &_h_errno;
170 /* Allocate the signals used. */
171 __pthread_sig_restart = __libc_allocate_rtsig (1);
172 __pthread_sig_cancel = __libc_allocate_rtsig (1);
173 if (__pthread_sig_restart < 0 || __pthread_sig_cancel < 0)
175 /* The kernel does not support real-time signals. Use as before
176 the available signals in the fixed set. */
177 __pthread_sig_restart = SIGUSR1;
178 __pthread_sig_cancel = SIGUSR2;
181 /* Setup signal handlers for the initial thread.
182 Since signal handlers are shared between threads, these settings
183 will be inherited by all other threads. */
184 sa.sa_handler = __pthread_sighandler;
185 sigemptyset(&sa.sa_mask);
186 sa.sa_flags = SA_RESTART; /* does not matter for regular threads, but
187 better for the thread manager */
188 sigaction(PTHREAD_SIG_RESTART, &sa, NULL);
189 sa.sa_handler = pthread_handle_sigcancel;
191 sigaction(PTHREAD_SIG_CANCEL, &sa, NULL);
193 /* Initially, block PTHREAD_SIG_RESTART. Will be unblocked on demand. */
195 sigaddset(&mask, PTHREAD_SIG_RESTART);
196 sigprocmask(SIG_BLOCK, &mask, NULL);
197 /* Register an exit function to kill all other threads. */
198 /* Do it early so that user-registered atexit functions are called
199 before pthread_exit_process. */
200 __on_exit(pthread_exit_process, NULL);
203 static int pthread_initialize_manager(void)
207 /* If basic initialization not done yet (e.g. we're called from a
208 constructor run before our constructor), do it now */
209 if (__pthread_initial_thread_bos == NULL) pthread_initialize();
210 /* Setup stack for thread manager */
211 __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
212 if (__pthread_manager_thread_bos == NULL) return -1;
213 __pthread_manager_thread_tos =
214 __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
215 /* Setup pipe to communicate with thread manager */
216 if (pipe(manager_pipe) == -1) {
217 free(__pthread_manager_thread_bos);
220 __pthread_manager_request = manager_pipe[1]; /* writing end */
221 __pthread_manager_reader = manager_pipe[0]; /* reading end */
222 /* Start the thread manager */
223 __pthread_manager_pid =
224 __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
225 CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
226 (void *)(long)manager_pipe[0]);
227 if (__pthread_manager_pid == -1) {
228 free(__pthread_manager_thread_bos);
229 __libc_close(manager_pipe[0]);
230 __libc_close(manager_pipe[1]);
231 __pthread_manager_request = -1;
237 /* Thread creation */
239 int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
240 void * (*start_routine)(void *), void *arg)
242 pthread_descr self = thread_self();
243 struct pthread_request request;
244 if (__pthread_manager_request < 0) {
245 if (pthread_initialize_manager() < 0) return EAGAIN;
247 request.req_thread = self;
248 request.req_kind = REQ_CREATE;
249 request.req_args.create.attr = attr;
250 request.req_args.create.fn = start_routine;
251 request.req_args.create.arg = arg;
252 sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
253 &request.req_args.create.mask);
254 __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
256 if (self->p_retcode == 0) *thread = (pthread_t) self->p_retval;
257 return self->p_retcode;
260 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
261 default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
263 int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
264 void * (*start_routine)(void *), void *arg)
266 /* The ATTR attribute is not really of type `pthread_attr_t *'. It has
267 the old size and access to the new members might crash the program.
268 We convert the struct now. */
269 pthread_attr_t new_attr;
273 size_t ps = __getpagesize ();
275 memcpy (&new_attr, attr, (size_t) &(((pthread_attr_t*)NULL)->guardsize));
276 new_attr.guardsize = ps;
277 new_attr.stackaddr_set = 0;
278 new_attr.stackaddr = NULL;
279 new_attr.stacksize = STACK_SIZE - ps;
282 return __pthread_create_2_1 (thread, attr, start_routine, arg);
284 symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
286 strong_alias (__pthread_create_2_1, pthread_create)
289 /* Simple operations on thread identifiers */
291 pthread_t pthread_self(void)
293 pthread_descr self = thread_self();
297 int pthread_equal(pthread_t thread1, pthread_t thread2)
299 return thread1 == thread2;
302 /* Thread scheduling */
304 int pthread_setschedparam(pthread_t thread, int policy,
305 const struct sched_param *param)
307 pthread_handle handle = thread_handle(thread);
310 acquire(&handle->h_spinlock);
311 if (invalid_handle(handle, thread)) {
312 release(&handle->h_spinlock);
315 th = handle->h_descr;
316 if (__sched_setscheduler(th->p_pid, policy, param) == -1) {
317 release(&handle->h_spinlock);
320 th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
321 release(&handle->h_spinlock);
325 int pthread_getschedparam(pthread_t thread, int *policy,
326 struct sched_param *param)
328 pthread_handle handle = thread_handle(thread);
331 acquire(&handle->h_spinlock);
332 if (invalid_handle(handle, thread)) {
333 release(&handle->h_spinlock);
336 pid = handle->h_descr->p_pid;
337 release(&handle->h_spinlock);
338 pol = __sched_getscheduler(pid);
339 if (pol == -1) return errno;
340 if (__sched_getparam(pid, param) == -1) return errno;
345 /* Process-wide exit() request */
347 static void pthread_exit_process(int retcode, void *arg)
349 struct pthread_request request;
350 pthread_descr self = thread_self();
352 if (__pthread_manager_request >= 0) {
353 request.req_thread = self;
354 request.req_kind = REQ_PROCESS_EXIT;
355 request.req_args.exit.code = retcode;
356 __libc_write(__pthread_manager_request,
357 (char *) &request, sizeof(request));
359 /* Main thread should accumulate times for thread manager and its
360 children, so that timings for main thread account for all threads. */
361 if (self == __pthread_main_thread)
362 waitpid(__pthread_manager_pid, NULL, __WCLONE);
366 /* The handler for the RESTART signal just records the signal received
367 in the thread descriptor, and optionally performs a siglongjmp
368 (for pthread_cond_timedwait). Also used in sigwait.
369 For the thread manager thread, redirect the signal to
370 __pthread_manager_sighandler. */
372 void __pthread_sighandler(int sig)
374 pthread_descr self = thread_self();
375 if (self == &__pthread_manager_thread) {
376 __pthread_manager_sighandler(sig);
378 self->p_signal = sig;
379 if (self->p_signal_jmp != NULL) siglongjmp(*self->p_signal_jmp, 1);
383 /* The handler for the CANCEL signal checks for cancellation
384 (in asynchronous mode) and for process-wide exit and exec requests. */
386 static void pthread_handle_sigcancel(int sig)
388 pthread_descr self = thread_self();
391 if (__pthread_exit_requested) {
392 /* Main thread should accumulate times for thread manager and its
393 children, so that timings for main thread account for all threads. */
394 if (self == __pthread_main_thread)
395 waitpid(__pthread_manager_pid, NULL, __WCLONE);
396 _exit(__pthread_exit_code);
398 if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
399 if (self->p_canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
400 pthread_exit(PTHREAD_CANCELED);
401 jmpbuf = self->p_cancel_jmp;
402 if (jmpbuf != NULL) {
403 self->p_cancel_jmp = NULL;
404 siglongjmp(*jmpbuf, 1);
409 /* Reset the state of the thread machinery after a fork().
410 Close the pipe used for requests and set the main thread to the forked
412 Notice that we can't free the stack segments, as the forked thread
413 may hold pointers into them. */
415 void __pthread_reset_main_thread()
417 pthread_descr self = thread_self();
419 if (__pthread_manager_request != -1) {
420 /* Free the thread manager stack */
421 free(__pthread_manager_thread_bos);
422 __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
423 /* Close the two ends of the pipe */
424 __libc_close(__pthread_manager_request);
425 __libc_close(__pthread_manager_reader);
426 __pthread_manager_request = __pthread_manager_reader = -1;
428 /* Update the pid of the main thread */
429 self->p_pid = __getpid();
430 /* Make the forked thread the main thread */
431 __pthread_main_thread = self;
432 self->p_nextlive = self;
433 self->p_prevlive = self;
434 /* Now this thread modifies the global variables. */
435 self->p_errnop = &_errno;
436 self->p_h_errnop = &_h_errno;
439 /* Process-wide exec() request */
441 void __pthread_kill_other_threads_np(void)
443 /* Terminate all other threads and thread manager */
444 pthread_exit_process(0, NULL);
445 /* Make current thread the main thread in case the calling thread
446 changes its mind, does not exec(), and creates new threads instead. */
447 __pthread_reset_main_thread();
449 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
451 /* Concurrency symbol level. */
452 static int current_level;
454 int __pthread_setconcurrency(int level)
456 /* We don't do anything unless we have found a useful interpretation. */
457 current_level = level;
460 weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
462 int __pthread_getconcurrency(void)
464 return current_level;
466 weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
473 void __pthread_message(char * fmt, long arg)
477 sprintf(buffer, "%05d : ", __getpid());
479 vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
481 __libc_write(2, buffer, strlen(buffer));
488 /* We need a hook to force the cancelation wrappers to be linked in when
489 static libpthread is used. */
490 extern const int __pthread_provide_wrappers;
491 static const int *const __pthread_require_wrappers =
492 &__pthread_provide_wrappers;