diff options
-rw-r--r-- | libc/misc/pthread/Makefile.in | 1 | ||||
-rw-r--r-- | libc/misc/pthread/weaks.c | 40 | ||||
-rw-r--r-- | libc/sysdeps/linux/common/bits/uClibc_mutex.h | 17 | ||||
-rw-r--r-- | libpthread/nptl/forward.c | 20 |
4 files changed, 62 insertions, 16 deletions
diff --git a/libc/misc/pthread/Makefile.in b/libc/misc/pthread/Makefile.in index 2f436ac1c..69cdf104a 100644 --- a/libc/misc/pthread/Makefile.in +++ b/libc/misc/pthread/Makefile.in @@ -11,6 +11,7 @@ MISC_PTHREAD_DIR := $(top_srcdir)libc/misc/pthread MISC_PTHREAD_OUT := $(top_builddir)libc/misc/pthread libc-shared-$(UCLIBC_HAS_TLS) += $(MISC_PTHREAD_OUT)/tsd.os +libc-static-$(UCLIBC_HAS_THREADS) += $(MISC_PTHREAD_OUT)/weaks.o objclean-y += CLEAN_libc/misc/pthread diff --git a/libc/misc/pthread/weaks.c b/libc/misc/pthread/weaks.c new file mode 100644 index 000000000..fb1d85fd7 --- /dev/null +++ b/libc/misc/pthread/weaks.c @@ -0,0 +1,40 @@ +/* The weak pthread functions for Linux. + Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <libc-internal.h> + +/* 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 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. + */ + +static int __pthread_return_0 (void) { return 0; } +static void __pthread_return_void (void) { return; } + +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_void, _pthread_cleanup_push_defer) +weak_alias (__pthread_return_void, _pthread_cleanup_pop_restore) + diff --git a/libc/sysdeps/linux/common/bits/uClibc_mutex.h b/libc/sysdeps/linux/common/bits/uClibc_mutex.h index 6d004bb74..3e3d0066a 100644 --- a/libc/sysdeps/linux/common/bits/uClibc_mutex.h +++ b/libc/sysdeps/linux/common/bits/uClibc_mutex.h @@ -15,13 +15,6 @@ #include <pthread.h> #include <bits/uClibc_pthread.h> -#define __uclibc_maybe_call(FUNC, ARGS) \ - (__extension__ ({ \ - __typeof (FUNC) *_fn = (FUNC); \ - if (_fn != NULL) { (*_fn) ARGS; } \ - })) - - #define __UCLIBC_MUTEX_TYPE pthread_mutex_t #define __UCLIBC_MUTEX(M) pthread_mutex_t M @@ -30,21 +23,21 @@ #define __UCLIBC_MUTEX_EXTERN(M) extern pthread_mutex_t M #define __UCLIBC_MUTEX_INIT_VAR(M) \ - __uclibc_maybe_call(__pthread_mutex_init,(&(M),NULL)) + ((M) = (pthread_mutex_t) PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) #define __UCLIBC_MUTEX_LOCK_CANCEL_UNSAFE(M) \ - __uclibc_maybe_call(__pthread_mutex_lock,(&(M))) + __pthread_mutex_lock(&(M)) #define __UCLIBC_MUTEX_UNLOCK_CANCEL_UNSAFE(M) \ - __uclibc_maybe_call(__pthread_mutex_unlock,(&(M))) + __pthread_mutex_unlock(&(M)) #define __UCLIBC_MUTEX_TRYLOCK_CANCEL_UNSAFE(M) \ - __uclibc_maybe_call(__pthread_mutex_trylock,(&(M))) + __pthread_mutex_trylock,(&(M)) #define __UCLIBC_MUTEX_CONDITIONAL_LOCK(M,C) \ do { \ struct _pthread_cleanup_buffer __infunc_pthread_cleanup_buffer; \ - int __infunc_need_locking = ((C) && (__pthread_mutex_lock != NULL)); \ + int __infunc_need_locking = (C); \ if (__infunc_need_locking) { \ _pthread_cleanup_push_defer(&__infunc_pthread_cleanup_buffer, \ (void (*) (void *))__pthread_mutex_unlock, \ diff --git a/libpthread/nptl/forward.c b/libpthread/nptl/forward.c index 8f528d0a8..7878334ac 100644 --- a/libpthread/nptl/forward.c +++ b/libpthread/nptl/forward.c @@ -35,10 +35,11 @@ int __libc_pthread_functions_init attribute_hidden; rettype \ name decl \ { \ - if (!__libc_pthread_functions_init) \ + if (!__libc_pthread_functions_init) { \ defaction; \ - \ - return PTHFCT_CALL (ptr_##name, params); \ + } else { \ + return PTHFCT_CALL (ptr_##name, params); \ + } \ } #define FORWARD(name, decl, params, defretval) \ @@ -130,9 +131,10 @@ FORWARD (pthread_mutex_init, (mutex, mutexattr), 0) FORWARD (pthread_mutex_lock, (pthread_mutex_t *mutex), (mutex), 0) +weak_alias (pthread_mutex_lock, __pthread_mutex_lock) FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0) - +weak_alias (pthread_mutex_unlock, __pthread_mutex_unlock) FORWARD2 (pthread_self, pthread_t, (void), (), return 0) @@ -143,6 +145,16 @@ FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate), FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0) #define return /* value is void */ +FORWARD2(_pthread_cleanup_push_defer, + void, (struct _pthread_cleanup_buffer *buffer, void (*routine)(void *), void *arg), + (buffer, routine, arg), + { buffer->__routine = routine; buffer->__arg = arg; }); + +FORWARD2(_pthread_cleanup_pop_restore, + void, (struct _pthread_cleanup_buffer *buffer, int execute), + (buffer, execute), + if (execute) { buffer->__routine(buffer->__arg); }); + FORWARD2(__pthread_unwind, void attribute_hidden __attribute ((noreturn)) __cleanup_fct_attribute, (__pthread_unwind_buf_t *buf), (buf), { |