[git commit nptl] nptl: fix libc internal, dynamically enabled locking

Timo Teräs timo.teras at iki.fi
Wed Apr 14 17:58:30 UTC 2010


commit: http://git.uclibc.org/uClibc/commit/?id=279c728ee62e53eb055227695bc6fafb31a3a5f1
branch: http://git.uclibc.org/uClibc/commit/?id=refs/heads/nptl

Final iteration to fix libc internal locking if libpthread is pulled
in by dlopen call (directly or indirectly).

We cannot really use the weak symbol trick for shared build, since
the symbols won't get refreshed if libpthread is pulled in dynamically.
In glibc, they have #ifdef SHARED magic to either use pthread_functions
table, or weaks. But as we shared object files with both builds, this
does not sounds good either.

The reintroduces the libc weaks.c, but uses them now only with static
build. For dynamic build, we still use the symbols with same name, but
provide weaks in forward.c so they end up dereferencing the
pthread_functions table indirectly if we are not linked to libpthread.
Mutex initialization is hard coded as inline, as it needs to happen even
if libpthread is not initially loaded.

Signed-off-by: Timo Teräs <timo.teras at iki.fi>
Signed-off-by: Austin Foxley <austinf at cetoncorp.com>
---
 libc/misc/pthread/Makefile.in                 |    1 +
 libc/misc/pthread/weaks.c                     |   40 +++++++++++++++++++++++++
 libc/sysdeps/linux/common/bits/uClibc_mutex.h |   17 +++-------
 libpthread/nptl/forward.c                     |   20 ++++++++++--
 4 files changed, 62 insertions(+), 16 deletions(-)
 create mode 100644 libc/misc/pthread/weaks.c

diff --git a/libc/misc/pthread/Makefile.in b/libc/misc/pthread/Makefile.in
index 2f436ac..69cdf10 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 0000000..fb1d85f
--- /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 6d004bb..3e3d006 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 8f528d0..7878334 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), {
-- 
1.6.3.3



More information about the uClibc-cvs mailing list