(pthread_create): Add new interface for changed pthread_attr_t.
[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   /* Allocate the signals used.  */
170   __pthread_sig_restart = __libc_allocate_rtsig (1);
171   __pthread_sig_cancel = __libc_allocate_rtsig (1);
172   if (__pthread_sig_restart < 0 || __pthread_sig_cancel < 0)
173     {
174       /* The kernel does not support real-time signals.  Use as before
175          the available signals in the fixed set.  */
176       __pthread_sig_restart = SIGUSR1;
177       __pthread_sig_cancel = SIGUSR2;
178     }
179   /* Setup signal handlers for the initial thread.
180      Since signal handlers are shared between threads, these settings
181      will be inherited by all other threads. */
182   sa.sa_handler = __pthread_sighandler;
183   sigemptyset(&sa.sa_mask);
184   sa.sa_flags = SA_RESTART; /* does not matter for regular threads, but
185                                better for the thread manager */
186   sigaction(PTHREAD_SIG_RESTART, &sa, NULL);
187   sa.sa_handler = pthread_handle_sigcancel;
188   sa.sa_flags = 0;
189   sigaction(PTHREAD_SIG_CANCEL, &sa, NULL);
190
191   /* Initially, block PTHREAD_SIG_RESTART. Will be unblocked on demand. */
192   sigemptyset(&mask);
193   sigaddset(&mask, PTHREAD_SIG_RESTART);
194   sigprocmask(SIG_BLOCK, &mask, NULL);
195   /* Register an exit function to kill all other threads. */
196   /* Do it early so that user-registered atexit functions are called
197      before pthread_exit_process. */
198   __on_exit(pthread_exit_process, NULL);
199 }
200
201 static int pthread_initialize_manager(void)
202 {
203   int manager_pipe[2];
204
205   /* If basic initialization not done yet (e.g. we're called from a
206      constructor run before our constructor), do it now */
207   if (__pthread_initial_thread_bos == NULL) pthread_initialize();
208   /* Setup stack for thread manager */
209   __pthread_manager_thread_bos = malloc(THREAD_MANAGER_STACK_SIZE);
210   if (__pthread_manager_thread_bos == NULL) return -1;
211   __pthread_manager_thread_tos =
212     __pthread_manager_thread_bos + THREAD_MANAGER_STACK_SIZE;
213   /* Setup pipe to communicate with thread manager */
214   if (pipe(manager_pipe) == -1) {
215     free(__pthread_manager_thread_bos);
216     return -1;
217   }
218   __pthread_manager_request = manager_pipe[1]; /* writing end */
219   __pthread_manager_reader = manager_pipe[0]; /* reading end */
220   /* Start the thread manager */
221   __pthread_manager_pid =
222     __clone(__pthread_manager, (void **) __pthread_manager_thread_tos,
223             CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
224             (void *)(long)manager_pipe[0]);
225   if (__pthread_manager_pid == -1) {
226     free(__pthread_manager_thread_bos);
227     __libc_close(manager_pipe[0]);
228     __libc_close(manager_pipe[1]);
229     __pthread_manager_request = -1;
230     return -1;
231   }
232   return 0;
233 }
234
235 /* Thread creation */
236
237 int __pthread_create_2_1(pthread_t *thread, const pthread_attr_t *attr,
238                          void * (*start_routine)(void *), void *arg)
239 {
240   pthread_descr self = thread_self();
241   struct pthread_request request;
242   if (__pthread_manager_request < 0) {
243     if (pthread_initialize_manager() < 0) return EAGAIN;
244   }
245   request.req_thread = self;
246   request.req_kind = REQ_CREATE;
247   request.req_args.create.attr = attr;
248   request.req_args.create.fn = start_routine;
249   request.req_args.create.arg = arg;
250   sigprocmask(SIG_SETMASK, (const sigset_t *) NULL,
251               &request.req_args.create.mask);
252   __libc_write(__pthread_manager_request, (char *) &request, sizeof(request));
253   suspend(self);
254   if (self->p_retcode == 0) *thread = (pthread_t) self->p_retval;
255   return self->p_retcode;
256 }
257
258 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
259 default_symbol_version (__pthread_create_2_1, pthread_create, GLIBC_2.1);
260
261 int __pthread_create_2_0(pthread_t *thread, const pthread_attr_t *attr,
262                          void * (*start_routine)(void *), void *arg)
263 {
264   /* The ATTR attribute is not really of type `pthread_attr_t *'.  It has
265      the old size and access to the new members might crash the program.
266      We convert the struct now.  */
267   pthread_attr_t new_attr;
268
269   if (attr != NULL)
270     {
271       size_t ps = __getpagesize ();
272
273       memcpy (&new_attr, attr, (size_t) &(((pthread_attr_t*)NULL)->guardsize));
274       new_attr.guardsize = ps;
275       new_attr.stackaddr_set = 0;
276       new_attr.stackaddr = NULL;
277       new_attr.stacksize = STACK_SIZE - ps;
278       attr = &new_attr;
279     }
280   return __pthread_create_2_1 (thread, attr, start_routine, arg);
281 }
282 symbol_version (__pthread_create_2_0, pthread_create, GLIBC_2.0);
283 #else
284 strong_alias (__pthread_create_2_1, pthread_create)
285 #endif
286
287 /* Simple operations on thread identifiers */
288
289 pthread_t pthread_self(void)
290 {
291   pthread_descr self = thread_self();
292   return self->p_tid;
293 }
294
295 int pthread_equal(pthread_t thread1, pthread_t thread2)
296 {
297   return thread1 == thread2;
298 }
299
300 /* Thread scheduling */
301
302 int pthread_setschedparam(pthread_t thread, int policy,
303                           const struct sched_param *param)
304 {
305   pthread_handle handle = thread_handle(thread);
306   pthread_descr th;
307
308   acquire(&handle->h_spinlock);
309   if (invalid_handle(handle, thread)) {
310     release(&handle->h_spinlock);
311     return ESRCH;
312   }
313   th = handle->h_descr;
314   if (__sched_setscheduler(th->p_pid, policy, param) == -1) {
315     release(&handle->h_spinlock);
316     return errno;
317   }
318   th->p_priority = policy == SCHED_OTHER ? 0 : param->sched_priority;
319   release(&handle->h_spinlock);
320   return 0;
321 }
322
323 int pthread_getschedparam(pthread_t thread, int *policy,
324                           struct sched_param *param)
325 {
326   pthread_handle handle = thread_handle(thread);
327   int pid, pol;
328
329   acquire(&handle->h_spinlock);
330   if (invalid_handle(handle, thread)) {
331     release(&handle->h_spinlock);
332     return ESRCH;
333   }
334   pid = handle->h_descr->p_pid;
335   release(&handle->h_spinlock);
336   pol = __sched_getscheduler(pid);
337   if (pol == -1) return errno;
338   if (__sched_getparam(pid, param) == -1) return errno;
339   *policy = pol;
340   return 0;
341 }
342
343 /* Process-wide exit() request */
344
345 static void pthread_exit_process(int retcode, void *arg)
346 {
347   struct pthread_request request;
348   pthread_descr self = thread_self();
349
350   if (__pthread_manager_request >= 0) {
351     request.req_thread = self;
352     request.req_kind = REQ_PROCESS_EXIT;
353     request.req_args.exit.code = retcode;
354     __libc_write(__pthread_manager_request,
355                  (char *) &request, sizeof(request));
356     suspend(self);
357     /* Main thread should accumulate times for thread manager and its
358        children, so that timings for main thread account for all threads. */
359     if (self == __pthread_main_thread)
360       waitpid(__pthread_manager_pid, NULL, __WCLONE);
361   }
362 }
363
364 /* The handler for the RESTART signal just records the signal received
365    in the thread descriptor, and optionally performs a siglongjmp
366    (for pthread_cond_timedwait). Also used in sigwait.
367    For the thread manager thread, redirect the signal to
368    __pthread_manager_sighandler. */
369
370 void __pthread_sighandler(int sig)
371 {
372   pthread_descr self = thread_self();
373   if (self == &__pthread_manager_thread) {
374     __pthread_manager_sighandler(sig);
375   } else {
376     self->p_signal = sig;
377     if (self->p_signal_jmp != NULL) siglongjmp(*self->p_signal_jmp, 1);
378   }
379 }
380
381 /* The handler for the CANCEL signal checks for cancellation
382    (in asynchronous mode) and for process-wide exit and exec requests. */
383
384 static void pthread_handle_sigcancel(int sig)
385 {
386   pthread_descr self = thread_self();
387   sigjmp_buf * jmpbuf;
388
389   if (__pthread_exit_requested) {
390     /* Main thread should accumulate times for thread manager and its
391        children, so that timings for main thread account for all threads. */
392     if (self == __pthread_main_thread)
393       waitpid(__pthread_manager_pid, NULL, __WCLONE);
394     _exit(__pthread_exit_code);
395   }
396   if (self->p_canceled && self->p_cancelstate == PTHREAD_CANCEL_ENABLE) {
397     if (self->p_canceltype == PTHREAD_CANCEL_ASYNCHRONOUS)
398       pthread_exit(PTHREAD_CANCELED);
399     jmpbuf = self->p_cancel_jmp;
400     if (jmpbuf != NULL) {
401       self->p_cancel_jmp = NULL;
402       siglongjmp(*jmpbuf, 1);
403     }
404   }
405 }
406
407 /* Reset the state of the thread machinery after a fork().
408    Close the pipe used for requests and set the main thread to the forked
409    thread.
410    Notice that we can't free the stack segments, as the forked thread
411    may hold pointers into them. */
412
413 void __pthread_reset_main_thread()
414 {
415   pthread_descr self = thread_self();
416
417   if (__pthread_manager_request != -1) {
418     /* Free the thread manager stack */
419     free(__pthread_manager_thread_bos);
420     __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL;
421     /* Close the two ends of the pipe */
422     __libc_close(__pthread_manager_request);
423     __libc_close(__pthread_manager_reader);
424     __pthread_manager_request = __pthread_manager_reader = -1;
425   }
426   /* Update the pid of the main thread */
427   self->p_pid = __getpid();
428   /* Make the forked thread the main thread */
429   __pthread_main_thread = self;
430   self->p_nextlive = self;
431   self->p_prevlive = self;
432   /* Now this thread modifies the global variables.  */
433   self->p_errnop = &_errno;
434   self->p_h_errnop = &_h_errno;
435 }
436
437 /* Process-wide exec() request */
438
439 void __pthread_kill_other_threads_np(void)
440 {
441   /* Terminate all other threads and thread manager */
442   pthread_exit_process(0, NULL);
443   /* Make current thread the main thread in case the calling thread
444      changes its mind, does not exec(), and creates new threads instead. */
445   __pthread_reset_main_thread();
446 }
447 weak_alias (__pthread_kill_other_threads_np, pthread_kill_other_threads_np)
448
449 /* Concurrency symbol level.  */
450 static int current_level;
451
452 int __pthread_setconcurrency(int level)
453 {
454   /* We don't do anything unless we have found a useful interpretation.  */
455   current_level = level;
456   return 0;
457 }
458 weak_alias (__pthread_setconcurrency, pthread_setconcurrency)
459
460 int __pthread_getconcurrency(void)
461 {
462   return current_level;
463 }
464 weak_alias (__pthread_getconcurrency, pthread_getconcurrency)
465
466 /* Debugging aid */
467
468 #ifdef DEBUG
469 #include <stdarg.h>
470
471 void __pthread_message(char * fmt, long arg)
472 {
473   char buffer[1024];
474   va_list args;
475   sprintf(buffer, "%05d : ", __getpid());
476   va_start(args, fmt);
477   vsnprintf(buffer + 8, sizeof(buffer) - 8, fmt, args);
478   va_end(args);
479   __libc_write(2, buffer, strlen(buffer));
480 }
481
482 #endif
483
484
485 #ifndef PIC
486 /* We need a hook to force the cancelation wrappers to be linked in when
487    static libpthread is used.  */
488 extern const int __pthread_provide_wrappers;
489 static const int *const __pthread_require_wrappers =
490   &__pthread_provide_wrappers;
491 #endif