Module Name:    src
Committed By:   christos
Date:           Thu Mar 21 16:49:12 UTC 2013

Modified Files:
        src/lib/libc/include: reentrant.h
        src/lib/libc/thread-stub: thread-stub.c
        src/lib/libpthread: Makefile pthread.c pthread_cancelstub.c
            pthread_cond.c pthread_int.h pthread_misc.c pthread_mutex.c
            pthread_once.c pthread_rwlock.c pthread_specific.c pthread_tsd.c

Log Message:
- Allow libpthread to be dlopened again, by providing libc stubs to libpthread.
- Fail if the dlopened libpthread does pthread_create(). From manu@
- Discussed at length in the mailing lists; approved by core@
- This was chosen as the least intrusive patch that will provide
  the necessary functionality.
XXX: pullup to 6


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/lib/libc/include/reentrant.h
cvs rdiff -u -r1.22 -r1.23 src/lib/libc/thread-stub/thread-stub.c
cvs rdiff -u -r1.79 -r1.80 src/lib/libpthread/Makefile
cvs rdiff -u -r1.142 -r1.143 src/lib/libpthread/pthread.c
cvs rdiff -u -r1.37 -r1.38 src/lib/libpthread/pthread_cancelstub.c
cvs rdiff -u -r1.58 -r1.59 src/lib/libpthread/pthread_cond.c
cvs rdiff -u -r1.88 -r1.89 src/lib/libpthread/pthread_int.h
cvs rdiff -u -r1.14 -r1.15 src/lib/libpthread/pthread_misc.c
cvs rdiff -u -r1.55 -r1.56 src/lib/libpthread/pthread_mutex.c
cvs rdiff -u -r1.2 -r1.3 src/lib/libpthread/pthread_once.c
cvs rdiff -u -r1.32 -r1.33 src/lib/libpthread/pthread_rwlock.c
cvs rdiff -u -r1.25 -r1.26 src/lib/libpthread/pthread_specific.c
cvs rdiff -u -r1.10 -r1.11 src/lib/libpthread/pthread_tsd.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/lib/libc/include/reentrant.h
diff -u src/lib/libc/include/reentrant.h:1.15 src/lib/libc/include/reentrant.h:1.16
--- src/lib/libc/include/reentrant.h:1.15	Sun Jun  3 17:27:30 2012
+++ src/lib/libc/include/reentrant.h	Thu Mar 21 12:49:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: reentrant.h,v 1.15 2012/06/03 21:27:30 joerg Exp $	*/
+/*	$NetBSD: reentrant.h,v 1.16 2013/03/21 16:49:11 christos Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2003 The NetBSD Foundation, Inc.
@@ -221,6 +221,56 @@ __END_DECLS
 #define	thr_enabled()		(__isthreaded)
 #define thr_setcancelstate(n, o) __libc_thr_setcancelstate((n),(o))
 #define thr_curcpu()		__libc_thr_curcpu()
+
+#else /* __LIBC_THREAD_STUBS */
+
+__BEGIN_DECLS
+void	__libc_thr_init_stub(void);
+
+int	__libc_mutex_init_stub(mutex_t *, const mutexattr_t *);
+int	__libc_mutex_lock_stub(mutex_t *);
+int	__libc_mutex_trylock_stub(mutex_t *);
+int	__libc_mutex_unlock_stub(mutex_t *);
+int	__libc_mutex_destroy_stub(mutex_t *);
+
+int	__libc_mutexattr_init_stub(mutexattr_t *); 
+int	__libc_mutexattr_destroy_stub(mutexattr_t *);
+int	__libc_mutexattr_settype_stub(mutexattr_t *, int);
+
+int	__libc_cond_init_stub(cond_t *, const condattr_t *);
+int	__libc_cond_signal_stub(cond_t *);
+int	__libc_cond_broadcast_stub(cond_t *);
+int	__libc_cond_wait_stub(cond_t *, mutex_t *);
+int	__libc_cond_timedwait_stub(cond_t *, mutex_t *,
+				   const struct timespec *);
+int	__libc_cond_destroy_stub(cond_t *);
+
+int	__libc_rwlock_init_stub(rwlock_t *, const rwlockattr_t *);
+int	__libc_rwlock_rdlock_stub(rwlock_t *);
+int	__libc_rwlock_wrlock_stub(rwlock_t *);
+int	__libc_rwlock_tryrdlock_stub(rwlock_t *);
+int	__libc_rwlock_trywrlock_stub(rwlock_t *);
+int	__libc_rwlock_unlock_stub(rwlock_t *);
+int	__libc_rwlock_destroy_stub(rwlock_t *);
+
+int	__libc_thr_keycreate_stub(thread_key_t *, void (*)(void *));
+int	__libc_thr_setspecific_stub(thread_key_t, const void *);
+void	*__libc_thr_getspecific_stub(thread_key_t);
+int	__libc_thr_keydelete_stub(thread_key_t);
+
+int	__libc_thr_once_stub(once_t *, void (*)(void));
+int	__libc_thr_sigsetmask_stub(int, const sigset_t *, sigset_t *);
+thr_t	__libc_thr_self_stub(void);
+int	__libc_thr_yield_stub(void);
+int	__libc_thr_create_stub(thr_t *, const thrattr_t *,
+	    void *(*)(void *), void *);
+void	__libc_thr_exit_stub(void *);
+int	*__libc_thr_errno_stub(void);
+int	__libc_thr_setcancelstate_stub(int, int *);
+int	__libc_thr_equal_stub(pthread_t, pthread_t);
+unsigned int	__libc_thr_curcpu_stub(void);
+__END_DECLS
+
 #endif /* __LIBC_THREAD_STUBS */
 
 #define	FLOCKFILE(fp)		__flockfile_internal(fp, 1)

Index: src/lib/libc/thread-stub/thread-stub.c
diff -u src/lib/libc/thread-stub/thread-stub.c:1.22 src/lib/libc/thread-stub/thread-stub.c:1.23
--- src/lib/libc/thread-stub/thread-stub.c:1.22	Fri Sep 16 12:05:59 2011
+++ src/lib/libc/thread-stub/thread-stub.c	Thu Mar 21 12:49:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: thread-stub.c,v 1.22 2011/09/16 16:05:59 joerg Exp $	*/
+/*	$NetBSD: thread-stub.c,v 1.23 2013/03/21 16:49:11 christos Exp $	*/
 
 /*-
  * Copyright (c) 2003, 2009 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: thread-stub.c,v 1.22 2011/09/16 16:05:59 joerg Exp $");
+__RCSID("$NetBSD: thread-stub.c,v 1.23 2013/03/21 16:49:11 christos Exp $");
 #endif /* LIBC_SCCS and not lint */
 
 /*
@@ -69,9 +69,6 @@ do {					\
 
 /* libpthread init */
 
-void	__libc_thr_init(void);
-void	__libc_thr_init_stub(void);
-
 __weak_alias(__libc_thr_init,__libc_thr_init_stub)
 
 void
@@ -83,8 +80,7 @@ __libc_thr_init_stub(void)
 
 /* mutexes */
 
-int	__libc_mutex_init_stub(mutex_t *, const mutexattr_t *);
-int	__libc_mutex_catchall_stub(mutex_t *);
+int __libc_mutex_catchall_stub(mutex_t *);
 
 __weak_alias(__libc_mutex_init,__libc_mutex_init_stub)
 __weak_alias(__libc_mutex_lock,__libc_mutex_catchall_stub)
@@ -92,13 +88,20 @@ __weak_alias(__libc_mutex_trylock,__libc
 __weak_alias(__libc_mutex_unlock,__libc_mutex_catchall_stub)
 __weak_alias(__libc_mutex_destroy,__libc_mutex_catchall_stub)
 
-int	__libc_mutexattr_catchall_stub(mutexattr_t *);
-int	__libc_mutexattr_settype_stub(mutexattr_t *, int);
+__strong_alias(__libc_mutex_lock_stub,__libc_mutex_catchall_stub)
+__strong_alias(__libc_mutex_trylock_stub,__libc_mutex_catchall_stub)
+__strong_alias(__libc_mutex_unlock_stub,__libc_mutex_catchall_stub)
+__strong_alias(__libc_mutex_destroy_stub,__libc_mutex_catchall_stub)
+
+int __libc_mutexattr_catchall_stub(mutexattr_t *);
 
 __weak_alias(__libc_mutexattr_init,__libc_mutexattr_catchall_stub)
 __weak_alias(__libc_mutexattr_destroy,__libc_mutexattr_catchall_stub)
 __weak_alias(__libc_mutexattr_settype,__libc_mutexattr_settype_stub)
 
+__strong_alias(__libc_mutexattr_init_stub,__libc_mutexattr_catchall_stub)
+__strong_alias(__libc_mutexattr_destroy_stub,__libc_mutexattr_catchall_stub)
+
 int
 __libc_mutex_init_stub(mutex_t *m, const mutexattr_t *a)
 {
@@ -147,11 +150,7 @@ __libc_mutexattr_catchall_stub(mutexattr
 
 /* condition variables */
 
-int	__libc_cond_init_stub(cond_t *, const condattr_t *);
-int	__libc_cond_wait_stub(cond_t *, mutex_t *);
-int	__libc_cond_timedwait_stub(cond_t *, mutex_t *,
-				   const struct timespec *);
-int	__libc_cond_catchall_stub(cond_t *);
+int __libc_cond_catchall_stub(cond_t *);
 
 __weak_alias(__libc_cond_init,__libc_cond_init_stub)
 __weak_alias(__libc_cond_signal,__libc_cond_catchall_stub)
@@ -160,6 +159,11 @@ __weak_alias(__libc_cond_wait,__libc_con
 __weak_alias(__libc_cond_timedwait,__libc_cond_timedwait_stub)
 __weak_alias(__libc_cond_destroy,__libc_cond_catchall_stub)
 
+__strong_alias(__libc_cond_signal_stub,__libc_cond_catchall_stub)
+__strong_alias(__libc_cond_broadcast_stub,__libc_cond_catchall_stub)
+__strong_alias(__libc_cond_wait_stub,__libc_cond_catchall_stub)
+__strong_alias(__libc_cond_destroy_stub,__libc_cond_catchall_stub)
+
 int
 __libc_cond_init_stub(cond_t *c, const condattr_t *a)
 {
@@ -215,8 +219,7 @@ __libc_cond_catchall_stub(cond_t *c)
 
 /* read-write locks */
 
-int	__libc_rwlock_init_stub(rwlock_t *, rwlockattr_t *);
-int	__libc_rwlock_catchall_stub(rwlock_t *);
+int __libc_rwlock_catchall_stub(rwlock_t *);
 
 __weak_alias(__libc_rwlock_init,__libc_rwlock_init_stub)
 __weak_alias(__libc_rwlock_rdlock,__libc_rwlock_catchall_stub)
@@ -226,8 +229,16 @@ __weak_alias(__libc_rwlock_trywrlock,__l
 __weak_alias(__libc_rwlock_unlock,__libc_rwlock_catchall_stub)
 __weak_alias(__libc_rwlock_destroy,__libc_rwlock_catchall_stub)
 
+__strong_alias(__libc_rwlock_rdlock_stub,__libc_rwlock_catchall_stub)
+__strong_alias(__libc_rwlock_wrlock_stub,__libc_rwlock_catchall_stub)
+__strong_alias(__libc_rwlock_tryrdlock_stub,__libc_rwlock_catchall_stub)
+__strong_alias(__libc_rwlock_trywrlock_stub,__libc_rwlock_catchall_stub)
+__strong_alias(__libc_rwlock_unlock_stub,__libc_rwlock_catchall_stub)
+__strong_alias(__libc_rwlock_destroy_stub,__libc_rwlock_catchall_stub)
+
+
 int
-__libc_rwlock_init_stub(rwlock_t *l, rwlockattr_t *a)
+__libc_rwlock_init_stub(rwlock_t *l, const rwlockattr_t *a)
 {
 	/* LINTED deliberate lack of effect */
 	(void)l;
@@ -265,11 +276,6 @@ static struct {
 } __libc_tsd[TSD_KEYS_MAX];
 static int __libc_tsd_nextkey;
 
-int	__libc_thr_keycreate_stub(thread_key_t *, void (*)(void *));
-int	__libc_thr_setspecific_stub(thread_key_t, const void *);
-void	*__libc_thr_getspecific_stub(thread_key_t);
-int	__libc_thr_keydelete_stub(thread_key_t);
-
 __weak_alias(__libc_thr_keycreate,__libc_thr_keycreate_stub)
 __weak_alias(__libc_thr_setspecific,__libc_thr_setspecific_stub)
 __weak_alias(__libc_thr_getspecific,__libc_thr_getspecific_stub)
@@ -337,18 +343,6 @@ __libc_thr_keydelete_stub(thread_key_t k
 
 /* misc. */
 
-int	__libc_thr_once_stub(once_t *, void (*)(void));
-int	__libc_thr_sigsetmask_stub(int, const sigset_t *, sigset_t *);
-thr_t	__libc_thr_self_stub(void);
-int	__libc_thr_yield_stub(void);
-int	__libc_thr_create_stub(thr_t *, const thrattr_t *,
-	    void *(*)(void *), void *);
-__dead void	__libc_thr_exit_stub(void *);
-int	*__libc_thr_errno_stub(void);
-int	__libc_thr_setcancelstate_stub(int, int *);
-int	__libc_thr_equal_stub(pthread_t, pthread_t);
-unsigned int __libc_thr_curcpu_stub(void);
-
 __weak_alias(__libc_thr_once,__libc_thr_once_stub)
 __weak_alias(__libc_thr_sigsetmask,__libc_thr_sigsetmask_stub)
 __weak_alias(__libc_thr_self,__libc_thr_self_stub)

Index: src/lib/libpthread/Makefile
diff -u src/lib/libpthread/Makefile:1.79 src/lib/libpthread/Makefile:1.80
--- src/lib/libpthread/Makefile:1.79	Mon Feb 25 12:04:46 2013
+++ src/lib/libpthread/Makefile	Thu Mar 21 12:49:11 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: Makefile,v 1.79 2013/02/25 17:04:46 apb Exp $
+#	$NetBSD: Makefile,v 1.80 2013/03/21 16:49:11 christos Exp $
 #
 
 WARNS?=	5
@@ -25,16 +25,15 @@ INCSDIR=/usr/include
 ARCHDIR=	${.CURDIR}/arch/${ARCHSUBDIR}
 .PATH:	${ARCHDIR}
 
-CPPFLAGS+=	-I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC
-CPPFLAGS+=	-D__LIBPTHREAD_SOURCE__
+CPPFLAGS+=	-I${ARCHDIR} -I${.CURDIR} -I${.OBJDIR} -D_LIBC -D_REENTRANT
+CPPFLAGS+=	-I${.CURDIR}/../libc/include
+CPPFLAGS+=	-D__LIBPTHREAD_SOURCE__ -D__LIBC_THREAD_STUBS
 
 # XXX: This crappy poke at libc's internals needs to be fixed.
 CPPFLAGS+=-I${NETBSDSRCDIR}/sys -I${.CURDIR}/../libc
 
 LIB=	pthread
 
-LDFLAGS+=	-Wl,-znodlopen
-
 #
 # NOTE: When you create a new file for libpthread, make sure that pthread.c
 # gets a reference to a symbol in that file.  Otherwise, Unix's stupid static

Index: src/lib/libpthread/pthread.c
diff -u src/lib/libpthread/pthread.c:1.142 src/lib/libpthread/pthread.c:1.143
--- src/lib/libpthread/pthread.c:1.142	Tue Jan  1 13:42:39 2013
+++ src/lib/libpthread/pthread.c	Thu Mar 21 12:49:11 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread.c,v 1.142 2013/01/01 18:42:39 dsl Exp $	*/
+/*	$NetBSD: pthread.c,v 1.143 2013/03/21 16:49:11 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread.c,v 1.142 2013/01/01 18:42:39 dsl Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.143 2013/03/21 16:49:11 christos Exp $");
 
 #define	__EXPOSE_STACK	1
 
@@ -59,6 +59,7 @@ __RCSID("$NetBSD: pthread.c,v 1.142 2013
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 pthread_rwlock_t pthread__alltree_lock = PTHREAD_RWLOCK_INITIALIZER;
 static rb_tree_t	pthread__alltree;
@@ -84,6 +85,7 @@ static void	pthread__start(void);
 void	pthread__init(void);
 
 int pthread__started;
+int __uselibcstub = 1;
 pthread_mutex_t pthread__deadqueue_lock = PTHREAD_MUTEX_INITIALIZER;
 pthread_queue_t pthread__deadqueue;
 pthread_queue_t pthread__allqueue;
@@ -162,6 +164,8 @@ pthread__init(void)
 	int i;
 	extern int __isthreaded;
 
+	__uselibcstub = 0;
+
 	pthread__pagesize = (size_t)sysconf(_SC_PAGESIZE);
 	pthread__concurrency = (int)sysconf(_SC_NPROCESSORS_CONF);
 
@@ -387,6 +391,12 @@ pthread_create(pthread_t *thread, const 
 	void *private_area;
 	int ret;
 
+	if (__predict_false(__uselibcstub)) {
+    		pthread__errorfunc(__FILE__, __LINE__, __func__,
+		    "pthread_create() requires linking with -lpthread");
+		return __libc_thr_create_stub(thread, attr, startfunc, arg);
+	}
+
 	/*
 	 * It's okay to check this without a lock because there can
 	 * only be one thread before it becomes true.
@@ -601,6 +611,11 @@ pthread_exit(void *retval)
 	struct pt_clean_t *cleanup;
 	char *name;
 
+	if (__predict_false(__uselibcstub)) {
+		__libc_thr_exit_stub(retval);
+		goto out;
+	}
+
 	self = pthread__self();
 
 	/* Disable cancellability. */
@@ -643,6 +658,7 @@ pthread_exit(void *retval)
 		_lwp_exit();
 	}
 
+out:
 	/*NOTREACHED*/
 	pthread__abort();
 	exit(1);
@@ -720,6 +736,8 @@ pthread__reap(pthread_t thread)
 int
 pthread_equal(pthread_t t1, pthread_t t2)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_equal_stub(t1, t2);
 
 	/* Nothing special here. */
 	return (t1 == t2);
@@ -819,6 +837,8 @@ pthread_setname_np(pthread_t thread, con
 pthread_t
 pthread_self(void)
 {
+	if (__predict_false(__uselibcstub))
+		return (pthread_t)__libc_thr_self_stub();
 
 	return pthread__self();
 }
@@ -849,6 +869,9 @@ pthread_setcancelstate(int state, int *o
 	pthread_t self;
 	int retval;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_setcancelstate_stub(state, oldstate);
+
 	self = pthread__self();
 	retval = 0;
 
@@ -1017,6 +1040,12 @@ pthread__errno(void)
 {
 	pthread_t self;
 
+	if (__predict_false(__uselibcstub)) {
+    		pthread__errorfunc(__FILE__, __LINE__, __func__,
+		    "pthread__errno() requires linking with -lpthread");
+		return __libc_thr_errno_stub();
+	}
+
 	self = pthread__self();
 
 	return &(self->pt_errno);

Index: src/lib/libpthread/pthread_cancelstub.c
diff -u src/lib/libpthread/pthread_cancelstub.c:1.37 src/lib/libpthread/pthread_cancelstub.c:1.38
--- src/lib/libpthread/pthread_cancelstub.c:1.37	Wed Apr  4 13:47:03 2012
+++ src/lib/libpthread/pthread_cancelstub.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_cancelstub.c,v 1.37 2012/04/04 17:47:03 christos Exp $	*/
+/*	$NetBSD: pthread_cancelstub.c,v 1.38 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2007 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #undef _FORTIFY_SOURCE
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_cancelstub.c,v 1.37 2012/04/04 17:47:03 christos Exp $");
+__RCSID("$NetBSD: pthread_cancelstub.c,v 1.38 2013/03/21 16:49:12 christos Exp $");
 
 #ifndef lint
 
@@ -81,6 +81,7 @@ __RCSID("$NetBSD: pthread_cancelstub.c,v
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 int	pthread__cancel_stub_binder;
 
@@ -128,7 +129,8 @@ int	____sigtimedwait50(const sigset_t * 
 int	__sigsuspend14(const sigset_t *);
 
 #define TESTCANCEL(id) 	do {						\
-	if (__predict_false((id)->pt_cancel))				\
+	if (__predict_true(!__uselibcstub) &&				\
+	    __predict_false((id)->pt_cancel))				\
 		pthread__cancelled();					\
 	} while (/*CONSTCOND*/0)
 

Index: src/lib/libpthread/pthread_cond.c
diff -u src/lib/libpthread/pthread_cond.c:1.58 src/lib/libpthread/pthread_cond.c:1.59
--- src/lib/libpthread/pthread_cond.c:1.58	Fri Nov  2 23:10:50 2012
+++ src/lib/libpthread/pthread_cond.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_cond.c,v 1.58 2012/11/03 03:10:50 christos Exp $	*/
+/*	$NetBSD: pthread_cond.c,v 1.59 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -46,15 +46,16 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_cond.c,v 1.58 2012/11/03 03:10:50 christos Exp $");
+__RCSID("$NetBSD: pthread_cond.c,v 1.59 2013/03/21 16:49:12 christos Exp $");
 
+#include <stdlib.h>
 #include <errno.h>
 #include <sys/time.h>
 #include <sys/types.h>
-#include <stdlib.h>
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 int	_sys___nanosleep50(const struct timespec *, struct timespec *);
 
@@ -77,6 +78,8 @@ __strong_alias(__libc_cond_destroy,pthre
 int
 pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_cond_init_stub(cond, attr);
 
 	pthread__error(EINVAL, "Invalid condition variable attribute",
 	    (attr == NULL) || (attr->ptca_magic == _PT_CONDATTR_MAGIC));
@@ -101,6 +104,8 @@ pthread_cond_init(pthread_cond_t *cond, 
 int
 pthread_cond_destroy(pthread_cond_t *cond)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_cond_destroy_stub(cond);
 
 	pthread__error(EINVAL, "Invalid condition variable",
 	    cond->ptc_magic == _PT_COND_MAGIC);
@@ -120,6 +125,9 @@ pthread_cond_timedwait(pthread_cond_t *c
 	pthread_t self;
 	int retval;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_cond_timedwait_stub(cond, mutex, abstime);
+
 	pthread__error(EINVAL, "Invalid condition variable",
 	    cond->ptc_magic == _PT_COND_MAGIC);
 	pthread__error(EINVAL, "Invalid mutex",
@@ -199,6 +207,8 @@ pthread_cond_timedwait(pthread_cond_t *c
 int
 pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_cond_wait_stub(cond, mutex);
 
 	return pthread_cond_timedwait(cond, mutex, NULL);
 }
@@ -263,6 +273,9 @@ int
 pthread_cond_signal(pthread_cond_t *cond)
 {
 
+	if (__predict_false(__uselibcstub))
+		return __libc_cond_signal_stub(cond);
+
 	if (__predict_true(PTQ_EMPTY(&cond->ptc_waiters)))
 		return 0;
 	return pthread__cond_wake_one(cond);
@@ -310,6 +323,8 @@ pthread__cond_wake_all(pthread_cond_t *c
 int
 pthread_cond_broadcast(pthread_cond_t *cond)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_cond_broadcast_stub(cond);
 
 	if (__predict_true(PTQ_EMPTY(&cond->ptc_waiters)))
 		return 0;

Index: src/lib/libpthread/pthread_int.h
diff -u src/lib/libpthread/pthread_int.h:1.88 src/lib/libpthread/pthread_int.h:1.89
--- src/lib/libpthread/pthread_int.h:1.88	Wed Nov 21 14:19:24 2012
+++ src/lib/libpthread/pthread_int.h	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_int.h,v 1.88 2012/11/21 19:19:24 christos Exp $	*/
+/*	$NetBSD: pthread_int.h,v 1.89 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -188,6 +188,8 @@ extern int	pthread__concurrency;
 extern int 	pthread__osrev;
 extern int 	pthread__unpark_max;
 
+extern int	__uselibcstub;
+
 /* Flag to be used in a ucontext_t's uc_flags indicating that
  * the saved register state is "user" state only, not full
  * trap state.

Index: src/lib/libpthread/pthread_misc.c
diff -u src/lib/libpthread/pthread_misc.c:1.14 src/lib/libpthread/pthread_misc.c:1.15
--- src/lib/libpthread/pthread_misc.c:1.14	Wed Aug 12 19:51:23 2009
+++ src/lib/libpthread/pthread_misc.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_misc.c,v 1.14 2009/08/12 23:51:23 enami Exp $	*/
+/*	$NetBSD: pthread_misc.c,v 1.15 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_misc.c,v 1.14 2009/08/12 23:51:23 enami Exp $");
+__RCSID("$NetBSD: pthread_misc.c,v 1.15 2013/03/21 16:49:12 christos Exp $");
 
 #include <errno.h>
 #include <string.h>
@@ -46,6 +46,7 @@ __RCSID("$NetBSD: pthread_misc.c,v 1.14 
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 int	pthread__sched_yield(void);
 
@@ -142,7 +143,6 @@ pthread_kill(pthread_t thread, int sig)
 int
 pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
 {
-
 	if (_sys___sigprocmask14(how, set, oset))
 		return errno;
 	return 0;
@@ -154,6 +154,9 @@ pthread__sched_yield(void)
 	pthread_t self;
 	int error;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_yield();
+
 	self = pthread__self();
 
 	/* Memory barrier for unlocked mutex release. */

Index: src/lib/libpthread/pthread_mutex.c
diff -u src/lib/libpthread/pthread_mutex.c:1.55 src/lib/libpthread/pthread_mutex.c:1.56
--- src/lib/libpthread/pthread_mutex.c:1.55	Wed Mar  6 06:31:34 2013
+++ src/lib/libpthread/pthread_mutex.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_mutex.c,v 1.55 2013/03/06 11:31:34 yamt Exp $	*/
+/*	$NetBSD: pthread_mutex.c,v 1.56 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -47,7 +47,7 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_mutex.c,v 1.55 2013/03/06 11:31:34 yamt Exp $");
+__RCSID("$NetBSD: pthread_mutex.c,v 1.56 2013/03/21 16:49:12 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/lwpctl.h>
@@ -56,11 +56,13 @@ __RCSID("$NetBSD: pthread_mutex.c,v 1.55
 #include <errno.h>
 #include <limits.h>
 #include <stdlib.h>
+#include <time.h>
 #include <string.h>
 #include <stdio.h>
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 #define	MUTEX_WAITERS_BIT		((uintptr_t)0x01)
 #define	MUTEX_RECURSIVE_BIT		((uintptr_t)0x02)
@@ -103,6 +105,9 @@ pthread_mutex_init(pthread_mutex_t *ptm,
 {
 	intptr_t type;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_mutex_init_stub(ptm, attr);
+
 	if (attr == NULL)
 		type = PTHREAD_MUTEX_NORMAL;
 	else
@@ -134,6 +139,9 @@ int
 pthread_mutex_destroy(pthread_mutex_t *ptm)
 {
 
+	if (__predict_false(__uselibcstub))
+		return __libc_mutex_destroy_stub(ptm);
+
 	pthread__error(EINVAL, "Invalid mutex",
 	    ptm->ptm_magic == _PT_MUTEX_MAGIC);
 	pthread__error(EBUSY, "Destroying locked mutex",
@@ -149,6 +157,9 @@ pthread_mutex_lock(pthread_mutex_t *ptm)
 	pthread_t self;
 	void *val;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_mutex_lock_stub(ptm);
+
 	self = pthread__self();
 	val = atomic_cas_ptr(&ptm->ptm_owner, NULL, self);
 	if (__predict_true(val == NULL)) {
@@ -332,6 +343,9 @@ pthread_mutex_trylock(pthread_mutex_t *p
 	pthread_t self;
 	void *val, *new, *next;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_mutex_trylock_stub(ptm);
+
 	self = pthread__self();
 	val = atomic_cas_ptr(&ptm->ptm_owner, NULL, self);
 	if (__predict_true(val == NULL)) {
@@ -369,6 +383,9 @@ pthread_mutex_unlock(pthread_mutex_t *pt
 	pthread_t self;
 	void *value;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_mutex_unlock_stub(ptm);
+
 	/*
 	 * Note this may be a non-interlocked CAS.  See lock_slow()
 	 * above and sys/kern/kern_mutex.c for details.
@@ -539,6 +556,8 @@ pthread__mutex_wakeup(pthread_t self, pt
 int
 pthread_mutexattr_init(pthread_mutexattr_t *attr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_mutexattr_init_stub(attr);
 
 	attr->ptma_magic = _PT_MUTEXATTR_MAGIC;
 	attr->ptma_private = (void *)PTHREAD_MUTEX_DEFAULT;
@@ -548,6 +567,8 @@ pthread_mutexattr_init(pthread_mutexattr
 int
 pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_mutexattr_destroy_stub(attr);
 
 	pthread__error(EINVAL, "Invalid mutex attribute",
 	    attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
@@ -558,7 +579,6 @@ pthread_mutexattr_destroy(pthread_mutexa
 int
 pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *typep)
 {
-
 	pthread__error(EINVAL, "Invalid mutex attribute",
 	    attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
 
@@ -569,6 +589,8 @@ pthread_mutexattr_gettype(const pthread_
 int
 pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_mutexattr_settype_stub(attr, type);
 
 	pthread__error(EINVAL, "Invalid mutex attribute",
 	    attr->ptma_magic == _PT_MUTEXATTR_MAGIC);

Index: src/lib/libpthread/pthread_once.c
diff -u src/lib/libpthread/pthread_once.c:1.2 src/lib/libpthread/pthread_once.c:1.3
--- src/lib/libpthread/pthread_once.c:1.2	Mon Mar 12 21:05:55 2012
+++ src/lib/libpthread/pthread_once.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_once.c,v 1.2 2012/03/13 01:05:55 joerg Exp $	*/
+/*	$NetBSD: pthread_once.c,v 1.3 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2003 The NetBSD Foundation, Inc.
@@ -37,9 +37,11 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_once.c,v 1.2 2012/03/13 01:05:55 joerg Exp $");
+__RCSID("$NetBSD: pthread_once.c,v 1.3 2013/03/21 16:49:12 christos Exp $");
 
 #include "pthread.h"
+#include "pthread_int.h"
+#include "reentrant.h"
 
 static void
 once_cleanup(void *closure)
@@ -51,6 +53,8 @@ once_cleanup(void *closure)
 int
 pthread_once(pthread_once_t *once_control, void (*routine)(void))
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_once_stub(once_control, routine);
 
 	if (once_control->pto_done == 0) {
 		pthread_mutex_lock(&once_control->pto_mutex);

Index: src/lib/libpthread/pthread_rwlock.c
diff -u src/lib/libpthread/pthread_rwlock.c:1.32 src/lib/libpthread/pthread_rwlock.c:1.33
--- src/lib/libpthread/pthread_rwlock.c:1.32	Sat Oct 25 10:14:11 2008
+++ src/lib/libpthread/pthread_rwlock.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_rwlock.c,v 1.32 2008/10/25 14:14:11 yamt Exp $ */
+/*	$NetBSD: pthread_rwlock.c,v 1.33 2013/03/21 16:49:12 christos Exp $ */
 
 /*-
  * Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,16 +30,18 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_rwlock.c,v 1.32 2008/10/25 14:14:11 yamt Exp $");
+__RCSID("$NetBSD: pthread_rwlock.c,v 1.33 2013/03/21 16:49:12 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/lwpctl.h>
 
+#include <time.h>
 #include <errno.h>
 #include <stddef.h>
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 #define	_RW_LOCKED		0
 #define	_RW_WANT_WRITE		1
@@ -85,6 +87,8 @@ int
 pthread_rwlock_init(pthread_rwlock_t *ptr,
 	    const pthread_rwlockattr_t *attr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_init_stub(ptr, attr);
 
 	if (attr && (attr->ptra_magic != _PT_RWLOCKATTR_MAGIC))
 		return EINVAL;
@@ -101,6 +105,8 @@ pthread_rwlock_init(pthread_rwlock_t *pt
 int
 pthread_rwlock_destroy(pthread_rwlock_t *ptr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_destroy_stub(ptr);
 
 	if ((ptr->ptr_magic != _PT_RWLOCK_MAGIC) ||
 	    (!PTQ_EMPTY(&ptr->ptr_rblocked)) ||
@@ -233,6 +239,9 @@ pthread_rwlock_tryrdlock(pthread_rwlock_
 {
 	uintptr_t owner, next;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_tryrdlock_stub(ptr);
+
 #ifdef ERRORCHECK
 	if (ptr->ptr_magic != _PT_RWLOCK_MAGIC)
 		return EINVAL;
@@ -355,6 +364,9 @@ pthread_rwlock_trywrlock(pthread_rwlock_
 	uintptr_t owner, next;
 	pthread_t self;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_trywrlock_stub(ptr);
+
 #ifdef ERRORCHECK
 	if (ptr->ptr_magic != _PT_RWLOCK_MAGIC)
 		return EINVAL;
@@ -379,6 +391,8 @@ pthread_rwlock_trywrlock(pthread_rwlock_
 int
 pthread_rwlock_rdlock(pthread_rwlock_t *ptr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_rdlock_stub(ptr);
 
 	return pthread__rwlock_rdlock(ptr, NULL);
 }
@@ -387,7 +401,6 @@ int
 pthread_rwlock_timedrdlock(pthread_rwlock_t *ptr,
 			   const struct timespec *abs_timeout)
 {
-
 	if (abs_timeout == NULL)
 		return EINVAL;
 	if ((abs_timeout->tv_nsec >= 1000000000) ||
@@ -401,6 +414,8 @@ pthread_rwlock_timedrdlock(pthread_rwloc
 int
 pthread_rwlock_wrlock(pthread_rwlock_t *ptr)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_wrlock_stub(ptr);
 
 	return pthread__rwlock_wrlock(ptr, NULL);
 }
@@ -409,7 +424,6 @@ int
 pthread_rwlock_timedwrlock(pthread_rwlock_t *ptr,
 			   const struct timespec *abs_timeout)
 {
-
 	if (abs_timeout == NULL)
 		return EINVAL;
 	if ((abs_timeout->tv_nsec >= 1000000000) ||
@@ -428,6 +442,9 @@ pthread_rwlock_unlock(pthread_rwlock_t *
 	pthread_mutex_t *interlock;
 	pthread_t self, thread;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_rwlock_unlock_stub(ptr);
+
 #ifdef ERRORCHECK
 	if ((ptr == NULL) || (ptr->ptr_magic != _PT_RWLOCK_MAGIC))
 		return EINVAL;

Index: src/lib/libpthread/pthread_specific.c
diff -u src/lib/libpthread/pthread_specific.c:1.25 src/lib/libpthread/pthread_specific.c:1.26
--- src/lib/libpthread/pthread_specific.c:1.25	Wed Mar  6 06:30:56 2013
+++ src/lib/libpthread/pthread_specific.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_specific.c,v 1.25 2013/03/06 11:30:56 yamt Exp $	*/
+/*	$NetBSD: pthread_specific.c,v 1.26 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
@@ -30,12 +30,13 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_specific.c,v 1.25 2013/03/06 11:30:56 yamt Exp $");
+__RCSID("$NetBSD: pthread_specific.c,v 1.26 2013/03/21 16:49:12 christos Exp $");
 
 /* Functions and structures dealing with thread-specific data */
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 #include <string.h>
 #include <sys/lwpctl.h>
@@ -55,6 +56,9 @@ pthread_setspecific(pthread_key_t key, c
 {
 	pthread_t self;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_setspecific_stub(key, value);
+
 	self = pthread__self();
 	/*
 	 * We can't win here on constness. Having been given a 
@@ -68,6 +72,8 @@ pthread_setspecific(pthread_key_t key, c
 void *
 pthread_getspecific(pthread_key_t key)
 {
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_getspecific_stub(key);
 
 	return pthread__self()->pt_specific[key].pts_value;
 }
@@ -75,12 +81,17 @@ pthread_getspecific(pthread_key_t key)
 unsigned int
 pthread_curcpu_np(void)
 {
-	const int curcpu = pthread__self()->pt_lwpctl->lc_curcpu;
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_curcpu_stub();
+
+	{
+		const int curcpu = pthread__self()->pt_lwpctl->lc_curcpu;
 
-	pthread__assert(curcpu != LWPCTL_CPU_NONE);
-	pthread__assert(curcpu != LWPCTL_CPU_EXITED);
-	pthread__assert(curcpu >= 0);
-	return curcpu;
+		pthread__assert(curcpu != LWPCTL_CPU_NONE);
+		pthread__assert(curcpu != LWPCTL_CPU_EXITED);
+		pthread__assert(curcpu >= 0);
+		return curcpu;
+	}
 }
 
 /*

Index: src/lib/libpthread/pthread_tsd.c
diff -u src/lib/libpthread/pthread_tsd.c:1.10 src/lib/libpthread/pthread_tsd.c:1.11
--- src/lib/libpthread/pthread_tsd.c:1.10	Thu Nov 22 03:32:36 2012
+++ src/lib/libpthread/pthread_tsd.c	Thu Mar 21 12:49:12 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: pthread_tsd.c,v 1.10 2012/11/22 08:32:36 christos Exp $	*/
+/*	$NetBSD: pthread_tsd.c,v 1.11 2013/03/21 16:49:12 christos Exp $	*/
 
 /*-
  * Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
@@ -30,13 +30,14 @@
  */
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_tsd.c,v 1.10 2012/11/22 08:32:36 christos Exp $");
+__RCSID("$NetBSD: pthread_tsd.c,v 1.11 2013/03/21 16:49:12 christos Exp $");
 
 /* Functions and structures dealing with thread-specific data */
 #include <errno.h>
 
 #include "pthread.h"
 #include "pthread_int.h"
+#include "reentrant.h"
 
 
 static pthread_mutex_t tsd_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -55,11 +56,16 @@ null_destructor(void *p)
 {
 }
 
+#include <err.h>
+#include <stdlib.h>
 int
 pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
 {
 	int i;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_keycreate_stub(key, destructor);
+
 	/* Get a lock on the allocation list */
 	pthread_mutex_lock(&tsd_mutex);
 	
@@ -148,7 +154,6 @@ pthread__add_specific(pthread_t self, pt
 int
 pthread_key_delete(pthread_key_t key)
 {
-
 	/*
 	 * This is tricky.  The standard says of pthread_key_create()
 	 * that new keys have the value NULL associated with them in
@@ -229,6 +234,9 @@ pthread_key_delete(pthread_key_t key)
 	 */
 	struct pt_specific *pt;
 
+	if (__predict_false(__uselibcstub))
+		return __libc_thr_keydelete_stub(key);
+
 	pthread__assert(key >= 0 && key < PTHREAD_KEYS_MAX);
 
 	pthread_mutex_lock(&tsd_mutex);

Reply via email to