summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--libc/misc/pthread/Makefile.in1
-rw-r--r--libc/misc/pthread/weaks.c40
-rw-r--r--libc/sysdeps/linux/common/bits/uClibc_mutex.h17
-rw-r--r--libpthread/nptl/forward.c20
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), {