diff options
author | Daniel Eischen <deischen@FreeBSD.org> | 2001-01-24 13:03:38 +0000 |
---|---|---|
committer | Daniel Eischen <deischen@FreeBSD.org> | 2001-01-24 13:03:38 +0000 |
commit | e5106342c6de9cbe26c4827e4e29bae309cd8cfb (patch) | |
tree | 5199387f09deaa21f12482317c165f815c4e8c2b /lib/libpthread/thread/thr_init.c | |
parent | f9447cd11209a5fb5ecef3f4cbe539e990f3b1bd (diff) | |
download | src-e5106342c6de9cbe26c4827e4e29bae309cd8cfb.tar.gz src-e5106342c6de9cbe26c4827e4e29bae309cd8cfb.zip |
Add weak definitions for wrapped system calls. In general:
_foo - wrapped system call
foo - weak definition to _foo
and for cancellation points:
_foo - wrapped system call
__foo - enter cancellation point, call _foo(), leave
cancellation point
foo - weak definition to __foo
Change use of global _thread_run to call a function to get the
currently running thread.
Make all pthread_foo functions weak definitions to _pthread_foo,
where _pthread_foo is the implementation. This allows an application
to provide its own pthread functions.
Provide slightly different versions of pthread_mutex_lock and
pthread_mutex_init so that we can tell the difference between
a libc mutex and an application mutex. Threads holding mutexes
internal to libc should never be allowed to exit, call signal
handlers, or cancel.
Approved by: -arch
Notes
Notes:
svn path=/head/; revision=71581
Diffstat (limited to 'lib/libpthread/thread/thr_init.c')
-rw-r--r-- | lib/libpthread/thread/thr_init.c | 210 |
1 files changed, 119 insertions, 91 deletions
diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c index 93d7849394bf..c92efe3e8595 100644 --- a/lib/libpthread/thread/thr_init.c +++ b/lib/libpthread/thread/thr_init.c @@ -35,74 +35,117 @@ /* Allocate space for global thread variables here: */ #define GLOBAL_PTHREAD_PRIVATE -#include <errno.h> -#include <stdlib.h> -#include <string.h> -#include <fcntl.h> -#include <paths.h> -#include <poll.h> -#include <unistd.h> +#include "namespace.h" +#include <sys/param.h> +#include <sys/types.h> +#include <machine/reg.h> + #include <sys/ioctl.h> +#include <sys/mount.h> +#include <sys/uio.h> +#include <sys/socket.h> +#include <sys/event.h> +#include <sys/stat.h> #include <sys/sysctl.h> #include <sys/time.h> #include <sys/ttycom.h> -#include <sys/param.h> #include <sys/user.h> +#include <sys/wait.h> #include <sys/mman.h> -#ifdef _THREAD_SAFE -#include <machine/reg.h> +#include <dirent.h> +#include <errno.h> +#include <fcntl.h> +#include <paths.h> +#include <poll.h> #include <pthread.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include "un-namespace.h" + #include "pthread_private.h" /* + * All weak references used within libc should be in this table. + * This will is so that static libraries will work. + */ +static void *references[] = { + &_accept, + &_bind, + &_close, + &_connect, + &_dup, + &_dup2, + &_execve, + &_fcntl, + &_flock, + &_flockfile, + &_fstat, + &_fstatfs, + &_fsync, + &_funlockfile, + &_getdirentries, + &_getlogin, + &_getpeername, + &_getsockname, + &_getsockopt, + &_ioctl, + &_kevent, + &_listen, + &_nanosleep, + &_open, + &_pthread_getspecific, + &_pthread_key_create, + &_pthread_key_delete, + &_pthread_mutex_destroy, + &_pthread_mutex_init, + &_pthread_mutex_lock, + &_pthread_mutex_trylock, + &_pthread_mutex_unlock, + &_pthread_mutexattr_init, + &_pthread_mutexattr_destroy, + &_pthread_mutexattr_settype, + &_pthread_once, + &_pthread_setspecific, + &_read, + &_readv, + &_recvfrom, + &_recvmsg, + &_select, + &_sendmsg, + &_sendto, + &_setsockopt, + &_sigaction, + &_sigprocmask, + &_sigsuspend, + &_socket, + &_socketpair, + &_wait4, + &_write, + &_writev +}; + +/* * These are needed when linking statically. All references within * libgcc (and in the future libc) to these routines are weak, but * if they are not (strongly) referenced by the application or other * libraries, then the actual functions will not be loaded. */ -static void *thread_references[] = { - &pthread_once, - &pthread_key_create, - &pthread_key_delete, - &pthread_getspecific, - &pthread_setspecific, - &pthread_mutex_init, - &pthread_mutex_destroy, - &pthread_mutex_lock, - &pthread_mutex_trylock, - &pthread_mutex_unlock, - &pthread_cond_init, - &pthread_cond_destroy, - &pthread_cond_wait, - &pthread_cond_timedwait, - &pthread_cond_signal, - &pthread_cond_broadcast +static void *libgcc_references[] = { + &_pthread_once, + &_pthread_key_create, + &_pthread_key_delete, + &_pthread_getspecific, + &_pthread_setspecific, + &_pthread_mutex_init, + &_pthread_mutex_destroy, + &_pthread_mutex_lock, + &_pthread_mutex_trylock, + &_pthread_mutex_unlock }; -#ifdef GCC_2_8_MADE_THREAD_AWARE -typedef void *** (*dynamic_handler_allocator)(); -extern void __set_dynamic_handler_allocator(dynamic_handler_allocator); - -static pthread_key_t except_head_key; - -typedef struct { - void **__dynamic_handler_chain; - void *top_elt[2]; -} except_struct; - -static void ***dynamic_allocator_handler_fn() -{ - except_struct *dh = (except_struct *)pthread_getspecific(except_head_key); - - if(dh == NULL) { - dh = (except_struct *)malloc( sizeof(except_struct) ); - memset(dh, '\0', sizeof(except_struct)); - dh->__dynamic_handler_chain= dh->top_elt; - pthread_setspecific(except_head_key, (void *)dh); - } - return &dh->__dynamic_handler_chain; -} -#endif /* GCC_2_8_MADE_THREAD_AWARE */ /* * Threaded process initialization @@ -124,11 +167,11 @@ _thread_init(void) return; /* - * Make gcc quiescent about thread_references not being + * Make gcc quiescent about {,libgcc_}references not being * referenced: */ - if (thread_references[0] == NULL) - PANIC("Mandatory pthread_* functions not loaded"); + if ((references[0] == NULL) || (libgcc_references[0] == NULL)) + PANIC("Failed loading mandatory references in _thread_init"); /* * Check for the special case of this process running as @@ -143,22 +186,22 @@ _thread_init(void) PANIC("Can't set session ID"); if (revoke(_PATH_CONSOLE) != 0) PANIC("Can't revoke console"); - if ((fd = _thread_sys_open(_PATH_CONSOLE, O_RDWR)) < 0) + if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0) PANIC("Can't open console"); if (setlogin("root") == -1) PANIC("Can't set login to root"); - if (_thread_sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1) + if (__sys_ioctl(fd,TIOCSCTTY, (char *) NULL) == -1) PANIC("Can't set controlling terminal"); - if (_thread_sys_dup2(fd,0) == -1 || - _thread_sys_dup2(fd,1) == -1 || - _thread_sys_dup2(fd,2) == -1) + if (__sys_dup2(fd,0) == -1 || + __sys_dup2(fd,1) == -1 || + __sys_dup2(fd,2) == -1) PANIC("Can't dup2"); } /* Get the standard I/O flags before messing with them : */ for (i = 0; i < 3; i++) if (((_pthread_stdio_flags[i] = - _thread_sys_fcntl(i,F_GETFL, NULL)) == -1) && + __sys_fcntl(i,F_GETFL, NULL)) == -1) && (errno != EBADF)) PANIC("Cannot get stdio flags"); @@ -166,27 +209,27 @@ _thread_init(void) * Create a pipe that is written to by the signal handler to prevent * signals being missed in calls to _select: */ - if (_thread_sys_pipe(_thread_kern_pipe) != 0) { + if (__sys_pipe(_thread_kern_pipe) != 0) { /* Cannot create pipe, so abort: */ PANIC("Cannot create kernel pipe"); } /* Get the flags for the read pipe: */ - else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) { + else if ((flags = __sys_fcntl(_thread_kern_pipe[0], F_GETFL, NULL)) == -1) { /* Abort this application: */ PANIC("Cannot get kernel read pipe flags"); } /* Make the read pipe non-blocking: */ - else if (_thread_sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) { + else if (__sys_fcntl(_thread_kern_pipe[0], F_SETFL, flags | O_NONBLOCK) == -1) { /* Abort this application: */ PANIC("Cannot make kernel read pipe non-blocking"); } /* Get the flags for the write pipe: */ - else if ((flags = _thread_sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) { + else if ((flags = __sys_fcntl(_thread_kern_pipe[1], F_GETFL, NULL)) == -1) { /* Abort this application: */ PANIC("Cannot get kernel write pipe flags"); } /* Make the write pipe non-blocking: */ - else if (_thread_sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) { + else if (__sys_fcntl(_thread_kern_pipe[1], F_SETFL, flags | O_NONBLOCK) == -1) { /* Abort this application: */ PANIC("Cannot get kernel write pipe flags"); } @@ -270,6 +313,9 @@ _thread_init(void) /* Initialise the state of the initial thread: */ _thread_initial->state = PS_RUNNING; + /* Set the name of the thread: */ + _thread_initial->name = strdup("_thread_initial"); + /* Initialise the queue: */ TAILQ_INIT(&(_thread_initial->join_queue)); @@ -299,7 +345,7 @@ _thread_init(void) _thread_initial->error = 0; TAILQ_INIT(&_thread_list); TAILQ_INSERT_HEAD(&_thread_list, _thread_initial, tle); - _thread_run = _thread_initial; + _set_curthread(_thread_initial); /* Initialise the global signal action structure: */ sigfillset(&act.sa_mask); @@ -320,7 +366,7 @@ _thread_init(void) _thread_sigstack.ss_size = SIGSTKSZ; _thread_sigstack.ss_flags = 0; if ((_thread_sigstack.ss_sp == NULL) || - (_thread_sys_sigaltstack(&_thread_sigstack, NULL) != 0)) + (__sys_sigaltstack(&_thread_sigstack, NULL) != 0)) PANIC("Unable to install alternate signal stack"); /* Enter a loop to get the existing signal status: */ @@ -330,7 +376,7 @@ _thread_init(void) } /* Get the signal handler details: */ - else if (_thread_sys_sigaction(i, NULL, + else if (__sys_sigaction(i, NULL, &_thread_sigact[i - 1]) != 0) { /* * Abort this process if signal @@ -348,9 +394,9 @@ _thread_init(void) * signals that the user-thread kernel needs. Actually * SIGINFO isn't really needed, but it is nice to have. */ - if (_thread_sys_sigaction(_SCHED_SIGNAL, &act, NULL) != 0 || - _thread_sys_sigaction(SIGINFO, &act, NULL) != 0 || - _thread_sys_sigaction(SIGCHLD, &act, NULL) != 0) { + if (__sys_sigaction(_SCHED_SIGNAL, &act, NULL) != 0 || + __sys_sigaction(SIGINFO, &act, NULL) != 0 || + __sys_sigaction(SIGCHLD, &act, NULL) != 0) { /* * Abort this process if signal initialisation fails: */ @@ -361,7 +407,7 @@ _thread_init(void) _thread_sigact[SIGCHLD - 1].sa_flags = SA_SIGINFO; /* Get the process signal mask: */ - _thread_sys_sigprocmask(SIG_SETMASK, NULL, &_process_sigmask); + __sys_sigprocmask(SIG_SETMASK, NULL, &_process_sigmask); /* Get the kernel clockrate: */ mib[0] = CTL_KERN; @@ -416,17 +462,8 @@ _thread_init(void) } } -#ifdef GCC_2_8_MADE_THREAD_AWARE - /* Create the thread-specific data for the exception linked list. */ - if(pthread_key_create(&except_head_key, NULL) != 0) - PANIC("Failed to create thread specific execption head"); - - /* Setup the gcc exception handler per thread. */ - __set_dynamic_handler_allocator( dynamic_allocator_handler_fn ); -#endif /* GCC_2_8_MADE_THREAD_AWARE */ - /* Initialise the garbage collector mutex and condition variable. */ - if (pthread_mutex_init(&_gc_mutex,NULL) != 0 || + if (_pthread_mutex_init(&_gc_mutex,NULL) != 0 || pthread_cond_init(&_gc_cond,NULL) != 0) PANIC("Failed to initialise garbage collector mutex or condvar"); } @@ -445,12 +482,3 @@ _thread_main(int argc, char *argv[], char *env) return (main(argc, argv, env)); } #endif -#else -/* - * A stub for non-threaded programs. - */ -void -_thread_init(void) -{ -} -#endif |