diff options
-rw-r--r-- | libc/misc/pthread/Makefile.in | 10 | ||||
-rw-r--r-- | libc/misc/pthread/weaks.c | 102 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/Makefile.in | 25 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/forward.c | 142 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/internals.h | 14 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/libc_pthread_init.c | 48 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/pthread.c | 65 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/specific.c | 36 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/sysdeps/pthread/bits/libc-tsd.h | 36 | ||||
-rw-r--r-- | libpthread/linuxthreads.old/sysdeps/pthread/pthread-functions.h | 95 |
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 */ |