summaryrefslogtreecommitdiffstats
path: root/lib/libc_r/uthread/uthread_init.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libc_r/uthread/uthread_init.c')
-rw-r--r--lib/libc_r/uthread/uthread_init.c80
1 files changed, 68 insertions, 12 deletions
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index fd4aef4..d1d116e 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -58,6 +58,7 @@
#include <paths.h>
#include <poll.h>
#include <pthread.h>
+#include <pthread_np.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
@@ -65,11 +66,16 @@
#include <unistd.h>
#include "un-namespace.h"
+#include "libc_private.h"
#include "pthread_private.h"
+int __pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
+int __pthread_mutex_lock(pthread_mutex_t *);
+int __pthread_mutex_trylock(pthread_mutex_t *);
+
/*
* All weak references used within libc should be in this table.
- * This will is so that static libraries will work.
+ * This allows static libraries to work.
*/
static void *references[] = {
&_accept,
@@ -96,6 +102,10 @@ static void *references[] = {
&_listen,
&_nanosleep,
&_open,
+ &_pthread_cond_destroy,
+ &_pthread_cond_init,
+ &_pthread_cond_signal,
+ &_pthread_cond_wait,
&_pthread_getspecific,
&_pthread_key_create,
&_pthread_key_delete,
@@ -129,9 +139,9 @@ static void *references[] = {
/*
* 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.
+ * libgcc (and 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 *libgcc_references[] = {
&_pthread_once,
@@ -146,6 +156,43 @@ static void *libgcc_references[] = {
&_pthread_mutex_unlock
};
+#define DUAL_ENTRY(entry) \
+ (pthread_func_t)entry, (pthread_func_t)entry
+
+static pthread_func_t jmp_table[][2] = {
+ {DUAL_ENTRY(_pthread_cond_broadcast)}, /* PJT_COND_BROADCAST */
+ {DUAL_ENTRY(_pthread_cond_destroy)}, /* PJT_COND_DESTROY */
+ {DUAL_ENTRY(_pthread_cond_init)}, /* PJT_COND_INIT */
+ {DUAL_ENTRY(_pthread_cond_signal)}, /* PJT_COND_SIGNAL */
+ {(pthread_func_t)__pthread_cond_wait,
+ (pthread_func_t)_pthread_cond_wait}, /* PJT_COND_WAIT */
+ {DUAL_ENTRY(_pthread_getspecific)}, /* PJT_GETSPECIFIC */
+ {DUAL_ENTRY(_pthread_key_create)}, /* PJT_KEY_CREATE */
+ {DUAL_ENTRY(_pthread_key_delete)}, /* PJT_KEY_DELETE*/
+ {DUAL_ENTRY(_pthread_main_np)}, /* PJT_MAIN_NP */
+ {DUAL_ENTRY(_pthread_mutex_destroy)}, /* PJT_MUTEX_DESTROY */
+ {DUAL_ENTRY(_pthread_mutex_init)}, /* PJT_MUTEX_INIT */
+ {(pthread_func_t)__pthread_mutex_lock,
+ (pthread_func_t)_pthread_mutex_lock}, /* PJT_MUTEX_LOCK */
+ {(pthread_func_t)__pthread_mutex_trylock,
+ (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */
+ {DUAL_ENTRY(_pthread_mutex_unlock)}, /* PJT_MUTEX_UNLOCK */
+ {DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */
+ {DUAL_ENTRY(_pthread_mutexattr_init)}, /* PJT_MUTEXATTR_INIT */
+ {DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */
+ {DUAL_ENTRY(_pthread_once)}, /* PJT_ONCE */
+ {DUAL_ENTRY(_pthread_rwlock_destroy)}, /* PJT_RWLOCK_DESTROY */
+ {DUAL_ENTRY(_pthread_rwlock_init)}, /* PJT_RWLOCK_INIT */
+ {DUAL_ENTRY(_pthread_rwlock_rdlock)}, /* PJT_RWLOCK_RDLOCK */
+ {DUAL_ENTRY(_pthread_rwlock_tryrdlock)},/* PJT_RWLOCK_TRYRDLOCK */
+ {DUAL_ENTRY(_pthread_rwlock_trywrlock)},/* PJT_RWLOCK_TRYWRLOCK */
+ {DUAL_ENTRY(_pthread_rwlock_unlock)}, /* PJT_RWLOCK_UNLOCK */
+ {DUAL_ENTRY(_pthread_rwlock_wrlock)}, /* PJT_RWLOCK_WRLOCK */
+ {DUAL_ENTRY(_pthread_self)}, /* PJT_SELF */
+ {DUAL_ENTRY(_pthread_setspecific)}, /* PJT_SETSPECIFIC */
+ {DUAL_ENTRY(_pthread_sigmask)} /* PJT_SIGMASK */
+};
+
int _pthread_guard_default;
int _pthread_page_size;
@@ -165,18 +212,18 @@ _thread_init(void)
struct clockinfo clockinfo;
struct sigaction act;
- _pthread_page_size = getpagesize();
- _pthread_guard_default = getpagesize();
- sched_stack_size = getpagesize();
-
- pthread_attr_default.guardsize_attr = _pthread_guard_default;
-
/* Check if this function has already been called: */
if (_thread_initial)
/* Only initialise the threaded application once. */
return;
+ _pthread_page_size = getpagesize();;
+ _pthread_guard_default = _pthread_page_size;
+ sched_stack_size = _pthread_page_size;
+
+ _pthread_attr_default.guardsize_attr = _pthread_guard_default;
+
/*
* Make gcc quiescent about {,libgcc_}references not being
* referenced:
@@ -185,6 +232,14 @@ _thread_init(void)
PANIC("Failed loading mandatory references in _thread_init");
/*
+ * Check the size of the jump table to make sure it is preset
+ * with the correct number of entries.
+ */
+ if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2))
+ PANIC("Thread jump table not properly initialized");
+ memcpy(__thr_jtable, jmp_table, sizeof(jmp_table));
+
+ /*
* Check for the special case of this process running as
* or in place of init as pid = 1:
*/
@@ -288,7 +343,7 @@ _thread_init(void)
_sched_switch_hook = NULL;
/* Give this thread default attributes: */
- memcpy((void *) &_thread_initial->attr, &pthread_attr_default,
+ memcpy((void *) &_thread_initial->attr, &_pthread_attr_default,
sizeof(struct pthread_attr));
/* Find the stack top */
@@ -480,10 +535,11 @@ _thread_init(void)
/* Initialise the garbage collector mutex and condition variable. */
if (_pthread_mutex_init(&_gc_mutex,NULL) != 0 ||
- pthread_cond_init(&_gc_cond,NULL) != 0)
+ _pthread_cond_init(&_gc_cond,NULL) != 0)
PANIC("Failed to initialise garbage collector mutex or condvar");
}
+
/*
* Special start up code for NetBSD/Alpha
*/
OpenPOWER on IntegriCloud