summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Frysinger <vapier@gentoo.org>2006-01-04 03:45:56 +0000
committerMike Frysinger <vapier@gentoo.org>2006-01-04 03:45:56 +0000
commite9264e49f3777c298e8a734cf4483c26b2602584 (patch)
treebc99d793d97a1d73bc55a256f6983c5d26fcc925
parentcd662e64be1b10615e2fb44d5f3dc97eca905a31 (diff)
update pthread weak handling to the style glibc uses
-rw-r--r--libc/misc/pthread/Makefile.in10
-rw-r--r--libc/misc/pthread/weaks.c102
-rw-r--r--libpthread/linuxthreads.old/Makefile.in25
-rw-r--r--libpthread/linuxthreads.old/forward.c142
-rw-r--r--libpthread/linuxthreads.old/internals.h14
-rw-r--r--libpthread/linuxthreads.old/libc_pthread_init.c48
-rw-r--r--libpthread/linuxthreads.old/pthread.c65
-rw-r--r--libpthread/linuxthreads.old/specific.c36
-rw-r--r--libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h36
-rw-r--r--libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h95
10 files changed, 432 insertions, 141 deletions
diff --git a/libc/misc/pthread/Makefile.in b/libc/misc/pthread/Makefile.in
index 02bfc25b4..7ce9a84ae 100644
--- a/libc/misc/pthread/Makefile.in
+++ b/libc/misc/pthread/Makefile.in
@@ -5,16 +5,14 @@
# Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
#
-CSRC := no-tsd.c weaks.c
-
MISC_PTHREAD_DIR := $(top_srcdir)libc/misc/pthread
MISC_PTHREAD_OUT := $(top_builddir)libc/misc/pthread
-MISC_PTHREAD_SRC := $(patsubst %.c,$(MISC_PTHREAD_DIR)/%.c,$(CSRC))
-MISC_PTHREAD_OBJ := $(patsubst %.c,$(MISC_PTHREAD_OUT)/%.o,$(CSRC))
+MISC_PTHREAD_CSRC := no-tsd.c
+MISC_PTHREAD_STATIC_CSRC := weaks.c
-libc-a-$(UCLIBC_HAS_THREADS)+=$(MISC_PTHREAD_OBJ)
-libc-so-$(UCLIBC_HAS_THREADS)+=$(MISC_PTHREAD_OBJ:.o=.os)
+libc-static-$(UCLIBC_HAS_THREADS) += $(patsubst %.c,$(MISC_PTHREAD_OUT)/%.o,$(MISC_PTHREAD_STATIC_CSRC))
+libc-shared-$(UCLIBC_HAS_THREADS) += $(patsubst %.c,$(MISC_PTHREAD_OUT)/%.oS,$(MISC_PTHREAD_CSRC))
objclean-y += misc_pthread_objclean
diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c
index 4b9e02672..20a98a3fe 100644
--- a/libc/misc/pthread/weaks.c
+++ b/libc/misc/pthread/weaks.c
@@ -18,109 +18,21 @@
Boston, MA 02111-1307, USA. */
#define _GNU_SOURCE
-#include <errno.h>
-#include <limits.h>
-#include <stdlib.h>
+#include <libc-internal.h>
-/**********************************************************************/
-/* Weaks for application/library use.
+/* Weaks for internal library use only.
*
* We need to define weaks here to cover all the pthread functions that
- * libc itself will use so that we aren't forced to link libc.so to
- * libpthread.so. When an application doesn't use pthreads support,
- * the locking functions used by libc itself basically become no-ops.
- * However, if the application uses pthreads, then it will pull in
- * libpthread.so whose symbols will override these weaks magically
- * turning the internal libc mutex calls from no-ops to real locking
- * calls.
+ * libc itself will use so that we aren't forced to link libc against
+ * libpthread. This file is only used in libc.a and since we have
+ * weaks here, they will be automatically overridden by libpthread.a
+ * if it gets linked in.
*/
-/* glibc itself defines all these, but we don't need them in uClibc
- *
- * Verified by comparing to glibc's linuxthreads/forward.c and defined
- * only those that are in the glibc abi.
- * The commented aliases are ones that were previously defined in uClibc
- * and which I left in for documentation.
- */
-
-static int __pthread_return_0 __P ((void));
+static int __pthread_return_0 (void);
static int __pthread_return_0 (void) { return 0; }
-/*
-weak_alias (__pthread_return_0, pthread_attr_destroy)
-weak_alias (__pthread_return_0, pthread_attr_getdetachstate)
-weak_alias (__pthread_return_0, pthread_attr_getinheritsched)
-weak_alias (__pthread_return_0, pthread_attr_getschedparam)
-weak_alias (__pthread_return_0, pthread_attr_getschedpolicy)
-weak_alias (__pthread_return_0, pthread_attr_getscope)
-weak_alias (__pthread_return_0, pthread_attr_getstackaddr)
-weak_alias (__pthread_return_0, pthread_attr_getstacksize)
-weak_alias (__pthread_return_0, pthread_attr_init)
-weak_alias (__pthread_return_0, pthread_attr_setdetachstate)
-weak_alias (__pthread_return_0, pthread_attr_setinheritsched)
-weak_alias (__pthread_return_0, pthread_attr_setschedparam)
-weak_alias (__pthread_return_0, pthread_attr_setschedpolicy)
-weak_alias (__pthread_return_0, pthread_attr_setscope)
-weak_alias (__pthread_return_0, pthread_attr_setstackaddr)
-weak_alias (__pthread_return_0, pthread_attr_setstacksize)
-weak_alias (__pthread_return_0, pthread_cond_broadcast)
-weak_alias (__pthread_return_0, pthread_cond_destroy)
-weak_alias (__pthread_return_0, pthread_cond_init)
-weak_alias (__pthread_return_0, pthread_cond_signal)
-weak_alias (__pthread_return_0, pthread_cond_timedwait)
-weak_alias (__pthread_return_0, pthread_cond_wait)
-weak_alias (__pthread_return_0, pthread_condattr_destroy)
-weak_alias (__pthread_return_0, pthread_condattr_init)
-weak_alias (__pthread_return_0, pthread_getschedparam)
-weak_alias (__pthread_return_0, pthread_getcancelstate)
-weak_alias (__pthread_return_0, pthread_getconcurrency)
-weak_alias (__pthread_return_0, pthread_mutex_destroy)
-weak_alias (__pthread_return_0, pthread_mutex_init)
-weak_alias (__pthread_return_0, pthread_mutex_lock)
-weak_alias (__pthread_return_0, pthread_mutex_trylock)
-weak_alias (__pthread_return_0, pthread_mutex_unlock)
-weak_alias (__pthread_return_0, pthread_mutexattr_destroy)
-weak_alias (__pthread_return_0, pthread_mutexattr_gettype)
-weak_alias (__pthread_return_0, pthread_mutexattr_init)
-weak_alias (__pthread_return_0, pthread_mutexattr_settype)
-weak_alias (__pthread_return_0, pthread_rwlock_destroy)
-weak_alias (__pthread_return_0, pthread_rwlock_init)
-weak_alias (__pthread_return_0, pthread_rwlock_rdlock)
-weak_alias (__pthread_return_0, pthread_rwlock_tryrdlock)
-weak_alias (__pthread_return_0, pthread_rwlock_trywrlock)
-weak_alias (__pthread_return_0, pthread_rwlock_unlock)
-weak_alias (__pthread_return_0, pthread_rwlock_wrlock)
-weak_alias (__pthread_return_0, pthread_rwlockattr_destroy)
-weak_alias (__pthread_return_0, pthread_rwlockattr_getpshared)
-weak_alias (__pthread_return_0, pthread_rwlockattr_init)
-weak_alias (__pthread_return_0, pthread_rwlockattr_setpshared)
-weak_alias (__pthread_return_0, pthread_self)
-weak_alias (__pthread_return_0, pthread_setcancelstate)
-weak_alias (__pthread_return_0, pthread_setcanceltype)
-weak_alias (__pthread_return_0, pthread_setconcurrency)
-weak_alias (__pthread_return_0, pthread_setschedparam)
-
-static int __pthread_return_1 __P ((void));
-static int __pthread_return_1 (void) { return 1; }
-
-weak_alias (__pthread_return_1, pthread_equal)
-
-void weak_function pthread_exit (void *retval)
-{
- __exit (EXIT_SUCCESS);
-}
-*/
-
-/**********************************************************************/
-/* Weaks used internally by the C library. */
weak_alias (__pthread_return_0, __pthread_mutex_init)
weak_alias (__pthread_return_0, __pthread_mutex_lock)
weak_alias (__pthread_return_0, __pthread_mutex_trylock)
weak_alias (__pthread_return_0, __pthread_mutex_unlock)
-#ifdef __UCLIBC_HAS_THREADS_NATIVE__
-weak_alias (__pthread_return_0, pthread_mutexattr_init)
-weak_alias (__pthread_return_0, pthread_mutexattr_settype)
-weak_alias (__pthread_return_0, pthread_mutexattr_destroy)
-#endif
-
-/**********************************************************************/
diff --git a/libpthread/linuxthreads.old/Makefile.in b/libpthread/linuxthreads.old/Makefile.in
index 585f8b50d..47a4f8d98 100644
--- a/libpthread/linuxthreads.old/Makefile.in
+++ b/libpthread/linuxthreads.old/Makefile.in
@@ -35,17 +35,18 @@ libpthread_OUT := $(top_builddir)libpthread/linuxthreads.old
libpthread_SRC := \
attr.c cancel.c condvar.c errno.c events.c join.c lockfile.c manager.c \
- mutex.c oldsemaphore.c pt-machine.c ptfork.c pthread.c ptlongjmp.c \
+ mutex.c oldsemaphore.c pt-machine.c ptfork.c ptlongjmp.c \
rwlock.c semaphore.c signals.c specific.c spinlock.c wrapsyscall.c
ifeq ($(UCLIBC_HAS_XLOCALE),y)
libpthread_SRC += locale.c
endif
-
ifneq ($(DOMULTI),n)
libpthread_NO_MULTI := manager.c pt-machine.c
libpthread_SRC := $(filter-out $(libpthread_NO_MULTI),$(libpthread_SRC))
endif
+libpthread_SPEC_SRC := pthread.c
+
# remove generic sources, if arch specific version is present
ifneq ($(strip $(libpthread_ARCH_SRC)),)
libpthread_SRC := $(filter-out $(patsubst %.c,$(libpthread_DIR)/%.c,$(notdir $(libpthread_ARCH_SRC))),$(libpthread_SRC))
@@ -55,12 +56,24 @@ libpthread_SRC := $(patsubst %,$(libpthread_DIR)/%,$(libpthread_SRC))
libpthread_OBJ := $(patsubst $(libpthread_DIR)/%.c,$(libpthread_OUT)/%.o,$(libpthread_SRC))
+#
+# Stuff that goes into libc.so, not libpthread.so
+#
+CFLAGS-forward.c := -DIS_IN_libc
+CFLAGS-libc_pthread_init.c := -DIS_IN_libc
+libpthread_libc_CSRC := forward.c libc_pthread_init.c
+libpthread_libc_OBJ := $(patsubst %.c, $(libpthread_OUT)/%.o,$(libpthread_libc_CSRC))
+libc-shared-y += $(libpthread_libc_OBJ:.o=.oS)
+
+libpthread-static-y += $(patsubst %.c,$(libpthread_OUT)/%.o,$(libpthread_SPEC_SRC))
+libpthread-shared-y += $(patsubst %.c,$(libpthread_OUT)/%.oS,$(libpthread_SPEC_SRC))
+
ifeq ($(DOPIC),y)
-libpthread-a-y += $(libpthread_OBJ:.o=.os)
+libpthread-a-y += $(libpthread_OBJ:.o=.os) $(libpthread-static-y:.o=.os)
else
-libpthread-a-y += $(libpthread_OBJ)
+libpthread-a-y += $(libpthread_OBJ) $(libpthread-static-y)
endif
-libpthread-so-y += $(libpthread_OBJ:.o=.os)
+libpthread-so-y += $(libpthread_OBJ:.o=.os) $(libpthread-shared-y)
libpthread-multi-y += $(libpthread_SRC)
libpthread-nomulti-y += $(patsubst %.c,$(libpthread_OUT)/%.o,$(libpthread_NO_MULTI))
@@ -104,4 +117,4 @@ linuxthreads_headers_clean:
$(top_builddir)include/bits/pthreadtypes.h
libpthread_clean:
- $(RM) $(libpthread_OUT)/*.{o,os,a}
+ $(RM) $(libpthread_OUT)/*.{o,os,oS,a}
diff --git a/libpthread/linuxthreads.old/forward.c b/libpthread/linuxthreads.old/forward.c
new file mode 100644
index 000000000..b5547a983
--- /dev/null
+++ b/libpthread/linuxthreads.old/forward.c
@@ -0,0 +1,142 @@
+/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <dlfcn.h>
+#include "internals.h"
+#include <stdlib.h>
+
+#include <libc-internal.h>
+
+
+/* Pointers to the libc functions. */
+struct pthread_functions __libc_pthread_functions attribute_hidden;
+
+
+# define FORWARD2(name, rettype, decl, params, defaction) \
+rettype \
+name decl \
+{ \
+ if (__libc_pthread_functions.ptr_##name == NULL) \
+ defaction; \
+ \
+ return __libc_pthread_functions.ptr_##name params; \
+}
+
+# define FORWARD(name, decl, params, defretval) \
+ FORWARD2 (name, int, decl, params, return defretval)
+
+FORWARD (pthread_attr_destroy, (pthread_attr_t *attr), (attr), 0)
+
+FORWARD (pthread_attr_init, (pthread_attr_t *attr), (attr), 0)
+
+FORWARD (pthread_attr_getdetachstate,
+ (const pthread_attr_t *attr, int *detachstate), (attr, detachstate),
+ 0)
+FORWARD (pthread_attr_setdetachstate, (pthread_attr_t *attr, int detachstate),
+ (attr, detachstate), 0)
+
+FORWARD (pthread_attr_getinheritsched,
+ (const pthread_attr_t *attr, int *inherit), (attr, inherit), 0)
+FORWARD (pthread_attr_setinheritsched, (pthread_attr_t *attr, int inherit),
+ (attr, inherit), 0)
+
+FORWARD (pthread_attr_getschedparam,
+ (const pthread_attr_t *attr, struct sched_param *param),
+ (attr, param), 0)
+FORWARD (pthread_attr_setschedparam,
+ (pthread_attr_t *attr, const struct sched_param *param),
+ (attr, param), 0)
+
+FORWARD (pthread_attr_getschedpolicy,
+ (const pthread_attr_t *attr, int *policy), (attr, policy), 0)
+FORWARD (pthread_attr_setschedpolicy, (pthread_attr_t *attr, int policy),
+ (attr, policy), 0)
+
+FORWARD (pthread_attr_getscope,
+ (const pthread_attr_t *attr, int *scope), (attr, scope), 0)
+FORWARD (pthread_attr_setscope, (pthread_attr_t *attr, int scope),
+ (attr, scope), 0)
+
+
+FORWARD (pthread_condattr_destroy, (pthread_condattr_t *attr), (attr), 0)
+FORWARD (pthread_condattr_init, (pthread_condattr_t *attr), (attr), 0)
+
+
+FORWARD (pthread_cond_broadcast, (pthread_cond_t *cond), (cond), 0)
+
+FORWARD (pthread_cond_destroy, (pthread_cond_t *cond), (cond), 0)
+
+FORWARD (pthread_cond_init,
+ (pthread_cond_t *cond, const pthread_condattr_t *cond_attr),
+ (cond, cond_attr), 0)
+
+FORWARD (pthread_cond_signal, (pthread_cond_t *cond), (cond), 0)
+
+FORWARD (pthread_cond_wait, (pthread_cond_t *cond, pthread_mutex_t *mutex),
+ (cond, mutex), 0)
+
+FORWARD (pthread_cond_timedwait,
+ (pthread_cond_t *cond, pthread_mutex_t *mutex,
+ const struct timespec *abstime), (cond, mutex, abstime), 0)
+
+
+FORWARD (pthread_equal, (pthread_t thread1, pthread_t thread2),
+ (thread1, thread2), 1)
+
+
+/* Use an alias to avoid warning, as pthread_exit is declared noreturn. */
+FORWARD2 (__pthread_exit, void, (void *retval), (retval), exit (EXIT_SUCCESS))
+strong_alias (__pthread_exit, pthread_exit);
+
+
+FORWARD (pthread_getschedparam,
+ (pthread_t target_thread, int *policy, struct sched_param *param),
+ (target_thread, policy, param), 0)
+FORWARD (pthread_setschedparam,
+ (pthread_t target_thread, int policy,
+ const struct sched_param *param), (target_thread, policy, param), 0)
+
+
+FORWARD (pthread_mutex_destroy, (pthread_mutex_t *mutex), (mutex), 0)
+
+FORWARD (pthread_mutex_init,
+ (pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr),
+ (mutex, mutexattr), 0)
+hidden_strong_alias(pthread_mutex_init, __pthread_mutex_init)
+
+FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0)
+hidden_strong_alias(pthread_mutex_lock, __pthread_mutex_lock)
+
+FORWARD (pthread_mutex_trylock, (pthread_mutex_t *mutex), (mutex), 0)
+hidden_strong_alias(pthread_mutex_trylock, __pthread_mutex_trylock)
+
+FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0)
+hidden_strong_alias(pthread_mutex_unlock, __pthread_mutex_unlock)
+
+FORWARD2 (pthread_self, pthread_t, (void), (), return 0)
+
+
+FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate),
+ 0)
+
+FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0)
+
+FORWARD2 (_pthread_cleanup_push, void, (struct _pthread_cleanup_buffer * buffer, void (*routine)(void *), void * arg), (buffer, routine, arg), return)
+
+FORWARD2 (_pthread_cleanup_pop, void, (struct _pthread_cleanup_buffer * buffer, int execute), (buffer, execute), return)
diff --git a/libpthread/linuxthreads.old/internals.h b/libpthread/linuxthreads.old/internals.h
index 4b3396aee..8422db58f 100644
--- a/libpthread/linuxthreads.old/internals.h
+++ b/libpthread/linuxthreads.old/internals.h
@@ -440,6 +440,10 @@ static inline pthread_descr thread_self (void)
#define SPIN_SLEEP_DURATION 2000001
#endif
+/* Defined and used in libc.so. */
+extern int __libc_multiple_threads attribute_hidden;
+extern int __librt_multiple_threads;
+
/* Debugging */
#ifdef DEBUG
@@ -510,9 +514,19 @@ extern ssize_t __libc_write (int fd, const void *buf, size_t count);
/* Prototypes for some of the new semaphore functions. */
extern int __new_sem_post (sem_t * sem);
+/* TSD. */
+extern int __pthread_internal_tsd_set (int key, const void * pointer);
+extern void * __pthread_internal_tsd_get (int key);
+extern void ** __attribute__ ((__const__))
+ __pthread_internal_tsd_address (int key);
+
/* The functions called the signal events. */
extern void __linuxthreads_create_event (void);
extern void __linuxthreads_death_event (void);
extern void __linuxthreads_reap_event (void);
+#include <pthread-functions.h>
+
+extern int * __libc_pthread_init (const struct pthread_functions *functions);
+
#endif /* internals.h */
diff --git a/libpthread/linuxthreads.old/libc_pthread_init.c b/libpthread/linuxthreads.old/libc_pthread_init.c
new file mode 100644
index 000000000..67b38745d
--- /dev/null
+++ b/libpthread/linuxthreads.old/libc_pthread_init.c
@@ -0,0 +1,48 @@
+/* Copyright (C) 2002 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#include <features.h>
+#include <locale.h>
+#include <stdlib.h>
+#include <string.h>
+#include "internals.h"
+#include "sysdeps/pthread/pthread-functions.h"
+
+int __libc_multiple_threads attribute_hidden __attribute__((nocommon));
+
+int *
+__libc_pthread_init (functions)
+ const struct pthread_functions *functions;
+{
+#ifdef SHARED
+ /* We copy the content of the variable pointed to by the FUNCTIONS
+ parameter to one in libc.so since this means access to the array
+ can be done with one memory access instead of two. */
+ memcpy (&__libc_pthread_functions, functions,
+ sizeof (__libc_pthread_functions));
+#endif
+
+#if !(USE_TLS && HAVE___THREAD) && defined __UCLIBC_HAS_XLOCALE__
+ /* Initialize thread-locale current locale to point to the global one.
+ With __thread support, the variable's initializer takes care of this. */
+ __uselocale (LC_GLOBAL_LOCALE);
+#endif
+
+ return &__libc_multiple_threads;
+}
diff --git a/libpthread/linuxthreads.old/pthread.c b/libpthread/linuxthreads.old/pthread.c
index a5ac1e24a..d7411f04b 100644
--- a/libpthread/linuxthreads.old/pthread.c
+++ b/libpthread/linuxthreads.old/pthread.c
@@ -286,6 +286,67 @@ int __libc_allocate_rtsig (int high)
static void pthread_initialize(void) __attribute__((constructor));
+struct pthread_functions __pthread_functions =
+ {
+#if !(USE_TLS && HAVE___THREAD)
+ .ptr_pthread_internal_tsd_set = __pthread_internal_tsd_set,
+ .ptr_pthread_internal_tsd_get = __pthread_internal_tsd_get,
+ .ptr_pthread_internal_tsd_address = __pthread_internal_tsd_address,
+#endif
+/*
+ .ptr_pthread_fork = __pthread_fork,
+*/
+ .ptr_pthread_attr_destroy = pthread_attr_destroy,
+ .ptr_pthread_attr_init = pthread_attr_init,
+ .ptr_pthread_attr_getdetachstate = pthread_attr_getdetachstate,
+ .ptr_pthread_attr_setdetachstate = pthread_attr_setdetachstate,
+ .ptr_pthread_attr_getinheritsched = pthread_attr_getinheritsched,
+ .ptr_pthread_attr_setinheritsched = pthread_attr_setinheritsched,
+ .ptr_pthread_attr_getschedparam = pthread_attr_getschedparam,
+ .ptr_pthread_attr_setschedparam = pthread_attr_setschedparam,
+ .ptr_pthread_attr_getschedpolicy = pthread_attr_getschedpolicy,
+ .ptr_pthread_attr_setschedpolicy = pthread_attr_setschedpolicy,
+ .ptr_pthread_attr_getscope = pthread_attr_getscope,
+ .ptr_pthread_attr_setscope = pthread_attr_setscope,
+ .ptr_pthread_condattr_destroy = pthread_condattr_destroy,
+ .ptr_pthread_condattr_init = pthread_condattr_init,
+ .ptr_pthread_cond_broadcast = pthread_cond_broadcast,
+ .ptr_pthread_cond_destroy = pthread_cond_destroy,
+ .ptr_pthread_cond_init = pthread_cond_init,
+ .ptr_pthread_cond_signal = pthread_cond_signal,
+ .ptr_pthread_cond_wait = pthread_cond_wait,
+ .ptr_pthread_cond_timedwait = pthread_cond_timedwait,
+ .ptr_pthread_equal = pthread_equal,
+ .ptr___pthread_exit = pthread_exit,
+ .ptr_pthread_getschedparam = pthread_getschedparam,
+ .ptr_pthread_setschedparam = pthread_setschedparam,
+ .ptr_pthread_mutex_destroy = pthread_mutex_destroy,
+ .ptr_pthread_mutex_init = pthread_mutex_init,
+ .ptr_pthread_mutex_lock = pthread_mutex_lock,
+ .ptr_pthread_mutex_trylock = pthread_mutex_trylock,
+ .ptr_pthread_mutex_unlock = pthread_mutex_unlock,
+ .ptr_pthread_self = pthread_self,
+ .ptr_pthread_setcancelstate = pthread_setcancelstate,
+ .ptr_pthread_setcanceltype = pthread_setcanceltype,
+/*
+ .ptr_pthread_do_exit = pthread_do_exit,
+ .ptr_pthread_thread_self = pthread_thread_self,
+ .ptr_pthread_cleanup_upto = pthread_cleanup_upto,
+ .ptr_pthread_sigaction = pthread_sigaction,
+ .ptr_pthread_sigwait = pthread_sigwait,
+ .ptr_pthread_raise = pthread_raise,
+ .ptr__pthread_cleanup_push = _pthread_cleanup_push,
+ .ptr__pthread_cleanup_pop = _pthread_cleanup_pop
+*/
+ };
+#ifdef SHARED
+# define ptr_pthread_functions &__pthread_functions
+#else
+# define ptr_pthread_functions NULL
+#endif
+
+static int *__libc_multiple_threads_ptr;
+
/* Do some minimal initialization which has to be done during the
startup of the C library. */
void __pthread_initialize_minimal(void)
@@ -295,6 +356,8 @@ void __pthread_initialize_minimal(void)
#ifdef INIT_THREAD_SELF
INIT_THREAD_SELF(&__pthread_initial_thread, 0);
#endif
+
+ __libc_multiple_threads_ptr = __libc_pthread_init (ptr_pthread_functions);
}
@@ -411,6 +474,8 @@ int __pthread_initialize_manager(void)
int report_events;
struct pthread_request request;
+ *__libc_multiple_threads_ptr = 1;
+
/* If basic initialization not done yet (e.g. we're called from a
constructor run before our constructor), do it now */
if (__pthread_initial_thread_bos == NULL) pthread_initialize();
diff --git a/libpthread/linuxthreads.old/specific.c b/libpthread/linuxthreads.old/specific.c
index 42be6043c..509ee6665 100644
--- a/libpthread/linuxthreads.old/specific.c
+++ b/libpthread/linuxthreads.old/specific.c
@@ -168,36 +168,32 @@ void __pthread_destroy_specifics()
__pthread_unlock(THREAD_GETMEM(self, p_lock));
}
+#if !(USE_TLS && HAVE___THREAD)
/* Thread-specific data for libc. */
-#if !(USE_TLS && HAVE___THREAD)
-static int
-libc_internal_tsd_set(enum __libc_tsd_key_t key, const void * pointer)
+
+int
+__pthread_internal_tsd_set (int key, const void * pointer)
{
- pthread_descr self = thread_self();
+ pthread_descr self = thread_self();
- THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer);
- return 0;
+ THREAD_SETMEM_NC(self, p_libc_specific[key], (void *) pointer);
+ return 0;
}
-int (*__libc_internal_tsd_set)(enum __libc_tsd_key_t key, const void * pointer)
- = libc_internal_tsd_set;
-static void *
-libc_internal_tsd_get(enum __libc_tsd_key_t key)
+void *
+__pthread_internal_tsd_get (int key)
{
- pthread_descr self = thread_self();
+ pthread_descr self = thread_self();
- return THREAD_GETMEM_NC(self, p_libc_specific[key]);
+ return THREAD_GETMEM_NC(self, p_libc_specific[key]);
}
-void * (*__libc_internal_tsd_get)(enum __libc_tsd_key_t key)
- = libc_internal_tsd_get;
-static void ** __attribute__ ((__const__))
-libc_internal_tsd_address (enum __libc_tsd_key_t key)
+void ** __attribute__ ((__const__))
+__pthread_internal_tsd_address (int key)
{
- pthread_descr self = thread_self();
- return &self->p_libc_specific[key];
+ pthread_descr self = thread_self();
+ return &self->p_libc_specific[key];
}
-void **(*const __libc_internal_tsd_address) (enum __libc_tsd_key_t key)
- __attribute__ ((__const__)) = libc_internal_tsd_address;
+
#endif
diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h b/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h
index 58b986a49..fc8388ab8 100644
--- a/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h
+++ b/libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h
@@ -35,6 +35,8 @@ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
#include <sys/cdefs.h>
#include <tls.h>
+#include <linuxthreads.old/internals.h>
+
#if USE_TLS && HAVE___THREAD
/* When __thread works, the generic definition is what we want. */
@@ -42,25 +44,31 @@ enum __libc_tsd_key_t { _LIBC_TSD_KEY_MALLOC = 0,
#else
-extern void *(*__libc_internal_tsd_get) (enum __libc_tsd_key_t);
-extern int (*__libc_internal_tsd_set) (enum __libc_tsd_key_t, __const void *);
-extern void **(*const __libc_internal_tsd_address) (enum __libc_tsd_key_t)
- __attribute__ ((__const__));
+# ifndef SHARED
+extern void ** __pthread_internal_tsd_address (int);
+extern void *__pthread_internal_tsd_get (int);
+extern int __pthread_internal_tsd_set (int, const void *);
-#define __libc_tsd_address(KEY) \
- (__libc_internal_tsd_address != NULL \
- ? __libc_internal_tsd_address (_LIBC_TSD_KEY_##KEY) \
- : &__libc_tsd_##KEY##_data)
+weak_extern (__pthread_internal_tsd_address)
+weak_extern (__pthread_internal_tsd_get)
+weak_extern (__pthread_internal_tsd_set)
+# endif
+
+#define __libc_maybe_call2(FUNC, ARGS, ELSE) \
+ ({__builtin_expect (__libc_pthread_functions.ptr_##FUNC != NULL, 0) \
+ ? __libc_pthread_functions.ptr_##FUNC ARGS : ELSE; })
#define __libc_tsd_define(CLASS, KEY) CLASS void *__libc_tsd_##KEY##_data;
+#define __libc_tsd_address(KEY) \
+ __libc_maybe_call2 (pthread_internal_tsd_address, \
+ (_LIBC_TSD_KEY_##KEY), &__libc_tsd_##KEY##_data)
#define __libc_tsd_get(KEY) \
- (__libc_internal_tsd_get != NULL \
- ? __libc_internal_tsd_get (_LIBC_TSD_KEY_##KEY) \
- : __libc_tsd_##KEY##_data)
+ __libc_maybe_call2 (pthread_internal_tsd_get, \
+ (_LIBC_TSD_KEY_##KEY), __libc_tsd_##KEY##_data)
#define __libc_tsd_set(KEY, VALUE) \
- (__libc_internal_tsd_set != NULL \
- ? __libc_internal_tsd_set (_LIBC_TSD_KEY_##KEY, (VALUE)) \
- : ((__libc_tsd_##KEY##_data = (VALUE)), 0))
+ __libc_maybe_call2 (pthread_internal_tsd_set, \
+ (_LIBC_TSD_KEY_##KEY, (VALUE)), \
+ (__libc_tsd_##KEY##_data = (VALUE), 0))
#endif
diff --git a/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h b/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h
new file mode 100644
index 000000000..846dc425b
--- /dev/null
+++ b/libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h
@@ -0,0 +1,95 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _PTHREAD_FUNCTIONS_H
+#define _PTHREAD_FUNCTIONS_H 1
+
+#include <pthread.h>
+#include <setjmp.h>
+#include <linuxthreads.old/internals.h>
+
+struct fork_block;
+
+/* Data type shared with libc. The libc uses it to pass on calls to
+ the thread functions. Wine pokes directly into this structure,
+ so if possible avoid breaking it and append new hooks to the end. */
+struct pthread_functions
+{
+ pid_t (*ptr_pthread_fork) (struct fork_block *);
+ int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
+ int (*ptr_pthread_attr_init) (pthread_attr_t *);
+ int (*ptr_pthread_attr_getdetachstate) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setdetachstate) (pthread_attr_t *, int);
+ int (*ptr_pthread_attr_getinheritsched) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setinheritsched) (pthread_attr_t *, int);
+ int (*ptr_pthread_attr_getschedparam) (const pthread_attr_t *,
+ struct sched_param *);
+ int (*ptr_pthread_attr_setschedparam) (pthread_attr_t *,
+ const struct sched_param *);
+ int (*ptr_pthread_attr_getschedpolicy) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setschedpolicy) (pthread_attr_t *, int);
+ int (*ptr_pthread_attr_getscope) (const pthread_attr_t *, int *);
+ int (*ptr_pthread_attr_setscope) (pthread_attr_t *, int);
+ int (*ptr_pthread_condattr_destroy) (pthread_condattr_t *);
+ int (*ptr_pthread_condattr_init) (pthread_condattr_t *);
+ int (*ptr_pthread_cond_broadcast) (pthread_cond_t *);
+ int (*ptr_pthread_cond_destroy) (pthread_cond_t *);
+ int (*ptr_pthread_cond_init) (pthread_cond_t *,
+ const pthread_condattr_t *);
+ int (*ptr_pthread_cond_signal) (pthread_cond_t *);
+ int (*ptr_pthread_cond_wait) (pthread_cond_t *, pthread_mutex_t *);
+ int (*ptr_pthread_equal) (pthread_t, pthread_t);
+ void (*ptr___pthread_exit) (void *);
+ int (*ptr_pthread_getschedparam) (pthread_t, int *, struct sched_param *);
+ int (*ptr_pthread_setschedparam) (pthread_t, int,
+ const struct sched_param *);
+ int (*ptr_pthread_mutex_destroy) (pthread_mutex_t *);
+ int (*ptr_pthread_mutex_init) (pthread_mutex_t *,
+ const pthread_mutexattr_t *);
+ int (*ptr_pthread_mutex_lock) (pthread_mutex_t *);
+ int (*ptr_pthread_mutex_trylock) (pthread_mutex_t *);
+ int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *);
+ pthread_t (*ptr_pthread_self) (void);
+ int (*ptr_pthread_setcancelstate) (int, int *);
+ int (*ptr_pthread_setcanceltype) (int, int *);
+ void (*ptr_pthread_do_exit) (void *retval, char *currentframe);
+ void (*ptr_pthread_cleanup_upto) (__jmp_buf target,
+ char *targetframe);
+ pthread_descr (*ptr_pthread_thread_self) (void);
+ int (*ptr_pthread_internal_tsd_set) (int key, const void *pointer);
+ void * (*ptr_pthread_internal_tsd_get) (int key);
+ void ** __attribute__ ((__const__))
+ (*ptr_pthread_internal_tsd_address) (int key);
+ int (*ptr_pthread_sigaction) (int sig, const struct sigaction * act,
+ struct sigaction *oact);
+ int (*ptr_pthread_sigwait) (const sigset_t *set, int *sig);
+ int (*ptr_pthread_raise) (int sig);
+ int (*ptr_pthread_cond_timedwait) (pthread_cond_t *, pthread_mutex_t *,
+ const struct timespec *);
+ void (*ptr__pthread_cleanup_push) (struct _pthread_cleanup_buffer * buffer,
+ void (*routine)(void *), void * arg);
+
+ void (*ptr__pthread_cleanup_pop) (struct _pthread_cleanup_buffer * buffer,
+ int execute);
+};
+
+/* Variable in libc.so. */
+extern struct pthread_functions __libc_pthread_functions attribute_hidden;
+
+#endif /* pthread-functions.h */