Update.
[kopensolaris-gnu/glibc.git] / linuxthreads / pthread.c
1 /* Linuxthreads - a simple clone()-based implementation of Posix        */
2 /* threads for Linux.                                                   */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr)              */
4 /*                                                                      */
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.               */
9 /*                                                                      */
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.                 */
14
15 /* Thread creation, initialization, and basic low-level routines */
16
17 #include <stddef.h>
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <unistd.h>
22 #include <fcntl.h>
23 #include <sys/wait.h>
24 #include "pthread.h"
25 #include "internals.h"
26 #include "spinlock.h"
27 #include "restart.h"
28
29 /* Descriptor of the initial thread */
30
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 */
36   0,                          /* int p_pid */
37   0,                          /* int p_priority */
38   &__pthread_handles[0].h_spinlock, /* int * p_spinlock */
39   0,                          /* int p_signal */
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 */
46   0,                          /* int 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 */
53   0,                          /* int p_errno */
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] */
58 };
59
60 /* Descriptor of the manager thread; none of this is used but the error
61    variables and the address for identification.  */
62
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 */
67   0,                          /* int p_tid */
68   0,                          /* int p_pid */
69   0,                          /* int p_priority */
70   NULL,                       /* int * p_spinlock */
71   0,                          /* int p_signal */
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 */
78   0,                          /* int 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 */
85   0,                          /* int p_errno */
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] */
90 };
91
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() */
94
95 pthread_descr __pthread_main_thread = &__pthread_initial_thread;
96
97 /* Limit between the stack of the initial thread (above) and the
98    stacks of other threads (below). Aligned on a STACK_SIZE boundary. */
99
100 char *__pthread_initial_thread_bos = NULL;
101
102 /* File descriptor for sending requests to the thread manager. */
103 /* Initially -1, meaning that the thread manager is not running. */
104
105 int __pthread_manager_request = -1;
106
107 /* Other end of the pipe for sending requests to the thread manager. */
108
109 int __pthread_manager_reader;
110
111 /* PID of thread manager */
112
113 static int __pthread_manager_pid;
114
115 /* Limits of the thread manager stack */
116
117 char *__pthread_manager_thread_bos = NULL;
118 char *__pthread_manager_thread_tos = NULL;
119
120 /* For process-wide exit() */
121
122 int __pthread_exit_requested = 0;
123 int __pthread_exit_code = 0;
124
125 /* Signal numbers used for the communication.  */
126 int __pthread_sig_restart;
127 int __pthread_sig_cancel;
128
129 /* These variables are used by the setup code.  */
130 extern int _errno;
131 extern int _h_errno;
132
133 /* Forward declarations */
134
135 static void pthread_exit_process(int retcode, void *arg);
136 static void pthread_handle_sigcancel(int sig);
137
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. */
144
145 static void pthread_initialize(void) __attribute__((constructor));
146
147 static void pthread_initialize(void)
148 {
149   struct sigaction sa;
150   sigset_t mask;
151
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
162      main thread now.  */
163 #ifdef INIT_THREAD_SELF
164   INIT_THREAD_SELF(&__pthread_initial_thread);
165 #endif
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;
169 #ifdef SIGRTMIN
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)
174     {
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;
179     }
180 #endif
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;
190   sa.sa_flags = 0;
191   sigaction(PTHREAD_SIG_CANCEL, &sa, NULL);
192
193   /* Initially, block PTHREAD_SIG_RESTART. Will be unblocked on demand. */
194   sigemptyset(&mask);
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);
201 }
202
203 static int pthread_initialize_manager(void)
204 {
205   int manager_pipe[2];
206
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);
218     return -1;
219   }
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;
232     return -1;
233   }
234   return 0;
235 }
236
237 /* Thread creation */
238
239 int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
240                          void * (*start_routine)(void *), void *arg)
241 {
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;
246   }
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));
255   suspend(self);
256   if (self->p_retcode == 0) *thread = (pthread_t) self->p_retval;
257   return self->p_retcode;
258 }
259
260 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
261 default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
262
263 int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
264                          void * (*start_routine)(void *), void *arg)
265 {
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;
270
271   if (attr != NULL)
272     {
273       size_t ps = __getpagesize ();
274
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;
280       attr = &new_attr;
281     }
282   return __pthread_create_2_1 (thread, attr, start_routine, arg);
283 }
284 symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
285 #else
286 strong_alias (__pthread_create_2_1, pthread_create)
287 #endif
288
289 /* Simple operations on thread identifiers */
290
291 pthread_t pthread_self(void)
292 {
293   pthread_descr self = thread_self();
294   return self->p_tid;
295 }
296
297 int pthread_equal(pthread_t thread1, pthread_t thread2)
298 {
299   return thread1 == thread2;
300 }
301
302 /* Thread scheduling */
303
304 int pthread_setschedparam(pthread_t thread, int policy,
305                           const struct sched_param *param)
306 {
307   pthread_handle handle = thread_handle(thread);
308   pthread_descr th;
309
310   acquire(&handle->h_spinlock);
311   if (invalid_handle(handle, thread)) {
312     release(&handle->h_spinlock);
313     return ESRCH;
314   }
315   th = handle->h_descr;
316   if (__sched_setscheduler(th->p_pid, policy, param) == -1) {
317     release(&handle->h_spinlock);
318     return errno;
319   }
320   th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
321   release(&handle->h_spinlock);
322   return 0;
323 }
324
325 int pthread_getschedparam(pthread_t thread, int *policy,
326                           struct sched_param *param)
327 {
328   pthread_handle handle = thread_handle(thread);
329   int pid, pol;
330
331   acquire(&handle->h_spinlock);
332   if (invalid_handle(handle, thread)) {
333     release(&handle->h_spinlock);
334     return ESRCH;
335   }
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;
341   *policy = pol;
342   return 0;
343 }
344
345 /* Process-wide exit() request */
346
347 static void pthread_exit_process(int retcode, void *arg)
348 {
349   struct pthread_request request;
350   pthread_descr self = thread_self();
351
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));
358     suspend(self);
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);
363   }
364 }
365
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. */
371
372 void __pthread_sighandler(int sig)
373 {
374   pthread_descr self = thread_self();
375   if (self == &__pthread_manager_thread) {
376     __pthread_manager_sighandler(sig);
377   } else {
378     self->p_signal = sig;
379     if (self->p_signal_jmp != NULL) siglongjmp(*self->p_signal_jmp, 1);
380   }
381 }
382
383 /* The handler for the CANCEL signal checks for cancellation
384    (in asynchronous mode) and for process-wide exit and exec requests. */
385
386 static void pthread_handle_sigcancel(int sig)
387 {
388   pthread_descr self = thread_self();
389   sigjmp_buf * jmpbuf;
390
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);
397   }
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);
405     }
406   }
407 }
408
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
411    thread.
412    Notice that we can't free the stack segments, as the forked thread
413    may hold pointers into them. */
414
415 void __pthread_reset_main_thread()
416 {
417   pthread_descr self = thread_self();
418
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;
427   }
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;
437 }
438
439 /* Process-wide exec() request */
440
441 void __pthread_kill_other_threads_np(void)
442 {
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();
448 }
449 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
450
451 /* Concurrency symbol level.  */
452 static int current_level;
453
454 int __pthread_setconcurrency(int level)
455 {
456   /* We don't do anything unless we have found a useful interpretation.  */
457   current_level = level;
458   return 0;
459 }
460 weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
461
462 int __pthread_getconcurrency(void)
463 {
464   return current_level;
465 }
466 weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
467
468 /* Debugging aid */
469
470 #ifdef DEBUG
471 #include <stdarg.h>
472
473 void __pthread_message(char * fmt, long arg)
474 {
475   char buffer[1024];
476   va_list args;
477   sprintf(buffer, "%05d : ", __getpid());
478   va_start(args, fmt);
479   vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
480   va_end(args);
481   __libc_write(2, buffer, strlen(buffer));
482 }
483
484 #endif
485
486
487 #ifndef PIC
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;
493 #endif