summaryrefslogtreecommitdiffstats
path: root/lib/libpthread/thread/thr_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libpthread/thread/thr_init.c')
-rw-r--r--lib/libpthread/thread/thr_init.c210
1 files changed, 119 insertions, 91 deletions
diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c
index 93d7849..c92efe3 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
OpenPOWER on IntegriCloud