[Midnightbsd-cvs] src: libthr/sys: update libthr

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Thu Oct 2 12:56:28 EDT 2008


Log Message:
-----------
update libthr

Modified Files:
--------------
    src/lib/libthr/arch/amd64/amd64:
        pthread_md.c (r1.1.1.1 -> r1.2)
    src/lib/libthr/arch/amd64/include:
        pthread_md.h (r1.1.1.1 -> r1.2)
    src/lib/libthr/arch/i386/i386:
        pthread_md.c (r1.1.1.2 -> r1.2)
    src/lib/libthr/arch/i386/include:
        pthread_md.h (r1.1.1.1 -> r1.2)
    src/lib/libthr/arch/sparc64/include:
        pthread_md.h (r1.1.1.1 -> r1.2)
    src/lib/libthr/sys:
        thr_error.c (r1.1.1.1 -> r1.2)
    src/lib/libthr/thread:
        Makefile.inc (r1.2 -> r1.3)
        thr_atfork.c (r1.1.1.1 -> r1.2)
        thr_attr.c (r1.1.1.2 -> r1.2)
        thr_barrier.c (r1.1.1.1 -> r1.2)
        thr_barrierattr.c (r1.1.1.1 -> r1.2)
        thr_cancel.c (r1.1.1.1 -> r1.2)
        thr_clean.c (r1.1.1.1 -> r1.2)
        thr_concurrency.c (r1.1.1.1 -> r1.2)
        thr_cond.c (r1.1.1.1 -> r1.2)
        thr_condattr.c (r1.1.1.1 -> r1.2)
        thr_create.c (r1.1.1.2 -> r1.2)
        thr_detach.c (r1.1.1.2 -> r1.2)
        thr_equal.c (r1.1.1.1 -> r1.2)
        thr_event.c (r1.1.1.1 -> r1.2)
        thr_exit.c (r1.1.1.2 -> r1.2)
        thr_fork.c (r1.1.1.2 -> r1.2)
        thr_getprio.c (r1.1.1.1 -> r1.2)
        thr_getschedparam.c (r1.1.1.1 -> r1.2)
        thr_info.c (r1.2 -> r1.3)
        thr_init.c (r1.1.1.2 -> r1.2)
        thr_join.c (r1.1.1.2 -> r1.2)
        thr_kern.c (r1.1.1.1 -> r1.2)
        thr_kill.c (r1.1.1.1 -> r1.2)
        thr_list.c (r1.1.1.2 -> r1.2)
        thr_main_np.c (r1.1.1.1 -> r1.2)
        thr_multi_np.c (r1.1.1.1 -> r1.2)
        thr_mutex.c (r1.2 -> r1.3)
        thr_mutexattr.c (r1.1.1.1 -> r1.2)
        thr_once.c (r1.1.1.2 -> r1.2)
        thr_private.h (r1.1.1.2 -> r1.2)
        thr_pspinlock.c (r1.1.1.1 -> r1.2)
        thr_resume_np.c (r1.1.1.2 -> r1.2)
        thr_rwlock.c (r1.1.1.1 -> r1.2)
        thr_rwlockattr.c (r1.1.1.1 -> r1.2)
        thr_self.c (r1.1.1.1 -> r1.2)
        thr_sem.c (r1.1.1.2 -> r1.2)
        thr_setprio.c (r1.1.1.1 -> r1.2)
        thr_setschedparam.c (r1.1.1.1 -> r1.2)
        thr_sig.c (r1.1.1.2 -> r1.2)
        thr_single_np.c (r1.1.1.1 -> r1.2)
        thr_spec.c (r1.2 -> r1.3)
        thr_spinlock.c (r1.1.1.1 -> r1.2)
        thr_stack.c (r1.1.1.1 -> r1.2)
        thr_suspend_np.c (r1.1.1.2 -> r1.2)
        thr_switch_np.c (r1.1.1.1 -> r1.2)
        thr_symbols.c (r1.1.1.2 -> r1.2)
        thr_syscalls.c (r1.2 -> r1.3)
        thr_umtx.c (r1.1.1.1 -> r1.2)
        thr_umtx.h (r1.1.1.2 -> r1.2)
        thr_yield.c (r1.1.1.1 -> r1.2)

Removed Files:
-------------
    src/lib/libthr/thread:
        thr_mutex_prioceiling.c
        thr_mutex_protocol.c
        thr_seterrno.c
        thr_sigmask.c

-------------- next part --------------
Index: pthread_md.h
===================================================================
RCS file: /home/cvs/src/lib/libthr/arch/sparc64/include/pthread_md.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/arch/sparc64/include/pthread_md.h -L lib/libthr/arch/sparc64/include/pthread_md.h -u -r1.1.1.1 -r1.2
--- lib/libthr/arch/sparc64/include/pthread_md.h
+++ lib/libthr/arch/sparc64/include/pthread_md.h
@@ -24,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/arch/sparc64/include/pthread_md.h,v 1.1 2005/04/02 01:19:59 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/arch/sparc64/include/pthread_md.h,v 1.2 2006/12/15 11:52:01 davidxu Exp $
  */
 
 /*
@@ -35,6 +35,8 @@
 
 #include <stddef.h>
 
+#define	CPU_SPINWAIT
+
 #define	DTV_OFFSET		offsetof(struct tcb, tcb_dtv)
 
 /*
Index: pthread_md.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/arch/i386/i386/pthread_md.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/arch/i386/i386/pthread_md.c -L lib/libthr/arch/i386/i386/pthread_md.c -u -r1.1.1.2 -r1.2
--- lib/libthr/arch/i386/i386/pthread_md.c
+++ lib/libthr/arch/i386/i386/pthread_md.c
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/arch/i386/i386/pthread_md.c,v 1.5.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/arch/i386/i386/pthread_md.c,v 1.7 2006/04/04 03:26:06 davidxu Exp $
  */
 
 #include <sys/types.h>
@@ -39,14 +39,11 @@
 _tcb_ctor(struct pthread *thread, int initial)
 {
 	struct tcb *tcb;
-	void *oldtls;
 
 	if (initial)
-		__asm __volatile("movl %%gs:0, %0" : "=r" (oldtls));
+		__asm __volatile("movl %%gs:0, %0" : "=r" (tcb));
 	else
-		oldtls = NULL;
-
-	tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
+		tcb = _rtld_allocate_tls(NULL, sizeof(struct tcb), 16);
 	if (tcb)
 		tcb->tcb_thread = thread;
 	return (tcb);
Index: pthread_md.h
===================================================================
RCS file: /home/cvs/src/lib/libthr/arch/i386/include/pthread_md.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/arch/i386/include/pthread_md.h -L lib/libthr/arch/i386/include/pthread_md.h -u -r1.1.1.1 -r1.2
--- lib/libthr/arch/i386/include/pthread_md.h
+++ lib/libthr/arch/i386/include/pthread_md.h
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/arch/i386/include/pthread_md.h,v 1.4 2005/04/27 01:29:03 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/arch/i386/include/pthread_md.h,v 1.8 2006/12/15 11:52:00 davidxu Exp $
  */
 
 /*
@@ -37,9 +37,9 @@
 #include <sys/types.h>
 #include <machine/sysarch.h>
 
-#define	DTV_OFFSET		offsetof(struct tcb, tcb_dtv)
+#define	CPU_SPINWAIT		__asm __volatile("pause")
 
-extern int _thr_using_setbase;
+#define	DTV_OFFSET		offsetof(struct tcb, tcb_dtv)
 
 /*
  * Variant II tcb, first two members are required by rtld,
@@ -96,14 +96,10 @@
 	return (TCB_GET32(tcb_self));
 }
 
-extern struct pthread *_thr_initial;
-
 /* Get the current thread. */
 static __inline struct pthread *
 _get_curthread(void)
 {
-	if (_thr_initial)
-		return (TCB_GET32(tcb_thread));
-	return (NULL);
+	return (TCB_GET32(tcb_thread));
 }
 #endif
Index: thr_error.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/sys/thr_error.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/sys/thr_error.c -L lib/libthr/sys/thr_error.c -u -r1.1.1.1 -r1.2
--- lib/libthr/sys/thr_error.c
+++ lib/libthr/sys/thr_error.c
@@ -31,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/sys/thr_error.c,v 1.2 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/sys/thr_error.c,v 1.3 2006/07/12 03:44:05 davidxu Exp $
  */
 
 #include <pthread.h>
@@ -45,10 +45,12 @@
 int *
 __error(void)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 
-	if (curthread != NULL && curthread != _thr_initial)
-		return (&curthread->error);
-	else
-		return (&errno);
+	if (_thr_initial != NULL) {
+		curthread = _get_curthread();
+		if (curthread != NULL && curthread != _thr_initial)
+			return (&curthread->error);
+	}
+	return (&errno);
 }
Index: pthread_md.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/arch/amd64/amd64/pthread_md.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/arch/amd64/amd64/pthread_md.c -L lib/libthr/arch/amd64/amd64/pthread_md.c -u -r1.1.1.1 -r1.2
--- lib/libthr/arch/amd64/amd64/pthread_md.c
+++ lib/libthr/arch/amd64/amd64/pthread_md.c
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/arch/amd64/amd64/pthread_md.c,v 1.1 2005/04/02 01:19:57 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/arch/amd64/amd64/pthread_md.c,v 1.2 2006/04/04 03:26:05 davidxu Exp $
  */
 
 #include <sys/types.h>
@@ -38,13 +38,11 @@
 _tcb_ctor(struct pthread *thread, int initial)
 {
 	struct tcb *tcb;
-	void *oldtls;
 
 	if (initial)
-		__asm __volatile("movq %%fs:0, %0" : "=r" (oldtls));
+		__asm __volatile("movq %%fs:0, %0" : "=r" (tcb));
 	else
-		oldtls = NULL;
-	tcb = _rtld_allocate_tls(oldtls, sizeof(struct tcb), 16);
+		tcb = _rtld_allocate_tls(NULL, sizeof(struct tcb), 16);
 	if (tcb)
 		tcb->tcb_thread = thread;
 	return (tcb);
Index: pthread_md.h
===================================================================
RCS file: /home/cvs/src/lib/libthr/arch/amd64/include/pthread_md.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/arch/amd64/include/pthread_md.h -L lib/libthr/arch/amd64/include/pthread_md.h -u -r1.1.1.1 -r1.2
--- lib/libthr/arch/amd64/include/pthread_md.h
+++ lib/libthr/arch/amd64/include/pthread_md.h
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/arch/amd64/include/pthread_md.h,v 1.1 2005/04/02 01:19:57 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/arch/amd64/include/pthread_md.h,v 1.4 2006/12/15 11:52:00 davidxu Exp $
  */
 
 /*
@@ -36,7 +36,8 @@
 #include <stddef.h>
 #include <sys/types.h>
 #include <machine/sysarch.h>
-#include <ucontext.h>
+
+#define	CPU_SPINWAIT		__asm __volatile("pause")
 
 #define	DTV_OFFSET		offsetof(struct tcb, tcb_dtv)
 
@@ -91,13 +92,9 @@
 	return (TCB_GET64(tcb_self));
 }
 
-extern struct pthread *_thr_initial;
-
 static __inline struct pthread *
 _get_curthread(void)
 {
-	if (_thr_initial)
-		return (TCB_GET64(tcb_thread));
-	return (NULL);
+	return (TCB_GET64(tcb_thread));
 }
 #endif
Index: thr_single_np.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_single_np.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_single_np.c -L lib/libthr/thread/thr_single_np.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_single_np.c
+++ lib/libthr/thread/thr_single_np.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,11 +26,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_single_np.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_single_np.c,v 1.3 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <pthread.h>
 #include <pthread_np.h>
+#include "un-namespace.h"
 
 __weak_reference(_pthread_single_np, pthread_single_np);
 
@@ -41,7 +40,7 @@
 {
 
 	/* Enter single-threaded (non-POSIX) scheduling mode: */
-	pthread_suspend_all_np();
+	_pthread_suspend_all_np();
 	/*
 	 * XXX - Do we want to do this?
 	 * __is_threaded = 0;
--- lib/libthr/thread/thr_seterrno.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libthr/thread/thr_seterrno.c,v 1.2 2005/04/02 01:20:00 davidxu Exp $
- */
-
-#include <pthread.h>
-
-#include "thr_private.h"
-
-/*
- * This function needs to reference the global error variable which is
- * normally hidden from the user. 
- */
-#undef errno
-extern int      errno;
-
-void
-_thread_seterrno(pthread_t thread, int error)
-{
-	/* Check for the initial thread: */
-	if (thread == NULL || thread == _thr_initial)
-		/* The initial thread always uses the global error variable: */
-		errno = error;
-	else
-		/*
-		 * Threads other than the initial thread always use the error
-		 * field in the thread structureL 
-		 */
-		thread->error = error;
-}
Index: thr_yield.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_yield.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_yield.c -L lib/libthr/thread/thr_yield.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_yield.c
+++ lib/libthr/thread/thr_yield.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,10 +26,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_yield.c,v 1.1 2003/04/01 03:46:29 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_yield.c,v 1.3 2007/01/12 07:26:21 imp Exp $
  */
+
+#include "namespace.h"
 #include <pthread.h>
-#include "thr_private.h"
+#include <sched.h>
+#include "un-namespace.h"
 
 __weak_reference(_pthread_yield, pthread_yield);
 
Index: thr_create.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_create.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_create.c -L lib/libthr/thread/thr_create.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_create.c
+++ lib/libthr/thread/thr_create.c
@@ -24,16 +24,19 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_create.c,v 1.22.2.2 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_create.c,v 1.36 2006/12/15 11:52:01 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <sys/types.h>
+#include <sys/rtprio.h>
 #include <sys/signalvar.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <string.h>
 #include <stddef.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -48,6 +51,8 @@
 {
 	struct pthread *curthread, *new_thread;
 	struct thr_param param;
+	struct sched_param sched_param;
+	struct rtprio rtp;
 	int ret = 0, locked, create_suspended;
 	sigset_t set, oset;
 
@@ -76,16 +81,10 @@
 			new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
 		else
 			new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM;
-		/*
-		 * scheduling policy and scheduling parameters will be
-		 * inherited in following code.
-		 */
-	}
 
-	if (_thr_scope_system > 0)
-		new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
-	else if (_thr_scope_system < 0)
-		new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM;
+		new_thread->attr.prio = curthread->attr.prio;
+		new_thread->attr.sched_policy = curthread->attr.sched_policy;
+	}
 
 	new_thread->tid = TID_TERMINATED;
 
@@ -101,35 +100,11 @@
 	new_thread->magic = THR_MAGIC;
 	new_thread->start_routine = start_routine;
 	new_thread->arg = arg;
-	new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
-	    PTHREAD_CANCEL_DEFERRED;
-	/*
-	 * Check if this thread is to inherit the scheduling
-	 * attributes from its parent:
-	 */
-	if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
-		/*
-		 * Copy the scheduling attributes. Lock the scheduling
-		 * lock to get consistent scheduling parameters.
-		 */
-		THR_LOCK(curthread);
-		new_thread->base_priority = curthread->base_priority;
-		new_thread->attr.prio = curthread->base_priority;
-		new_thread->attr.sched_policy = curthread->attr.sched_policy;
-		THR_UNLOCK(curthread);
-	} else {
-		/*
-		 * Use just the thread priority, leaving the
-		 * other scheduling attributes as their
-		 * default values:
-		 */
-		new_thread->base_priority = new_thread->attr.prio;
-	}
-	new_thread->active_priority = new_thread->base_priority;
-
+	new_thread->cancel_enable = 1;
+	new_thread->cancel_async = 0;
 	/* Initialize the mutex queue: */
 	TAILQ_INIT(&new_thread->mutexq);
-	TAILQ_INIT(&new_thread->pri_mutexq);
+	TAILQ_INIT(&new_thread->pp_mutexq);
 
 	/* Initialise hooks in the thread structure: */
 	if (new_thread->attr.suspend == THR_CREATE_SUSPENDED) {
@@ -165,6 +140,14 @@
 	param.flags = 0;
 	if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM)
 		param.flags |= THR_SYSTEM_SCOPE;
+	if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED)
+		param.rtp = NULL;
+	else {
+		sched_param.sched_priority = new_thread->attr.prio;
+		_schedparam_to_rtp(new_thread->attr.sched_policy,
+			&sched_param, &rtp);
+		param.rtp = &rtp;
+	}
 
 	/* Schedule the new thread. */
 	if (create_suspended) {
@@ -176,6 +159,15 @@
 
 	ret = thr_new(&param, sizeof(param));
 
+	if (ret != 0) {
+		ret = errno;
+		/*
+		 * Translate EPROCLIM into well-known POSIX code EAGAIN.
+		 */
+		if (ret == EPROCLIM)
+			ret = EAGAIN;
+	}
+
 	if (create_suspended)
 		__sys_sigprocmask(SIG_SETMASK, &oset, NULL);
 
@@ -195,7 +187,6 @@
 		_thr_ref_delete_unlocked(curthread, new_thread);
 		THREAD_LIST_UNLOCK(curthread);
 		(*thread) = 0;
-		ret = EAGAIN;
 	} else if (locked) {
 		_thr_report_creation(curthread, new_thread);
 		THR_THREAD_UNLOCK(curthread, new_thread);
@@ -243,7 +234,7 @@
 	THR_UNLOCK(curthread);
 
 	/* Run the current thread's start routine with argument: */
-	pthread_exit(curthread->start_routine(curthread->arg));
+	_pthread_exit(curthread->start_routine(curthread->arg));
 
 	/* This point should never be reached. */
 	PANIC("Thread has resumed after exit");
Index: thr_barrier.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_barrier.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_barrier.c -L lib/libthr/thread/thr_barrier.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_barrier.c
+++ lib/libthr/thread/thr_barrier.c
@@ -23,12 +23,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_barrier.c,v 1.4 2005/04/04 23:43:53 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_barrier.c,v 1.8 2006/12/05 23:46:11 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <stdlib.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -54,10 +56,12 @@
 
 int
 _pthread_barrier_init(pthread_barrier_t *barrier,
-		      const pthread_barrierattr_t *attr, int count)
+		      const pthread_barrierattr_t *attr, unsigned count)
 {
 	pthread_barrier_t	bar;
 
+	(void)attr;
+
 	if (barrier == NULL || count <= 0)
 		return (EINVAL);
 
@@ -65,7 +69,8 @@
 	if (bar == NULL)
 		return (ENOMEM);
 
-	_thr_umtx_init(&bar->b_lock);
+	_thr_umutex_init(&bar->b_lock);
+	_thr_ucond_init(&bar->b_cv);
 	bar->b_cycle	= 0;
 	bar->b_waiters	= 0;
 	bar->b_count	= count;
@@ -79,28 +84,29 @@
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_barrier_t bar;
-	long cycle;
+	int64_t cycle;
 	int ret;
 
 	if (barrier == NULL || *barrier == NULL)
 		return (EINVAL);
 
 	bar = *barrier;
-	THR_UMTX_LOCK(curthread, &bar->b_lock);
+	THR_UMUTEX_LOCK(curthread, &bar->b_lock);
 	if (++bar->b_waiters == bar->b_count) {
 		/* Current thread is lastest thread */
 		bar->b_waiters = 0;
 		bar->b_cycle++;
-		_thr_umtx_wake(&bar->b_cycle, bar->b_count - 1);
-		THR_UMTX_UNLOCK(curthread, &bar->b_lock);
+		_thr_ucond_broadcast(&bar->b_cv);
+		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
 		ret = PTHREAD_BARRIER_SERIAL_THREAD;
 	} else {
 		cycle = bar->b_cycle;
-		THR_UMTX_UNLOCK(curthread, &bar->b_lock);
 		do {
-			_thr_umtx_wait(&bar->b_cycle, cycle, NULL);
+			_thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
+			THR_UMUTEX_LOCK(curthread, &bar->b_lock);
 			/* test cycle to avoid bogus wakeup */
 		} while (cycle == bar->b_cycle);
+		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
 		ret = 0;
 	}
 	return (ret);
Index: thr_fork.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_fork.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_fork.c -L lib/libthr/thread/thr_fork.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_fork.c
+++ lib/libthr/thread/thr_fork.c
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_fork.c,v 1.1.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_fork.c,v 1.8 2007/01/12 07:26:20 imp Exp $
  */
 
 /*
@@ -39,10 +39,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -60,12 +57,14 @@
  *
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <string.h>
 #include <stdlib.h>
 #include <unistd.h>
 #include <pthread.h>
 #include <spinlock.h>
+#include "un-namespace.h"
 
 #include "libc_private.h"
 #include "thr_private.h"
@@ -88,20 +87,16 @@
 	af->prepare = prepare;
 	af->parent = parent;
 	af->child = child;
-	THR_UMTX_LOCK(curthread, &_thr_atfork_lock);
+	THR_UMUTEX_LOCK(curthread, &_thr_atfork_lock);
 	TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe);
-	THR_UMTX_UNLOCK(curthread, &_thr_atfork_lock);
+	THR_UMUTEX_UNLOCK(curthread, &_thr_atfork_lock);
 	return (0);
 }
 
-/*
- * For a while, allow libpthread to work with a libc that doesn't
- * export the malloc lock.
- */
-#pragma weak __malloc_lock
-
 __weak_reference(_fork, fork);
 
+pid_t _fork(void);
+
 pid_t
 _fork(void)
 {
@@ -116,7 +111,7 @@
 
 	curthread = _get_curthread();
 
-	THR_UMTX_LOCK(curthread, &_thr_atfork_lock);
+	THR_UMUTEX_LOCK(curthread, &_thr_atfork_lock);
 
 	/* Run down atfork prepare handlers. */
 	TAILQ_FOREACH_REVERSE(af, &_thr_atfork_list, atfork_head, qe) {
@@ -129,9 +124,9 @@
 	 * child process because another thread in malloc code will
 	 * simply be kill by fork().
 	 */
-	if ((_thr_isthreaded() != 0) && (__malloc_lock != NULL)) {
+	if (_thr_isthreaded() != 0) {
 		unlock_malloc = 1;
-		_spinlock(__malloc_lock);
+		_malloc_prefork();
 	} else {
 		unlock_malloc = 0;
 	}
@@ -145,7 +140,9 @@
 	if ((ret = __sys_fork()) == 0) {
 		/* Child process */
 		errsave = errno;
-		curthread->cancelflags &= ~THR_CANCEL_NEEDED;
+		curthread->cancel_pending = 0;
+		curthread->flags &= ~THR_FLAGS_NEED_SUSPEND;
+
 		/*
 		 * Thread list will be reinitialized, and later we call
 		 * _libpthread_init(), it will add us back to list.
@@ -156,11 +153,11 @@
 		thr_self(&curthread->tid);
 
 		/* clear other threads locked us. */
-		_thr_umtx_init(&curthread->lock);
-		_thr_umtx_init(&_thr_atfork_lock);
+		_thr_umutex_init(&curthread->lock);
+		_thr_umutex_init(&_thr_atfork_lock);
 		_thr_setthreaded(0);
 
-		/* reinitialize libc spinlocks, this includes __malloc_lock. */
+		/* reinitialize libc spinlocks. */
 		_thr_spinlock_init();
 		_mutex_fork(curthread);
 
@@ -183,7 +180,7 @@
 		_thr_signal_unblock(curthread);
 
 		if (unlock_malloc)
-			_spinunlock(__malloc_lock);
+			_malloc_postfork();
 
 		/* Run down atfork parent handlers. */
 		TAILQ_FOREACH(af, &_thr_atfork_list, qe) {
@@ -191,7 +188,7 @@
 				af->parent();
 		}
 
-		THR_UMTX_UNLOCK(curthread, &_thr_atfork_lock);
+		THR_UMUTEX_UNLOCK(curthread, &_thr_atfork_lock);
 	}
 	errno = errsave;
 
Index: thr_setprio.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_setprio.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_setprio.c -L lib/libthr/thread/thr_setprio.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_setprio.c
+++ lib/libthr/thread/thr_setprio.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,9 +26,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_setprio.c,v 1.1 2003/04/01 03:46:29 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_setprio.c,v 1.8 2007/01/12 07:26:20 imp Exp $
  */
+
+#include "namespace.h"
 #include <pthread.h>
+#include "un-namespace.h"
+
 #include "thr_private.h"
 
 __weak_reference(_pthread_setprio, pthread_setprio);
@@ -39,14 +40,43 @@
 int
 _pthread_setprio(pthread_t pthread, int prio)
 {
-	int ret, policy;
-	struct sched_param param;
+	struct pthread	*curthread = _get_curthread();
+	struct sched_param	param;
+	int	ret;
 
-	if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0) {
-		param.sched_priority = prio;
-		ret = pthread_setschedparam(pthread, policy, &param);
+	param.sched_priority = prio;
+	if (pthread == curthread) {
+		THR_LOCK(curthread);
+		if (curthread->attr.sched_policy == SCHED_OTHER ||
+		    curthread->attr.prio == prio) {
+			curthread->attr.prio = prio;
+			ret = 0;
+		} else {
+			ret = _thr_setscheduler(curthread->tid,
+			    curthread->attr.sched_policy, &param);
+			if (ret == -1)
+				ret = errno;
+			else 
+				curthread->attr.prio = prio;
+		}
+		THR_UNLOCK(curthread);
+	} else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
+		== 0) {
+		THR_THREAD_LOCK(curthread, pthread);
+		if (pthread->attr.sched_policy == SCHED_OTHER ||
+		    pthread->attr.prio == prio) {
+			pthread->attr.prio = prio;
+			ret = 0;
+		} else {
+			ret = _thr_setscheduler(pthread->tid,
+				curthread->attr.sched_policy, &param);
+			if (ret == -1)
+				ret = errno;
+			else
+				pthread->attr.prio = prio;
+		}
+		THR_THREAD_UNLOCK(curthread, pthread);
+		_thr_ref_delete(curthread, pthread);
 	}
-
-	/* Return the error status: */
 	return (ret);
 }
Index: thr_join.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_join.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_join.c -L lib/libthr/thread/thr_join.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_join.c
+++ lib/libthr/thread/thr_join.c
@@ -23,14 +23,19 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_join.c,v 1.16.2.3 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_join.c,v 1.23 2006/11/28 11:05:31 davidxu Exp $
+ *
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
+int	_pthread_timedjoin_np(pthread_t pthread, void **thread_return,
+	const struct timespec *abstime);
 static int join_common(pthread_t, void **, const struct timespec *);
 
 __weak_reference(_pthread_join, pthread_join);
@@ -71,7 +76,6 @@
 	struct timespec ts, ts2, *tsp;
 	void *tmp;
 	long tid;
-	int oldcancel;
 	int ret = 0;
 
 	if (pthread == NULL)
@@ -84,7 +88,7 @@
 	if ((ret = _thr_find_thread(curthread, pthread, 1)) != 0) {
 		ret = ESRCH;
 	} else if ((pthread->tlflags & TLFLAGS_DETACHED) != 0) {
-		ret = ESRCH;
+		ret = EINVAL;
 	} else if (pthread->joiner != NULL) {
 		/* Multiple joiners are not supported. */
 		ret = ENOTSUP;
@@ -99,7 +103,7 @@
 	THREAD_LIST_UNLOCK(curthread);
 
 	THR_CLEANUP_PUSH(curthread, backout_join, pthread);
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 
 	tid = pthread->tid;
 	while (pthread->tid != TID_TERMINATED) {
@@ -118,7 +122,7 @@
 			break;
 	}
 
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	THR_CLEANUP_POP(curthread, 0);
 
 	if (ret == ETIMEDOUT) {
Index: thr_sem.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_sem.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_sem.c -L lib/libthr/thread/thr_sem.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_sem.c
+++ lib/libthr/thread/thr_sem.c
@@ -27,7 +27,7 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_sem.c,v 1.5.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_sem.c,v 1.9 2006/11/24 09:57:38 davidxu Exp $
  */
 
 #include "namespace.h"
@@ -81,7 +81,7 @@
 		errno = ENOSPC;
 		return (NULL);
 	}
-	_thr_umtx_init((umtx_t *)&sem->lock);
+	bzero(sem, sizeof(*sem));
 	/*
 	 * Fortunatly count and nwaiters are adjacency, so we can
 	 * use umtx_wait to wait on it, umtx_wait needs an address
@@ -176,16 +176,16 @@
 _sem_wait(sem_t *sem)
 {
 	struct pthread *curthread;
-	int val, oldcancel, retval;
+	int val, retval;
 
 	if (sem_check_validity(sem) != 0)
 		return (-1);
 
 	curthread = _get_curthread();
 	if ((*sem)->syssem != 0) {
-		oldcancel = _thr_cancel_enter(curthread);
+		_thr_cancel_enter(curthread);
 		retval = ksem_wait((*sem)->semid);
-		_thr_cancel_leave(curthread, oldcancel);
+		_thr_cancel_leave(curthread);
 		return (retval);
 	}
 
@@ -195,29 +195,30 @@
 			if (atomic_cmpset_acq_int(&(*sem)->count, val, val - 1))
 				return (0);
 		}
-		oldcancel = _thr_cancel_enter(curthread);
+		_thr_cancel_enter(curthread);
 		retval = _thr_umtx_wait((umtx_t *)&(*sem)->count, 0, NULL);
-		_thr_cancel_leave(curthread, oldcancel);
+		_thr_cancel_leave(curthread);
 	} while (retval == 0);
 	errno = retval;
 	return (-1);
 }
 
 int
-_sem_timedwait(sem_t * __restrict sem, struct timespec * __restrict abstime)
+_sem_timedwait(sem_t * __restrict sem,
+    const struct timespec * __restrict abstime)
 {
 	struct timespec ts, ts2;
 	struct pthread *curthread;
-	int val, oldcancel, retval;
+	int val, retval;
 
 	if (sem_check_validity(sem) != 0)
 		return (-1);
 
 	curthread = _get_curthread();
 	if ((*sem)->syssem != 0) {
-		oldcancel = _thr_cancel_enter(curthread);
+		_thr_cancel_enter(curthread);
 		retval = ksem_timedwait((*sem)->semid, abstime);
-		_thr_cancel_leave(curthread, oldcancel);
+		_thr_cancel_leave(curthread);
 		return (retval);
 	}
 
@@ -237,9 +238,9 @@
 		}
 		clock_gettime(CLOCK_REALTIME, &ts);
 		TIMESPEC_SUB(&ts2, abstime, &ts);
-		oldcancel = _thr_cancel_enter(curthread);
+		_thr_cancel_enter(curthread);
 		retval = _thr_umtx_wait((umtx_t *)&(*sem)->count, 0, &ts2);
-		_thr_cancel_leave(curthread, oldcancel);
+		_thr_cancel_leave(curthread);
 	} while (retval == 0);
 	errno = retval;
 	return (-1);
Index: thr_getschedparam.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_getschedparam.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_getschedparam.c -L lib/libthr/thread/thr_getschedparam.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_getschedparam.c
+++ lib/libthr/thread/thr_getschedparam.c
@@ -29,11 +29,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_getschedparam.c,v 1.3 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_getschedparam.c,v 1.9 2006/09/21 04:21:30 davidxu Exp $
  */
 
+#include "namespace.h"
+#include <sys/types.h>
+#include <sys/rtprio.h>
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -44,34 +48,30 @@
 	struct sched_param *param)
 {
 	struct pthread *curthread = _get_curthread();
-	int ret, tmp;
+	int ret;
 
-	if ((param == NULL) || (policy == NULL))
-		/* Return an invalid argument error: */
-		ret = EINVAL;
-	else if (pthread == curthread) {
+	if (policy == NULL || param == NULL)
+		return (EINVAL);
+
+	if (pthread == curthread) {
 		/*
 		 * Avoid searching the thread list when it is the current
 		 * thread.
 		 */
-		THR_THREAD_LOCK(curthread, curthread);
-		param->sched_priority =
-		    THR_BASE_PRIORITY(pthread->base_priority);
-		tmp = pthread->attr.sched_policy;
-		THR_THREAD_UNLOCK(curthread, curthread);
-		*policy = tmp;
+		THR_LOCK(curthread);
+		*policy = curthread->attr.sched_policy;
+		param->sched_priority = curthread->attr.prio;
+		THR_UNLOCK(curthread);
 		ret = 0;
 	}
 	/* Find the thread in the list of active threads. */
 	else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
 	    == 0) {
 		THR_THREAD_LOCK(curthread, pthread);
-		param->sched_priority =
-		    THR_BASE_PRIORITY(pthread->base_priority);
-		tmp = pthread->attr.sched_policy;
+		*policy = pthread->attr.sched_policy;
+		param->sched_priority = pthread->attr.prio;
 		THR_THREAD_UNLOCK(curthread, pthread);
 		_thr_ref_delete(curthread, pthread);
-		*policy = tmp;
 	}
 	return (ret);
 }
Index: thr_resume_np.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_resume_np.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_resume_np.c -L lib/libthr/thread/thr_resume_np.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_resume_np.c
+++ lib/libthr/thread/thr_resume_np.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,11 +26,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_resume_np.c,v 1.8.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_resume_np.c,v 1.11 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
+#include <pthread_np.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_umtx.h
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_umtx.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_umtx.h -L lib/libthr/thread/thr_umtx.h -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_umtx.h
+++ lib/libthr/thread/thr_umtx.h
@@ -23,65 +23,78 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_umtx.h,v 1.1.2.2 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_umtx.h,v 1.10 2006/12/20 04:43:34 davidxu Exp $
  */
 
 #ifndef _THR_FBSD_UMTX_H_
 #define _THR_FBSD_UMTX_H_
 
+#include <strings.h>
 #include <sys/umtx.h>
 
+#define DEFAULT_UMUTEX	{0}
+
 typedef long umtx_t;
 
-int __thr_umtx_lock(volatile umtx_t *mtx, long id) __hidden;
-int __thr_umtx_timedlock(volatile umtx_t *mtx, long id,
+int __thr_umutex_lock(struct umutex *mtx) __hidden;
+int __thr_umutex_timedlock(struct umutex *mtx,
 	const struct timespec *timeout) __hidden;
-int __thr_umtx_unlock(volatile umtx_t *mtx, long id) __hidden;
+int __thr_umutex_unlock(struct umutex *mtx) __hidden;
+int __thr_umutex_trylock(struct umutex *mtx) __hidden;
+int __thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling,
+	uint32_t *oldceiling) __hidden;
+
+void _thr_umutex_init(struct umutex *mtx) __hidden;
+int _thr_umtx_wait(volatile umtx_t *mtx, umtx_t exp,
+	const struct timespec *timeout) __hidden;
+int _thr_umtx_wake(volatile umtx_t *mtx, int count) __hidden;
+int _thr_ucond_wait(struct ucond *cv, struct umutex *m,
+        const struct timespec *timeout, int check_unpaking) __hidden;
+void _thr_ucond_init(struct ucond *cv) __hidden;
+int _thr_ucond_signal(struct ucond *cv) __hidden;
+int _thr_ucond_broadcast(struct ucond *cv) __hidden;
 
-static inline void
-_thr_umtx_init(volatile umtx_t *mtx)
+static inline int
+_thr_umutex_trylock(struct umutex *mtx, uint32_t id)
 {
-    *mtx = 0;
+    if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
+	return (0);
+    if ((mtx->m_flags & UMUTEX_PRIO_PROTECT) == 0)
+    	return (EBUSY);
+    return (__thr_umutex_trylock(mtx));
 }
 
 static inline int
-_thr_umtx_trylock(volatile umtx_t *mtx, long id)
+_thr_umutex_trylock2(struct umutex *mtx, uint32_t id)
 {
-    if (atomic_cmpset_acq_ptr((volatile uintptr_t *)mtx,
-	(uintptr_t)UMTX_UNOWNED, (uintptr_t)id))
+    if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
 	return (0);
     return (EBUSY);
 }
 
 static inline int
-_thr_umtx_lock(volatile umtx_t *mtx, long id)
+_thr_umutex_lock(struct umutex *mtx, uint32_t id)
 {
-    if (atomic_cmpset_acq_ptr((volatile uintptr_t *)mtx,
-	(uintptr_t)UMTX_UNOWNED, (uintptr_t)id))
+    if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
 	return (0);
-    return (__thr_umtx_lock(mtx, id));
+    return (__thr_umutex_lock(mtx));
 }
 
 static inline int
-_thr_umtx_timedlock(volatile umtx_t *mtx, long id,
+_thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
 	const struct timespec *timeout)
 {
-    if (atomic_cmpset_acq_ptr((volatile uintptr_t *)mtx,
-	(uintptr_t)UMTX_UNOWNED, (uintptr_t)id))
+    if (atomic_cmpset_acq_32(&mtx->m_owner, UMUTEX_UNOWNED, id))
 	return (0);
-    return (__thr_umtx_timedlock(mtx, id, timeout));
+    return (__thr_umutex_timedlock(mtx, timeout));
 }
 
 static inline int
-_thr_umtx_unlock(volatile umtx_t *mtx, long id)
+_thr_umutex_unlock(struct umutex *mtx, uint32_t id)
 {
-    if (atomic_cmpset_rel_ptr((volatile uintptr_t *)mtx,
-	(uintptr_t)id, (uintptr_t)UMTX_UNOWNED))
+    if (atomic_cmpset_rel_32(&mtx->m_owner, id, UMUTEX_UNOWNED))
 	return (0);
-    return __thr_umtx_unlock(mtx, id);
+    return (__thr_umutex_unlock(mtx));
 }
 
-int _thr_umtx_wait(volatile umtx_t *mtx, umtx_t exp,
-	const struct timespec *timeout) __hidden;
-int _thr_umtx_wake(volatile umtx_t *mtx, int count) __hidden;
 #endif
Index: thr_main_np.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_main_np.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_main_np.c -L lib/libthr/thread/thr_main_np.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_main_np.c
+++ lib/libthr/thread/thr_main_np.c
@@ -24,11 +24,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_main_np.c,v 1.2 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_main_np.c,v 1.3 2006/04/04 02:57:49 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <pthread.h>
 #include <pthread_np.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -44,5 +46,5 @@
 	if (!_thr_initial)
 		return (-1);
 	else
-		return (pthread_equal(pthread_self(), _thr_initial) ? 1 : 0);
+		return (_pthread_equal(_pthread_self(), _thr_initial) ? 1 : 0);
 }
Index: thr_getprio.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_getprio.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_getprio.c -L lib/libthr/thread/thr_getprio.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_getprio.c
+++ lib/libthr/thread/thr_getprio.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,10 +26,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_getprio.c,v 1.1 2003/04/01 03:46:28 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_getprio.c,v 1.3 2007/01/12 07:26:20 imp Exp $
  */
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 #include "thr_private.h"
 
 __weak_reference(_pthread_getprio, pthread_getprio);
@@ -43,7 +42,7 @@
 	int policy, ret;
 	struct sched_param param;
 
-	if ((ret = pthread_getschedparam(pthread, &policy, &param)) == 0)
+	if ((ret = _pthread_getschedparam(pthread, &policy, &param)) == 0)
 		ret = param.sched_priority;
 	else {
 		/* Invalid thread: */
Index: thr_rwlock.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_rwlock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_rwlock.c -L lib/libthr/thread/thr_rwlock.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_rwlock.c
+++ lib/libthr/thread/thr_rwlock.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_rwlock.c,v 1.8 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_rwlock.c,v 1.10 2006/04/23 11:23:37 davidxu Exp $
  */
 
 #include <errno.h>
@@ -53,7 +53,7 @@
  */
 
 static int
-rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
+rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr __unused)
 {
 	pthread_rwlock_t prwlock;
 	int ret;
@@ -172,7 +172,6 @@
 		return (EAGAIN);
 	}
 
-	curthread = _get_curthread();
 	if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) {
 		/*
 		 * To avoid having to track all the rdlocks held by
@@ -256,7 +255,6 @@
 	if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
 		return (ret);
 
-	curthread = _get_curthread();
 	if (prwlock->state == MAX_READ_LOCKS)
 		ret = EAGAIN;
 	else if ((curthread->rdlock_count > 0) && (prwlock->state > 0)) {
@@ -317,7 +315,7 @@
 int
 _pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
 {
-	struct pthread *curthread;
+	struct pthread *curthread = _get_curthread();
 	pthread_rwlock_t prwlock;
 	int ret;
 
@@ -333,7 +331,6 @@
 	if ((ret = _pthread_mutex_lock(&prwlock->lock)) != 0)
 		return (ret);
 
-	curthread = _get_curthread();
 	if (prwlock->state > 0) {
 		curthread->rdlock_count--;
 		prwlock->state--;
Index: thr_exit.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_exit.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_exit.c -L lib/libthr/thread/thr_exit.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_exit.c
+++ lib/libthr/thread/thr_exit.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_exit.c,v 1.18.2.2 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_exit.c,v 1.23 2007/01/12 07:26:20 imp Exp $
  */
 
 #include <errno.h>
@@ -44,7 +41,7 @@
 __weak_reference(_pthread_exit, pthread_exit);
 
 void
-_thread_exit(char *fname, int lineno, char *msg)
+_thread_exit(const char *fname, int lineno, const char *msg)
 {
 
 	/* Write an error message to the standard error file descriptor: */
@@ -87,7 +84,7 @@
 	struct pthread *curthread = _get_curthread();
 
 	/* Check if this thread is already in the process of exiting: */
-	if ((curthread->cancelflags & THR_CANCEL_EXITING) != 0) {
+	if (curthread->cancelling) {
 		char msg[128];
 		snprintf(msg, sizeof(msg), "Thread %p has called "
 		    "pthread_exit() from a destructor. POSIX 1003.1 "
@@ -96,7 +93,7 @@
 	}
 
 	/* Flag this thread as exiting. */
-	atomic_set_int(&curthread->cancelflags, THR_CANCEL_EXITING);
+	curthread->cancelling = 1;
 	
 	_thr_exit_cleanup();
 
@@ -105,9 +102,7 @@
 	while (curthread->cleanup != NULL) {
 		pthread_cleanup_pop(1);
 	}
-	if (curthread->attr.cleanup_attr != NULL) {
-		curthread->attr.cleanup_attr(curthread->attr.arg_attr);
-	}
+
 	/* Check if there is thread specific data: */
 	if (curthread->specific != NULL) {
 		/* Run the thread-specific data destructors: */
Index: thr_detach.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_detach.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_detach.c -L lib/libthr/thread/thr_detach.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_detach.c
+++ lib/libthr/thread/thr_detach.c
@@ -24,13 +24,15 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_detach.c,v 1.9.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_detach.c,v 1.11 2006/04/04 02:57:49 davidxu Exp $
  *
  */
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_event.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_event.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_event.c -L lib/libthr/thread/thr_event.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_event.c
+++ lib/libthr/thread/thr_event.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_event.c,v 1.1 2005/04/12 03:08:11 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_event.c,v 1.2 2006/09/06 04:04:10 davidxu Exp $
  */
 
 #include "thr_private.h"
@@ -44,11 +44,11 @@
 	curthread->event_buf.event = TD_CREATE;
 	curthread->event_buf.th_p = (td_thrhandle_t *)newthread;
 	curthread->event_buf.data = 0;
-	THR_UMTX_LOCK(curthread, &_thr_event_lock);
+	THR_UMUTEX_LOCK(curthread, &_thr_event_lock);
 	_thread_last_event = curthread;
 	_thread_bp_create();
 	_thread_last_event = NULL;
-	THR_UMTX_UNLOCK(curthread, &_thr_event_lock);
+	THR_UMUTEX_UNLOCK(curthread, &_thr_event_lock);
 }
 
 void
@@ -57,9 +57,9 @@
 	curthread->event_buf.event = TD_DEATH;
 	curthread->event_buf.th_p = (td_thrhandle_t *)curthread;
 	curthread->event_buf.data = 0;
-	THR_UMTX_LOCK(curthread, &_thr_event_lock);
+	THR_UMUTEX_LOCK(curthread, &_thr_event_lock);
 	_thread_last_event = curthread;
 	_thread_bp_death();
 	_thread_last_event = NULL;
-	THR_UMTX_UNLOCK(curthread, &_thr_event_lock);
+	THR_UMUTEX_UNLOCK(curthread, &_thr_event_lock);
 }
--- lib/libthr/thread/thr_mutex_prioceiling.c
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * Copyright (c) 1998 Daniel Eischen <eischen at vigrid.com>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Daniel Eischen.
- * 4. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libthr/thread/thr_mutex_prioceiling.c,v 1.4 2005/04/02 01:20:00 davidxu Exp $
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <pthread.h>
-#include "thr_private.h"
-
-__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling);
-__weak_reference(_pthread_mutexattr_setprioceiling, pthread_mutexattr_setprioceiling);
-__weak_reference(_pthread_mutex_getprioceiling, pthread_mutex_getprioceiling);
-__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling);
-
-int
-_pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling)
-{
-	int ret = 0;
-
-	if ((mattr == NULL) || (*mattr == NULL))
-		ret = EINVAL;
-	else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
-		ret = EINVAL;
-	else
-		*prioceiling = (*mattr)->m_ceiling;
-
-	return(ret);
-}
-
-int
-_pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling)
-{
-	int ret = 0;
-
-	if ((mattr == NULL) || (*mattr == NULL))
-		ret = EINVAL;
-	else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
-		ret = EINVAL;
-	else
-		(*mattr)->m_ceiling = prioceiling;
-
-	return(ret);
-}
-
-int
-_pthread_mutex_getprioceiling(pthread_mutex_t *mutex,
-			      int *prioceiling)
-{
-	int ret;
-
-	if ((mutex == NULL) || (*mutex == NULL))
-		ret = EINVAL;
-	else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
-		ret = EINVAL;
-	else
-		ret = (*mutex)->m_prio;
-
-	return(ret);
-}
-
-int
-_pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
-			      int prioceiling, int *old_ceiling)
-{
-	int ret = 0;
-	int tmp;
-
-	if ((mutex == NULL) || (*mutex == NULL))
-		ret = EINVAL;
-	else if ((*mutex)->m_protocol != PTHREAD_PRIO_PROTECT)
-		ret = EINVAL;
-	/* Lock the mutex: */
-	else if ((ret = pthread_mutex_lock(mutex)) == 0) {
-		tmp = (*mutex)->m_prio;
-		/* Set the new ceiling: */
-		(*mutex)->m_prio = prioceiling;
-
-		/* Unlock the mutex: */
-		ret = pthread_mutex_unlock(mutex);
-
-		/* Return the old ceiling: */
-		*old_ceiling = tmp;
-	}
-	return(ret);
-}
Index: thr_list.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_list.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_list.c -L lib/libthr/thread/thr_list.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_list.c
+++ lib/libthr/thread/thr_list.c
@@ -24,7 +24,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_list.c,v 1.4.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_list.c,v 1.11 2006/11/24 09:57:38 davidxu Exp $
  */
 
 #include <sys/types.h>
@@ -44,6 +44,8 @@
 #define DBG_MSG(x...)
 #endif
 
+#define MAX_THREADS		100000
+
 /*
  * Define a high water mark for the maximum number of threads that
  * will be cached.  Once this level is reached, any extra threads
@@ -57,10 +59,11 @@
  * after a fork().
  */
 static TAILQ_HEAD(, pthread)	free_threadq;
-static umtx_t			free_thread_lock;
-static umtx_t			tcb_lock;
+static struct umutex		free_thread_lock = DEFAULT_UMUTEX;
+static struct umutex		tcb_lock = DEFAULT_UMUTEX;
 static int			free_thread_count = 0;
 static int			inited = 0;
+static int			total_threads;
 
 LIST_HEAD(thread_hash_head, pthread);
 #define HASH_QUEUES	128
@@ -75,11 +78,12 @@
 	int i;
 
 	_gc_count = 0;
-	_thr_umtx_init(&_thr_list_lock);
+	total_threads = 1;
+	_thr_umutex_init(&_thr_list_lock);
 	TAILQ_INIT(&_thread_list);
 	TAILQ_INIT(&free_threadq);
-	_thr_umtx_init(&free_thread_lock);
-	_thr_umtx_init(&tcb_lock);
+	_thr_umutex_init(&free_thread_lock);
+	_thr_umutex_init(&tcb_lock);
 	if (inited) {
 		for (i = 0; i < HASH_QUEUES; ++i)
 			LIST_INIT(&thr_hashtable[i]);
@@ -97,8 +101,7 @@
 	THREAD_LIST_LOCK(curthread);
 
 	/* Check the threads waiting for GC. */
-	for (td = TAILQ_FIRST(&_thread_gc_list); td != NULL; td = td_next) {
-		td_next = TAILQ_NEXT(td, gcle);
+	TAILQ_FOREACH_SAFE(td, &_thread_gc_list, gcle, td_next) {
 		if (td->tid != TID_TERMINATED) {
 			/* make sure we are not still in userland */
 			continue;
@@ -152,9 +155,14 @@
 		}
 	}
 	if (thread == NULL) {
+		if (total_threads > MAX_THREADS)
+			return (NULL);
+		atomic_fetchadd_int(&total_threads, 1);
 		thread = malloc(sizeof(struct pthread));
-		if (thread == NULL)
+		if (thread == NULL) {
+			atomic_fetchadd_int(&total_threads, -1);
 			return (NULL);
+		}
 	}
 	if (curthread != NULL) {
 		THR_LOCK_ACQUIRE(curthread, &tcb_lock);
@@ -168,6 +176,7 @@
 		thread->tcb = tcb;
 	} else {
 		thr_destroy(curthread, thread);
+		atomic_fetchadd_int(&total_threads, -1);
 		thread = NULL;
 	}
 	return (thread);
@@ -177,10 +186,7 @@
 _thr_free(struct pthread *curthread, struct pthread *thread)
 {
 	DBG_MSG("Freeing thread %p\n", thread);
-	if (thread->name) {
-		free(thread->name);
-		thread->name = NULL;
-	}
+
 	/*
 	 * Always free tcb, as we only know it is part of RTLD TLS
 	 * block, but don't know its detail and can not assume how
@@ -196,6 +202,7 @@
 	thread->tcb = NULL;
 	if ((curthread == NULL) || (free_thread_count >= MAX_CACHED_THREADS)) {
 		thr_destroy(curthread, thread);
+		atomic_fetchadd_int(&total_threads, -1);
 	} else {
 		/*
 		 * Add the thread to the free thread list, this also avoids
@@ -286,6 +293,7 @@
 	THREAD_LIST_LOCK(curthread);
 	if ((ret = _thr_find_thread(curthread, thread, include_dead)) == 0) {
 		thread->refcount++;
+		THR_CRITICAL_ENTER(curthread);
 	}
 	THREAD_LIST_UNLOCK(curthread);
 
@@ -302,18 +310,20 @@
 }
 
 void
-_thr_ref_delete_unlocked(struct pthread *curthread, struct pthread *thread)
+_thr_ref_delete_unlocked(struct pthread *curthread,
+	struct pthread *thread)
 {
 	if (thread != NULL) {
 		thread->refcount--;
 		if ((thread->refcount == 0) && thread->state == PS_DEAD &&
 		    (thread->tlflags & TLFLAGS_DETACHED) != 0)
 			THR_GCLIST_ADD(thread);
+		THR_CRITICAL_LEAVE(curthread);
 	}
 }
 
 int
-_thr_find_thread(struct pthread *curthread, struct pthread *thread,
+_thr_find_thread(struct pthread *curthread __unused, struct pthread *thread,
     int include_dead)
 {
 	struct pthread *pthread;
Index: thr_mutex.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_mutex.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L lib/libthr/thread/thr_mutex.c -L lib/libthr/thread/thr_mutex.c -u -r1.2 -r1.3
--- lib/libthr/thread/thr_mutex.c
+++ lib/libthr/thread/thr_mutex.c
@@ -1,5 +1,6 @@
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
+ * Copyright (c) 2006 David Xu <davidxu at freebsd.org>.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -29,15 +30,18 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_mutex.c,v 1.33.2.2 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_mutex.c,v 1.54.2.2 2007/12/13 02:29:17 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include <sys/param.h>
 #include <sys/queue.h>
 #include <pthread.h>
+#include "un-namespace.h"
+
 #include "thr_private.h"
 
 #if defined(_PTHREADS_INVARIANTS)
@@ -54,39 +58,32 @@
 	    ((m)->m_qe.tqe_next != NULL))		\
 		PANIC("mutex is on list");		\
 } while (0)
-#define	THR_ASSERT_NOT_IN_SYNCQ(thr)	do {		\
-	THR_ASSERT(((thr)->sflags & THR_FLAGS_IN_SYNCQ) == 0, \
-	    "thread in syncq when it shouldn't be.");	\
-} while (0);
 #else
 #define MUTEX_INIT_LINK(m)
 #define MUTEX_ASSERT_IS_OWNED(m)
 #define MUTEX_ASSERT_NOT_OWNED(m)
-#define	THR_ASSERT_NOT_IN_SYNCQ(thr)
 #endif
 
-#define THR_IN_MUTEXQ(thr)	(((thr)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
-#define	MUTEX_DESTROY(m) do {		\
-	free(m);			\
-} while (0)
-
+/*
+ * For adaptive mutexes, how many times to spin doing trylock2
+ * before entering the kernel to block
+ */
+#define MUTEX_ADAPTIVE_SPINS	200
 
 /*
  * Prototypes
  */
-static long		mutex_handoff(struct pthread *, struct pthread_mutex *);
-static int		mutex_self_trylock(struct pthread *, pthread_mutex_t);
-static int		mutex_self_lock(struct pthread *, pthread_mutex_t,
+int	__pthread_mutex_init(pthread_mutex_t *mutex,
+		const pthread_mutexattr_t *mutex_attr);
+int	__pthread_mutex_trylock(pthread_mutex_t *mutex);
+int	__pthread_mutex_lock(pthread_mutex_t *mutex);
+int	__pthread_mutex_timedlock(pthread_mutex_t *mutex,
+		const struct timespec *abstime);
+
+static int	mutex_self_trylock(pthread_mutex_t);
+static int	mutex_self_lock(pthread_mutex_t,
 				const struct timespec *abstime);
-static int		mutex_unlock_common(pthread_mutex_t *, int);
-static void		mutex_priority_adjust(struct pthread *, pthread_mutex_t);
-static void		mutex_rescan_owned (struct pthread *, struct pthread *,
-			    struct pthread_mutex *);
-#if 0
-static pthread_t	mutex_queue_deq(pthread_mutex_t);
-#endif
-static void		mutex_queue_remove(pthread_mutex_t, pthread_t);
-static void		mutex_queue_enq(pthread_mutex_t, pthread_t);
+static int	mutex_unlock_common(pthread_mutex_t *);
 
 __weak_reference(__pthread_mutex_init, pthread_mutex_init);
 __weak_reference(__pthread_mutex_lock, pthread_mutex_lock);
@@ -98,102 +95,55 @@
 __weak_reference(_pthread_mutex_destroy, pthread_mutex_destroy);
 __weak_reference(_pthread_mutex_unlock, pthread_mutex_unlock);
 
+__weak_reference(_pthread_mutex_getprioceiling, pthread_mutex_getprioceiling);
+__weak_reference(_pthread_mutex_setprioceiling, pthread_mutex_setprioceiling);
+
 static int
 mutex_init(pthread_mutex_t *mutex,
     const pthread_mutexattr_t *mutex_attr, int private)
 {
+	const struct pthread_mutex_attr *attr;
 	struct pthread_mutex *pmutex;
-	enum pthread_mutextype type;
-	int		protocol;
-	int		ceiling;
-	int		flags;
-	int		ret = 0;
-
-	/* Check if default mutex attributes: */
-	if (mutex_attr == NULL || *mutex_attr == NULL) {
-		/* Default to a (error checking) POSIX mutex: */
-		type = PTHREAD_MUTEX_ERRORCHECK;
-		protocol = PTHREAD_PRIO_NONE;
-		ceiling = THR_MAX_PRIORITY;
-		flags = 0;
-	}
-
-	/* Check mutex type: */
-	else if (((*mutex_attr)->m_type < PTHREAD_MUTEX_ERRORCHECK) ||
-	    ((*mutex_attr)->m_type >= MUTEX_TYPE_MAX))
-		/* Return an invalid argument error: */
-		ret = EINVAL;
 
-	/* Check mutex protocol: */
-	else if (((*mutex_attr)->m_protocol < PTHREAD_PRIO_NONE) ||
-	    ((*mutex_attr)->m_protocol > PTHREAD_PRIO_PROTECT))
-		/* Return an invalid argument error: */
-		ret = EINVAL;
-
-	else {
-		/* Use the requested mutex type and protocol: */
-		type = (*mutex_attr)->m_type;
-		protocol = (*mutex_attr)->m_protocol;
-		ceiling = (*mutex_attr)->m_ceiling;
-		flags = (*mutex_attr)->m_flags;
-	}
-
-	/* Check no errors so far: */
-	if (ret == 0) {
-		if ((pmutex = (pthread_mutex_t)
-		    malloc(sizeof(struct pthread_mutex))) == NULL) {
-			ret = ENOMEM;
-		} else {
-			_thr_umtx_init(&pmutex->m_lock);
-			/* Set the mutex flags: */
-			pmutex->m_flags = flags;
-
-			/* Process according to mutex type: */
-			switch (type) {
-			/* case PTHREAD_MUTEX_DEFAULT: */
-			case PTHREAD_MUTEX_ERRORCHECK:
-			case PTHREAD_MUTEX_NORMAL:
-				/* Nothing to do here. */
-				break;
-
-			/* Single UNIX Spec 2 recursive mutex: */
-			case PTHREAD_MUTEX_RECURSIVE:
-				/* Reset the mutex count: */
-				pmutex->m_count = 0;
-				break;
-
-			/* Trap invalid mutex types: */
-			default:
-				/* Return an invalid argument error: */
-				ret = EINVAL;
-				break;
-			}
-			if (ret == 0) {
-				/* Initialise the rest of the mutex: */
-				TAILQ_INIT(&pmutex->m_queue);
-				pmutex->m_flags |= MUTEX_FLAGS_INITED;
-				if (private)
-					pmutex->m_flags |= MUTEX_FLAGS_PRIVATE;
-				pmutex->m_owner = NULL;
-				pmutex->m_type = type;
-				pmutex->m_protocol = protocol;
-				pmutex->m_refcount = 0;
-				if (protocol == PTHREAD_PRIO_PROTECT)
-					pmutex->m_prio = ceiling;
-				else
-					pmutex->m_prio = -1;
-				pmutex->m_saved_prio = 0;
-				MUTEX_INIT_LINK(pmutex);
-				*mutex = pmutex;
-			} else {
-				/* Free the mutex lock structure: */
-				MUTEX_DESTROY(pmutex);
-				*mutex = NULL;
-			}
-		}
+	if (mutex_attr == NULL) {
+		attr = &_pthread_mutexattr_default;
+	} else {
+		attr = *mutex_attr;
+		if (attr->m_type < PTHREAD_MUTEX_ERRORCHECK ||
+		    attr->m_type >= PTHREAD_MUTEX_TYPE_MAX)
+			return (EINVAL);
+		if (attr->m_protocol < PTHREAD_PRIO_NONE ||
+		    attr->m_protocol > PTHREAD_PRIO_PROTECT)
+			return (EINVAL);
+	}
+	if ((pmutex = (pthread_mutex_t)
+		calloc(1, sizeof(struct pthread_mutex))) == NULL)
+		return (ENOMEM);
+
+	pmutex->m_type = attr->m_type;
+	pmutex->m_owner = NULL;
+	pmutex->m_flags = attr->m_flags | MUTEX_FLAGS_INITED;
+	if (private)
+		pmutex->m_flags |= MUTEX_FLAGS_PRIVATE;
+	pmutex->m_count = 0;
+	pmutex->m_refcount = 0;
+	MUTEX_INIT_LINK(pmutex);
+	switch(attr->m_protocol) {
+	case PTHREAD_PRIO_INHERIT:
+		pmutex->m_lock.m_owner = UMUTEX_UNOWNED;
+		pmutex->m_lock.m_flags = UMUTEX_PRIO_INHERIT;
+		break;
+	case PTHREAD_PRIO_PROTECT:
+		pmutex->m_lock.m_owner = UMUTEX_CONTESTED;
+		pmutex->m_lock.m_flags = UMUTEX_PRIO_PROTECT;
+		pmutex->m_lock.m_ceilings[0] = attr->m_ceiling;
+		break;
+	case PTHREAD_PRIO_NONE:
+		pmutex->m_lock.m_owner = UMUTEX_UNOWNED;
+		pmutex->m_lock.m_flags = 0;
 	}
-	/* Return the completion status: */
-	return (ret);
+	*mutex = pmutex;
+	return (0);
 }
 
 static int
@@ -230,6 +180,18 @@
 	return (ret);
 }
 
+static void
+set_inherited_priority(struct pthread *curthread, struct pthread_mutex *m)
+{
+	struct pthread_mutex *m2;
+
+	m2 = TAILQ_LAST(&curthread->pp_mutexq, mutex_queue);
+	if (m2 != NULL)
+		m->m_lock.m_ceilings[1] = m2->m_lock.m_ceilings[0];
+	else
+		m->m_lock.m_ceilings[1] = -1;
+}
+
 int
 _pthread_mutex_init(pthread_mutex_t *mutex,
     const pthread_mutexattr_t *mutex_attr)
@@ -244,20 +206,6 @@
 	return mutex_init(mutex, mutex_attr, 0);
 }
 
-int
-_mutex_reinit(pthread_mutex_t *mutex)
-{
-	_thr_umtx_init(&(*mutex)->m_lock);
-	TAILQ_INIT(&(*mutex)->m_queue);
-	MUTEX_INIT_LINK(*mutex);
-	(*mutex)->m_owner = NULL;
-	(*mutex)->m_count = 0;
-	(*mutex)->m_refcount = 0;
-	(*mutex)->m_prio = 0;
-	(*mutex)->m_saved_prio = 0;
-	return (0);
-}
-
 void
 _mutex_fork(struct pthread *curthread)
 {
@@ -272,16 +220,11 @@
 	 * process shared mutex is not supported, so I
 	 * am not worried.
 	 */
-	TAILQ_FOREACH(m, &curthread->mutexq, m_qe) {
-		m->m_lock = (umtx_t)curthread->tid;
-	}
 
-	/* Clear contender for priority mutexes */
-	TAILQ_FOREACH(m, &curthread->pri_mutexq, m_qe) {
-		/* clear another thread locked us */
-		_thr_umtx_init(&m->m_lock);
-		TAILQ_INIT(&m->m_queue);
-	}
+	TAILQ_FOREACH(m, &curthread->mutexq, m_qe)
+		m->m_lock.m_owner = TID(curthread);
+	TAILQ_FOREACH(m, &curthread->pp_mutexq, m_qe)
+		m->m_lock.m_owner = TID(curthread) | UMUTEX_CONTESTED;
 }
 
 int
@@ -289,174 +232,79 @@
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_mutex_t m;
+	uint32_t id;
 	int ret = 0;
 
-	if (mutex == NULL || *mutex == NULL)
+	if (__predict_false(*mutex == NULL))
 		ret = EINVAL;
 	else {
+		id = TID(curthread);
+
 		/*
 		 * Try to lock the mutex structure, we only need to
 		 * try once, if failed, the mutex is in used.
 		 */
-		ret = THR_UMTX_TRYLOCK(curthread, &(*mutex)->m_lock);
+		ret = _thr_umutex_trylock(&(*mutex)->m_lock, id);
 		if (ret)
 			return (ret);
-
+		m  = *mutex;
 		/*
 		 * Check mutex other fields to see if this mutex is
 		 * in use. Mostly for prority mutex types, or there
 		 * are condition variables referencing it.
 		 */
-		if (((*mutex)->m_owner != NULL) ||
-		    (TAILQ_FIRST(&(*mutex)->m_queue) != NULL) ||
-		    ((*mutex)->m_refcount != 0)) {
-			THR_UMTX_UNLOCK(curthread, &(*mutex)->m_lock);
+		if (m->m_owner != NULL || m->m_refcount != 0) {
+			if (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)
+				set_inherited_priority(curthread, m);
+			_thr_umutex_unlock(&m->m_lock, id);
 			ret = EBUSY;
 		} else {
 			/*
 			 * Save a pointer to the mutex so it can be free'd
-			 * and set the caller's pointer to NULL:
+			 * and set the caller's pointer to NULL.
 			 */
-			m = *mutex;
 			*mutex = NULL;
 
-			/* Unlock the mutex structure: */
-			_thr_umtx_unlock(&m->m_lock, curthread->tid);
+			if (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)
+				set_inherited_priority(curthread, m);
+			_thr_umutex_unlock(&m->m_lock, id);
 
-			/*
-			 * Free the memory allocated for the mutex
-			 * structure:
-			 */
 			MUTEX_ASSERT_NOT_OWNED(m);
-			MUTEX_DESTROY(m);
+			free(m);
 		}
 	}
 
-	/* Return the completion status: */
 	return (ret);
 }
 
+
+#define ENQUEUE_MUTEX(curthread, m)  					\
+	do {								\
+		(m)->m_owner = curthread;				\
+		/* Add to the list of owned mutexes: */			\
+		MUTEX_ASSERT_NOT_OWNED((m));				\
+		if (((m)->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)	\
+			TAILQ_INSERT_TAIL(&curthread->mutexq, (m), m_qe);\
+		else							\
+			TAILQ_INSERT_TAIL(&curthread->pp_mutexq, (m), m_qe);\
+	} while (0)
+
 static int
 mutex_trylock_common(struct pthread *curthread, pthread_mutex_t *mutex)
 {
-	int ret = 0;
-
-	THR_ASSERT((mutex != NULL) && (*mutex != NULL),
-	    "Uninitialized mutex in mutex_trylock_common");
-
-	/* Short cut for simple mutex. */
-	if ((*mutex)->m_protocol == PTHREAD_PRIO_NONE) {
-		ret = THR_UMTX_TRYLOCK(curthread, &(*mutex)->m_lock);
-		if (ret == 0) {
-			(*mutex)->m_owner = curthread;
-			/* Add to the list of owned mutexes: */
-			MUTEX_ASSERT_NOT_OWNED(*mutex);
-			TAILQ_INSERT_TAIL(&curthread->mutexq,
-			    (*mutex), m_qe);
-		} else if ((*mutex)->m_owner == curthread) {
-			ret = mutex_self_trylock(curthread, *mutex);
-		} /* else {} */
-
-		return (ret);
-	}
-
-	/* Code for priority mutex */
-
-	/* Lock the mutex structure: */
-	THR_LOCK_ACQUIRE(curthread, &(*mutex)->m_lock);
-
-	/*
-	 * If the mutex was statically allocated, properly
-	 * initialize the tail queue.
-	 */
-	if (((*mutex)->m_flags & MUTEX_FLAGS_INITED) == 0) {
-		TAILQ_INIT(&(*mutex)->m_queue);
-		MUTEX_INIT_LINK(*mutex);
-		(*mutex)->m_flags |= MUTEX_FLAGS_INITED;
-	}
-
-	/* Process according to mutex type: */
-	switch ((*mutex)->m_protocol) {
-	/* POSIX priority inheritence mutex: */
-	case PTHREAD_PRIO_INHERIT:
-		/* Check if this mutex is not locked: */
-		if ((*mutex)->m_owner == NULL) {
-			/* Lock the mutex for the running thread: */
-			(*mutex)->m_owner = curthread;
-
-			THR_LOCK(curthread);
-			/* Track number of priority mutexes owned: */
-			curthread->priority_mutex_count++;
-
-			/*
-			 * The mutex takes on the attributes of the
-			 * running thread when there are no waiters.
-			 */
-			(*mutex)->m_prio = curthread->active_priority;
-			(*mutex)->m_saved_prio =
-			    curthread->inherited_priority;
-			curthread->inherited_priority = (*mutex)->m_prio;
-			THR_UNLOCK(curthread);
-
-			/* Add to the list of owned mutexes: */
-			MUTEX_ASSERT_NOT_OWNED(*mutex);
-			TAILQ_INSERT_TAIL(&curthread->pri_mutexq,
-			    (*mutex), m_qe);
-		} else if ((*mutex)->m_owner == curthread)
-			ret = mutex_self_trylock(curthread, *mutex);
-		else
-			/* Return a busy error: */
-			ret = EBUSY;
-		break;
-
-	/* POSIX priority protection mutex: */
-	case PTHREAD_PRIO_PROTECT:
-		/* Check for a priority ceiling violation: */
-		if (curthread->active_priority > (*mutex)->m_prio)
-			ret = EINVAL;
-
-		/* Check if this mutex is not locked: */
-		else if ((*mutex)->m_owner == NULL) {
-			/* Lock the mutex for the running thread: */
-			(*mutex)->m_owner = curthread;
-
-			THR_LOCK(curthread);
-			/* Track number of priority mutexes owned: */
-			curthread->priority_mutex_count++;
-
-			/*
-			 * The running thread inherits the ceiling
-			 * priority of the mutex and executes at that
-			 * priority.
-			 */
-			curthread->active_priority = (*mutex)->m_prio;
-			(*mutex)->m_saved_prio =
-			    curthread->inherited_priority;
-			curthread->inherited_priority =
-			    (*mutex)->m_prio;
-			THR_UNLOCK(curthread);
-			/* Add to the list of owned mutexes: */
-			MUTEX_ASSERT_NOT_OWNED(*mutex);
-			TAILQ_INSERT_TAIL(&curthread->pri_mutexq,
-			    (*mutex), m_qe);
-		} else if ((*mutex)->m_owner == curthread)
-			ret = mutex_self_trylock(curthread, *mutex);
-		else
-			/* Return a busy error: */
-			ret = EBUSY;
-		break;
-
-	/* Trap invalid mutex types: */
-	default:
-		/* Return an invalid argument error: */
-		ret = EINVAL;
-		break;
-	}
+	struct pthread_mutex *m;
+	uint32_t id;
+	int ret;
 
-	/* Unlock the mutex structure: */
-	THR_LOCK_RELEASE(curthread, &(*mutex)->m_lock);
+	id = TID(curthread);
+	m = *mutex;
+	ret = _thr_umutex_trylock(&m->m_lock, id);
+	if (ret == 0) {
+		ENQUEUE_MUTEX(curthread, m);
+	} else if (m->m_owner == curthread) {
+		ret = mutex_self_trylock(m);
+	} /* else {} */
 
-	/* Return the completion status: */
 	return (ret);
 }
 
@@ -464,302 +312,127 @@
 __pthread_mutex_trylock(pthread_mutex_t *mutex)
 {
 	struct pthread *curthread = _get_curthread();
-	int ret = 0;
+	int ret;
 
 	/*
 	 * If the mutex is statically initialized, perform the dynamic
 	 * initialization:
 	 */
-	if ((*mutex != NULL) ||
-	    ((ret = init_static(curthread, mutex)) == 0))
-		ret = mutex_trylock_common(curthread, mutex);
-
-	return (ret);
+	if (__predict_false(*mutex == NULL)) {
+		ret = init_static(curthread, mutex);
+		if (__predict_false(ret))
+			return (ret);
+	}
+	return (mutex_trylock_common(curthread, mutex));
 }
 
 int
 _pthread_mutex_trylock(pthread_mutex_t *mutex)
 {
 	struct pthread	*curthread = _get_curthread();
-	int	ret = 0;
+	int	ret;
 
 	/*
 	 * If the mutex is statically initialized, perform the dynamic
 	 * initialization marking the mutex private (delete safe):
 	 */
-	if ((*mutex != NULL) ||
-	    ((ret = init_static_private(curthread, mutex)) == 0))
-		ret = mutex_trylock_common(curthread, mutex);
-
-	return (ret);
+	if (__predict_false(*mutex == NULL)) {
+		ret = init_static_private(curthread, mutex);
+		if (__predict_false(ret))
+			return (ret);
+	}
+	return (mutex_trylock_common(curthread, mutex));
 }
 
 static int
-mutex_lock_common(struct pthread *curthread, pthread_mutex_t *m,
+mutex_lock_common(struct pthread *curthread, pthread_mutex_t *mutex,
 	const struct timespec * abstime)
 {
 	struct  timespec ts, ts2;
-	long	cycle;
-	int	ret = 0;
-
-	THR_ASSERT((m != NULL) && (*m != NULL),
-	    "Uninitialized mutex in mutex_lock_common");
-
-	if (abstime != NULL && (abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
-	    abstime->tv_nsec >= 1000000000))
-		return (EINVAL);
-
-	/* Short cut for simple mutex. */
-
-	if ((*m)->m_protocol == PTHREAD_PRIO_NONE) {
-		/* Default POSIX mutex: */
-		ret = THR_UMTX_TRYLOCK(curthread, &(*m)->m_lock);
-		if (ret == 0) {
-			(*m)->m_owner = curthread;
-			/* Add to the list of owned mutexes: */
-			MUTEX_ASSERT_NOT_OWNED(*m);
-			TAILQ_INSERT_TAIL(&curthread->mutexq,
-			    (*m), m_qe);
-		} else if ((*m)->m_owner == curthread) {
-			ret = mutex_self_lock(curthread, *m, abstime);
-		} else {
-			if (abstime == NULL) {
-				THR_UMTX_LOCK(curthread, &(*m)->m_lock);
-				ret = 0;
-			} else {
-				clock_gettime(CLOCK_REALTIME, &ts);
-				TIMESPEC_SUB(&ts2, abstime, &ts);
-				ret = THR_UMTX_TIMEDLOCK(curthread,
-					&(*m)->m_lock, &ts2);
-				/*
-				 * Timed out wait is not restarted if
-				 * it was interrupted, not worth to do it.
-				 */
-				if (ret == EINTR)
-					ret = ETIMEDOUT;
-			}
-			if (ret == 0) {
-				(*m)->m_owner = curthread;
-				/* Add to the list of owned mutexes: */
-				MUTEX_ASSERT_NOT_OWNED(*m);
-				TAILQ_INSERT_TAIL(&curthread->mutexq,
-				    (*m), m_qe);
-			}
-		}
-		return (ret);
-	}
-
-	/* Code for priority mutex */
-
-	/*
-	 * Enter a loop waiting to become the mutex owner.  We need a
-	 * loop in case the waiting thread is interrupted by a signal
-	 * to execute a signal handler.  It is not (currently) possible
-	 * to remain in the waiting queue while running a handler.
-	 * Instead, the thread is interrupted and backed out of the
-	 * waiting queue prior to executing the signal handler.
-	 */
-	do {
-		/* Lock the mutex structure: */
-		THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
+	struct	pthread_mutex *m;
+	uint32_t	id;
+	int	ret;
+	int	count;
 
+	id = TID(curthread);
+	m = *mutex;
+	ret = _thr_umutex_trylock2(&m->m_lock, id);
+	if (ret == 0) {
+		ENQUEUE_MUTEX(curthread, m);
+	} else if (m->m_owner == curthread) {
+		ret = mutex_self_lock(m, abstime);
+	} else {
 		/*
-		 * If the mutex was statically allocated, properly
-		 * initialize the tail queue.
-		 */
-		if (((*m)->m_flags & MUTEX_FLAGS_INITED) == 0) {
-			TAILQ_INIT(&(*m)->m_queue);
-			(*m)->m_flags |= MUTEX_FLAGS_INITED;
-			MUTEX_INIT_LINK(*m);
-		}
-
-		/* Process according to mutex type: */
-		switch ((*m)->m_protocol) {
-		/* POSIX priority inheritence mutex: */
-		case PTHREAD_PRIO_INHERIT:
-			/* Check if this mutex is not locked: */
-			if ((*m)->m_owner == NULL) {
-				/* Lock the mutex for this thread: */
-				(*m)->m_owner = curthread;
-
-				THR_LOCK(curthread);
-				/* Track number of priority mutexes owned: */
-				curthread->priority_mutex_count++;
-
-				/*
-				 * The mutex takes on attributes of the
-				 * running thread when there are no waiters.
-				 * Make sure the thread's scheduling lock is
-				 * held while priorities are adjusted.
-				 */
-				(*m)->m_prio = curthread->active_priority;
-				(*m)->m_saved_prio =
-				    curthread->inherited_priority;
-				curthread->inherited_priority = (*m)->m_prio;
-				THR_UNLOCK(curthread);
-
-				/* Add to the list of owned mutexes: */
-				MUTEX_ASSERT_NOT_OWNED(*m);
-				TAILQ_INSERT_TAIL(&curthread->pri_mutexq,
-				    (*m), m_qe);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-			} else if ((*m)->m_owner == curthread) {
-				ret = mutex_self_lock(curthread, *m, abstime);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-			} else {
-				/*
-				 * Join the queue of threads waiting to lock
-				 * the mutex and save a pointer to the mutex.
-				 */
-				mutex_queue_enq(*m, curthread);
-				curthread->data.mutex = *m;
-
-				if (curthread->active_priority > (*m)->m_prio)
-					/* Adjust priorities: */
-					mutex_priority_adjust(curthread, *m);
-
-				THR_LOCK(curthread);
-				cycle = curthread->cycle;
-				THR_UNLOCK(curthread);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-				if (abstime != NULL) {
-					clock_gettime(CLOCK_REALTIME, &ts);
-					TIMESPEC_SUB(&ts2, abstime, &ts);
-					ret = _thr_umtx_wait(&curthread->cycle,
-						cycle, &ts2);
-				} else
-					ret = _thr_umtx_wait(&curthread->cycle,
-						cycle, NULL);
-				if (ret == EINTR)
-					ret = 0;
-
-				if (THR_IN_MUTEXQ(curthread)) {
-					THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
-					mutex_queue_remove(*m, curthread);
-					THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-				}
-				/*
-				 * Only clear these after assuring the
-				 * thread is dequeued.
-				 */
-				curthread->data.mutex = NULL;
-			}
-			break;
-
-		/* POSIX priority protection mutex: */
-		case PTHREAD_PRIO_PROTECT:
-			/* Check for a priority ceiling violation: */
-			if (curthread->active_priority > (*m)->m_prio) {
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-				ret = EINVAL;
+		 * For adaptive mutexes, spin for a bit in the expectation
+		 * that if the application requests this mutex type then
+		 * the lock is likely to be released quickly and it is
+		 * faster than entering the kernel
+		 */
+		if (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT)
+			goto sleep_in_kernel;
+
+		if (!_thr_is_smp)
+			goto yield_loop;
+
+		if (m->m_type == PTHREAD_MUTEX_ADAPTIVE_NP) {
+			count = MUTEX_ADAPTIVE_SPINS;
+  	 
+			while (count--) {
+				ret = _thr_umutex_trylock2(&m->m_lock, id);
+				if (ret == 0)
+					break;
+				CPU_SPINWAIT;
 			}
-			/* Check if this mutex is not locked: */
-			else if ((*m)->m_owner == NULL) {
-				/*
-				 * Lock the mutex for the running
-				 * thread:
-				 */
-				(*m)->m_owner = curthread;
-
-				THR_LOCK(curthread);
-				/* Track number of priority mutexes owned: */
-				curthread->priority_mutex_count++;
-
-				/*
-				 * The running thread inherits the ceiling
-				 * priority of the mutex and executes at that
-				 * priority.  Make sure the thread's
-				 * scheduling lock is held while priorities
-				 * are adjusted.
-				 */
-				curthread->active_priority = (*m)->m_prio;
-				(*m)->m_saved_prio =
-				    curthread->inherited_priority;
-				curthread->inherited_priority = (*m)->m_prio;
-				THR_UNLOCK(curthread);
-
-				/* Add to the list of owned mutexes: */
-				MUTEX_ASSERT_NOT_OWNED(*m);
-				TAILQ_INSERT_TAIL(&curthread->pri_mutexq,
-				    (*m), m_qe);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-			} else if ((*m)->m_owner == curthread) {
-				ret = mutex_self_lock(curthread, *m, abstime);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-			} else {
-				/*
-				 * Join the queue of threads waiting to lock
-				 * the mutex and save a pointer to the mutex.
-				 */
-				mutex_queue_enq(*m, curthread);
-				curthread->data.mutex = *m;
-
-				/* Clear any previous error: */
-				curthread->error = 0;
-
-				THR_LOCK(curthread);
-				cycle = curthread->cycle;
-				THR_UNLOCK(curthread);
-
-				/* Unlock the mutex structure: */
-				THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-				if (abstime != NULL) {
-					clock_gettime(CLOCK_REALTIME, &ts);
-					TIMESPEC_SUB(&ts2, abstime, &ts);
-					ret = _thr_umtx_wait(&curthread->cycle,
-						cycle, &ts2);
-				} else
-					ret = _thr_umtx_wait(&curthread->cycle,
-						cycle, NULL);
-				if (ret == EINTR)
-					ret = 0;
-
-				curthread->data.mutex = NULL;
-				if (THR_IN_MUTEXQ(curthread)) {
-					THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
-					mutex_queue_remove(*m, curthread);
-					THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
+			if (ret == 0)
+				goto done;
+		} else {
+			if (_thr_spinloops != 0) {
+				count = _thr_spinloops;
+				while (count) {
+					if (m->m_lock.m_owner == UMUTEX_UNOWNED) {
+						ret = _thr_umutex_trylock2(&m->m_lock, id);
+						if (ret == 0)
+							goto done;
+					}
+					CPU_SPINWAIT;
+					count--;
 				}
-				/*
-				 * Only clear these after assuring the
-				 * thread is dequeued.
-				 */
-				curthread->data.mutex = NULL;
-
-				/*
-				 * The threads priority may have changed while
-				 * waiting for the mutex causing a ceiling
-				 * violation.
-				 */
-				ret = curthread->error;
-				curthread->error = 0;
 			}
-			break;
-
-		/* Trap invalid mutex types: */
-		default:
-			/* Unlock the mutex structure: */
-			THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-
-			/* Return an invalid argument error: */
-			ret = EINVAL;
-			break;
 		}
 
-	} while (((*m)->m_owner != curthread) && (ret == 0));
+yield_loop:
+		if (_thr_yieldloops != 0) {
+			count = _thr_yieldloops;
+			while (count--) {
+				_sched_yield();
+				ret = _thr_umutex_trylock2(&m->m_lock, id);
+				if (ret == 0)
+					goto done;
+			}
+		}
 
-	/* Return the completion status: */
+sleep_in_kernel:
+		if (abstime == NULL) {
+			ret = __thr_umutex_lock(&m->m_lock);
+		} else if (__predict_false(
+			   abstime->tv_sec < 0 || abstime->tv_nsec < 0 ||
+			   abstime->tv_nsec >= 1000000000)) {
+			ret = EINVAL;
+		} else {
+			clock_gettime(CLOCK_REALTIME, &ts);
+			TIMESPEC_SUB(&ts2, abstime, &ts);
+			ret = __thr_umutex_timedlock(&m->m_lock, &ts2);
+			/*
+			 * Timed out wait is not restarted if
+			 * it was interrupted, not worth to do it.
+			 */
+			if (ret == EINTR)
+				ret = ETIMEDOUT;
+		}
+done:
+		if (ret == 0)
+			ENQUEUE_MUTEX(curthread, m);
+	}
 	return (ret);
 }
 
@@ -767,7 +440,7 @@
 __pthread_mutex_lock(pthread_mutex_t *m)
 {
 	struct pthread *curthread;
-	int	ret = 0;
+	int	ret;
 
 	_thr_check_init();
 
@@ -777,17 +450,19 @@
 	 * If the mutex is statically initialized, perform the dynamic
 	 * initialization:
 	 */
-	if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0))
-		ret = mutex_lock_common(curthread, m, NULL);
-
-	return (ret);
+	if (__predict_false(*m == NULL)) {
+		ret = init_static(curthread, m);
+		if (__predict_false(ret))
+			return (ret);
+	}
+	return (mutex_lock_common(curthread, m, NULL));
 }
 
 int
 _pthread_mutex_lock(pthread_mutex_t *m)
 {
 	struct pthread *curthread;
-	int	ret = 0;
+	int	ret;
 
 	_thr_check_init();
 
@@ -797,19 +472,19 @@
 	 * If the mutex is statically initialized, perform the dynamic
 	 * initialization marking it private (delete safe):
 	 */
-	if ((*m != NULL) ||
-	    ((ret = init_static_private(curthread, m)) == 0))
-		ret = mutex_lock_common(curthread, m, NULL);
-
-	return (ret);
+	if (__predict_false(*m == NULL)) {
+		ret = init_static_private(curthread, m);
+		if (__predict_false(ret))
+			return (ret);
+	}
+	return (mutex_lock_common(curthread, m, NULL));
 }
 
 int
-__pthread_mutex_timedlock(pthread_mutex_t *m,
-	const struct timespec *abs_timeout)
+__pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *abstime)
 {
 	struct pthread *curthread;
-	int	ret = 0;
+	int	ret;
 
 	_thr_check_init();
 
@@ -819,18 +494,19 @@
 	 * If the mutex is statically initialized, perform the dynamic
 	 * initialization:
 	 */
-	if ((*m != NULL) || ((ret = init_static(curthread, m)) == 0))
-		ret = mutex_lock_common(curthread, m, abs_timeout);
-
-	return (ret);
+	if (__predict_false(*m == NULL)) {
+		ret = init_static(curthread, m);
+		if (__predict_false(ret))
+			return (ret);
+	}
+	return (mutex_lock_common(curthread, m, abstime));
 }
 
 int
-_pthread_mutex_timedlock(pthread_mutex_t *m,
-	const struct timespec *abs_timeout)
+_pthread_mutex_timedlock(pthread_mutex_t *m, const struct timespec *abstime)
 {
-	struct pthread *curthread;
-	int	ret = 0;
+	struct pthread	*curthread;
+	int	ret;
 
 	_thr_check_init();
 
@@ -840,43 +516,39 @@
 	 * If the mutex is statically initialized, perform the dynamic
 	 * initialization marking it private (delete safe):
 	 */
-	if ((*m != NULL) ||
-	    ((ret = init_static_private(curthread, m)) == 0))
-		ret = mutex_lock_common(curthread, m, abs_timeout);
-
-	return (ret);
+	if (__predict_false(*m == NULL)) {
+		ret = init_static_private(curthread, m);
+		if (__predict_false(ret))
+			return (ret);
+	}
+	return (mutex_lock_common(curthread, m, abstime));
 }
 
 int
 _pthread_mutex_unlock(pthread_mutex_t *m)
 {
-	return (mutex_unlock_common(m, /* add reference */ 0));
-}
-
-int
-_mutex_cv_unlock(pthread_mutex_t *m)
-{
-	return (mutex_unlock_common(m, /* add reference */ 1));
+	return (mutex_unlock_common(m));
 }
 
 int
-_mutex_cv_lock(pthread_mutex_t *m)
+_mutex_cv_lock(pthread_mutex_t *m, int count)
 {
 	int	ret;
 
 	ret = mutex_lock_common(_get_curthread(), m, NULL);
-	if (ret == 0)
+	if (ret == 0) {
 		(*m)->m_refcount--;
+		(*m)->m_count += count;
+	}
 	return (ret);
 }
 
 static int
-mutex_self_trylock(struct pthread *curthread, pthread_mutex_t m)
+mutex_self_trylock(pthread_mutex_t m)
 {
 	int	ret;
 
 	switch (m->m_type) {
-	/* case PTHREAD_MUTEX_DEFAULT: */
 	case PTHREAD_MUTEX_ERRORCHECK:
 	case PTHREAD_MUTEX_NORMAL:
 		ret = EBUSY; 
@@ -900,15 +572,14 @@
 }
 
 static int
-mutex_self_lock(struct pthread *curthread, pthread_mutex_t m,
-	const struct timespec *abstime)
+mutex_self_lock(pthread_mutex_t m, const struct timespec *abstime)
 {
-	struct timespec ts1, ts2;
-	int ret;
+	struct timespec	ts1, ts2;
+	int	ret;
 
 	switch (m->m_type) {
-	/* case PTHREAD_MUTEX_DEFAULT: */
 	case PTHREAD_MUTEX_ERRORCHECK:
+	case PTHREAD_MUTEX_ADAPTIVE_NP:
 		if (abstime) {
 			clock_gettime(CLOCK_REALTIME, &ts1);
 			TIMESPEC_SUB(&ts2, abstime, &ts1);
@@ -929,10 +600,6 @@
 		 * deadlock on attempts to get a lock you already own.
 		 */
 		ret = 0;
-		if (m->m_protocol != PTHREAD_PRIO_NONE) {
-			/* Unlock the mutex structure: */
-			THR_LOCK_RELEASE(curthread, &m->m_lock);
-		}
 		if (abstime) {
 			clock_gettime(CLOCK_REALTIME, &ts1);
 			TIMESPEC_SUB(&ts2, abstime, &ts1);
@@ -964,529 +631,75 @@
 }
 
 static int
-mutex_unlock_common(pthread_mutex_t *m, int add_reference)
+mutex_unlock_common(pthread_mutex_t *mutex)
 {
 	struct pthread *curthread = _get_curthread();
-	long tid = -1;
-	int ret = 0;
-
-	if (m == NULL || *m == NULL)
-		ret = EINVAL;
-	else {
-		/* Short cut for simple mutex. */
-
-		if ((*m)->m_protocol == PTHREAD_PRIO_NONE) {
-			/*
-			 * Check if the running thread is not the owner of the
-			 * mutex:
-			 */
-			if (__predict_false((*m)->m_owner != curthread)) {
-				ret = EPERM;
-			} else if (__predict_false(
-				  (*m)->m_type == PTHREAD_MUTEX_RECURSIVE &&
-			          (*m)->m_count > 0)) {
-				/* Decrement the count: */
-				(*m)->m_count--;
-				if (add_reference)
-					(*m)->m_refcount++;
-			} else {
-				/*
-				 * Clear the count in case this is a recursive
-				 * mutex.
-				 */
-				(*m)->m_count = 0;
-				(*m)->m_owner = NULL;
-				/* Remove the mutex from the threads queue. */
-				MUTEX_ASSERT_IS_OWNED(*m);
-				TAILQ_REMOVE(&curthread->mutexq, (*m), m_qe);
-				MUTEX_INIT_LINK(*m);
-				if (add_reference)
-					(*m)->m_refcount++;
-				/*
-				 * Hand off the mutex to the next waiting
-				 * thread.
-				 */
-				_thr_umtx_unlock(&(*m)->m_lock, curthread->tid);
-			}
-			return (ret);
-		}
-
-		/* Code for priority mutex */
-
-		/* Lock the mutex structure: */
-		THR_LOCK_ACQUIRE(curthread, &(*m)->m_lock);
-
-		/* Process according to mutex type: */
-		switch ((*m)->m_protocol) {
-		/* POSIX priority inheritence mutex: */
-		case PTHREAD_PRIO_INHERIT:
-			/*
-			 * Check if the running thread is not the owner of the
-			 * mutex:
-			 */
-			if ((*m)->m_owner != curthread)
-				ret = EPERM;
-			else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
-			    ((*m)->m_count > 0))
-				/* Decrement the count: */
-				(*m)->m_count--;
-			else {
-				/*
-				 * Clear the count in case this is recursive
-				 * mutex.
-				 */
-				(*m)->m_count = 0;
-
-				/*
-				 * Restore the threads inherited priority and
-				 * recompute the active priority (being careful
-				 * not to override changes in the threads base
-				 * priority subsequent to locking the mutex).
-				 */
-				THR_LOCK(curthread);
-				curthread->inherited_priority =
-					(*m)->m_saved_prio;
-				curthread->active_priority =
-				    MAX(curthread->inherited_priority,
-				    curthread->base_priority);
-
-				/*
-				 * This thread now owns one less priority mutex.
-				 */
-				curthread->priority_mutex_count--;
-				THR_UNLOCK(curthread);
-
-				/* Remove the mutex from the threads queue. */
-				MUTEX_ASSERT_IS_OWNED(*m);
-				TAILQ_REMOVE(&(*m)->m_owner->pri_mutexq,
-				    (*m), m_qe);
-				MUTEX_INIT_LINK(*m);
-
-				/*
-				 * Hand off the mutex to the next waiting
-				 * thread:
-				 */
-				tid = mutex_handoff(curthread, *m);
-			}
-			break;
-
-		/* POSIX priority ceiling mutex: */
-		case PTHREAD_PRIO_PROTECT:
-			/*
-			 * Check if the running thread is not the owner of the
-			 * mutex:
-			 */
-			if ((*m)->m_owner != curthread)
-				ret = EPERM;
-			else if (((*m)->m_type == PTHREAD_MUTEX_RECURSIVE) &&
-			    ((*m)->m_count > 0))
-				/* Decrement the count: */
-				(*m)->m_count--;
-			else {
-				/*
-				 * Clear the count in case this is a recursive
-				 * mutex.
-				 */
-				(*m)->m_count = 0;
-
-				/*
-				 * Restore the threads inherited priority and
-				 * recompute the active priority (being careful
-				 * not to override changes in the threads base
-				 * priority subsequent to locking the mutex).
-				 */
-				THR_LOCK(curthread);
-				curthread->inherited_priority =
-					(*m)->m_saved_prio;
-				curthread->active_priority =
-				    MAX(curthread->inherited_priority,
-				    curthread->base_priority);
-
-				/*
-				 * This thread now owns one less priority mutex.
-				 */
-				curthread->priority_mutex_count--;
-				THR_UNLOCK(curthread);
-
-				/* Remove the mutex from the threads queue. */
-				MUTEX_ASSERT_IS_OWNED(*m);
-				TAILQ_REMOVE(&(*m)->m_owner->pri_mutexq,
-				    (*m), m_qe);
-				MUTEX_INIT_LINK(*m);
-
-				/*
-				 * Hand off the mutex to the next waiting
-				 * thread:
-				 */
-				tid = mutex_handoff(curthread, *m);
-			}
-			break;
-
-		/* Trap invalid mutex types: */
-		default:
-			/* Return an invalid argument error: */
-			ret = EINVAL;
-			break;
-		}
-
-		if ((ret == 0) && (add_reference != 0))
-			/* Increment the reference count: */
-			(*m)->m_refcount++;
-
-		/* Unlock the mutex structure: */
-		THR_LOCK_RELEASE(curthread, &(*m)->m_lock);
-	}
-
-	/* Return the completion status: */
-	return (ret);
-}
-
-
-/*
- * This function is called when a change in base priority occurs for
- * a thread that is holding or waiting for a priority protection or
- * inheritence mutex.  A change in a threads base priority can effect
- * changes to active priorities of other threads and to the ordering
- * of mutex locking by waiting threads.
- *
- * This must be called without the target thread's scheduling lock held.
- */
-void
-_mutex_notify_priochange(struct pthread *curthread, struct pthread *pthread,
-    int propagate_prio)
-{
 	struct pthread_mutex *m;
+	uint32_t id;
 
-	/* Adjust the priorites of any owned priority mutexes: */
-	if (pthread->priority_mutex_count > 0) {
-		/*
-		 * Rescan the mutexes owned by this thread and correct
-		 * their priorities to account for this threads change
-		 * in priority.  This has the side effect of changing
-		 * the threads active priority.
-		 *
-		 * Be sure to lock the first mutex in the list of owned
-		 * mutexes.  This acts as a barrier against another
-		 * simultaneous call to change the threads priority
-		 * and from the owning thread releasing the mutex.
-		 */
-		m = TAILQ_FIRST(&pthread->pri_mutexq);
-		if (m != NULL) {
-			THR_LOCK_ACQUIRE(curthread, &m->m_lock);
-			/*
-			 * Make sure the thread still owns the lock.
-			 */
-			if (m == TAILQ_FIRST(&pthread->pri_mutexq))
-				mutex_rescan_owned(curthread, pthread,
-				    /* rescan all owned */ NULL);
-			THR_LOCK_RELEASE(curthread, &m->m_lock);
-		}
-	}
+	if (__predict_false((m = *mutex) == NULL))
+		return (EINVAL);
 
 	/*
-	 * If this thread is waiting on a priority inheritence mutex,
-	 * check for priority adjustments.  A change in priority can
-	 * also cause a ceiling violation(*) for a thread waiting on
-	 * a priority protection mutex; we don't perform the check here
-	 * as it is done in pthread_mutex_unlock.
-	 *
-	 * (*) It should be noted that a priority change to a thread
-	 *     _after_ taking and owning a priority ceiling mutex
-	 *     does not affect ownership of that mutex; the ceiling
-	 *     priority is only checked before mutex ownership occurs.
+	 * Check if the running thread is not the owner of the mutex.
 	 */
-	if (propagate_prio != 0) {
-		/*
-		 * Lock the thread's scheduling queue.  This is a bit
-		 * convoluted; the "in synchronization queue flag" can
-		 * only be cleared with both the thread's scheduling and
-		 * mutex locks held.  The thread's pointer to the wanted
-		 * mutex is guaranteed to be valid during this time.
-		 */
-		THR_THREAD_LOCK(curthread, pthread);
+	if (__predict_false(m->m_owner != curthread))
+		return (EPERM);
 
-		if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) == 0) ||
-		    ((m = pthread->data.mutex) == NULL))
-			THR_THREAD_UNLOCK(curthread, pthread);
+	id = TID(curthread);
+	if (__predict_false(
+		m->m_type == PTHREAD_MUTEX_RECURSIVE &&
+		m->m_count > 0)) {
+		m->m_count--;
+	} else {
+		m->m_owner = NULL;
+		/* Remove the mutex from the threads queue. */
+		MUTEX_ASSERT_IS_OWNED(m);
+		if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)
+			TAILQ_REMOVE(&curthread->mutexq, m, m_qe);
 		else {
-			/*
-			 * This thread is currently waiting on a mutex; unlock
-			 * the scheduling queue lock and lock the mutex.  We
-			 * can't hold both at the same time because the locking
-			 * order could cause a deadlock.
-			 */
-			THR_THREAD_UNLOCK(curthread, pthread);
-			THR_LOCK_ACQUIRE(curthread, &m->m_lock);
-
-			/*
-			 * Check to make sure this thread is still in the
-			 * same state (the lock above can yield the CPU to
-			 * another thread or the thread may be running on
-			 * another CPU).
-			 */
-			if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) &&
-			    (pthread->data.mutex == m)) {
-				/*
-				 * Remove and reinsert this thread into
-				 * the list of waiting threads to preserve
-				 * decreasing priority order.
-				 */
-				mutex_queue_remove(m, pthread);
-				mutex_queue_enq(m, pthread);
-
-				if (m->m_protocol == PTHREAD_PRIO_INHERIT)
-					/* Adjust priorities: */
-					mutex_priority_adjust(curthread, m);
-			}
-
-			/* Unlock the mutex structure: */
-			THR_LOCK_RELEASE(curthread, &m->m_lock);
+			TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe);
+			set_inherited_priority(curthread, m);
 		}
+		MUTEX_INIT_LINK(m);
+		_thr_umutex_unlock(&m->m_lock, id);
 	}
+	return (0);
 }
 
-/*
- * Called when a new thread is added to the mutex waiting queue or
- * when a threads priority changes that is already in the mutex
- * waiting queue.
- *
- * This must be called with the mutex locked by the current thread.
- */
-static void
-mutex_priority_adjust(struct pthread *curthread, pthread_mutex_t mutex)
+int
+_mutex_cv_unlock(pthread_mutex_t *mutex, int *count)
 {
-	pthread_mutex_t	m = mutex;
-	struct pthread	*pthread_next, *pthread = mutex->m_owner;
-	int		done, temp_prio;
-
-	/*
-	 * Calculate the mutex priority as the maximum of the highest
-	 * active priority of any waiting threads and the owning threads
-	 * active priority(*).
-	 *
-	 * (*) Because the owning threads current active priority may
-	 *     reflect priority inherited from this mutex (and the mutex
-	 *     priority may have changed) we must recalculate the active
-	 *     priority based on the threads saved inherited priority
-	 *     and its base priority.
-	 */
-	pthread_next = TAILQ_FIRST(&m->m_queue);  /* should never be NULL */
-	temp_prio = MAX(pthread_next->active_priority,
-	    MAX(m->m_saved_prio, pthread->base_priority));
-
-	/* See if this mutex really needs adjusting: */
-	if (temp_prio == m->m_prio)
-		/* No need to propagate the priority: */
-		return;
+	struct pthread *curthread = _get_curthread();
+	struct pthread_mutex *m;
 
-	/* Set new priority of the mutex: */
-	m->m_prio = temp_prio;
+	if (__predict_false((m = *mutex) == NULL))
+		return (EINVAL);
 
 	/*
-	 * Don't unlock the mutex passed in as an argument.  It is
-	 * expected to be locked and unlocked by the caller.
+	 * Check if the running thread is not the owner of the mutex.
 	 */
-	done = 1;
-	do {
-		/*
-		 * Save the threads priority before rescanning the
-		 * owned mutexes:
-		 */
-		temp_prio = pthread->active_priority;
-
-		/*
-		 * Fix the priorities for all mutexes held by the owning
-		 * thread since taking this mutex.  This also has a
-		 * potential side-effect of changing the threads priority.
-		 *
-		 * At this point the mutex is locked by the current thread.
-		 * The owning thread can't release the mutex until it is
-		 * unlocked, so we should be able to safely walk its list
-		 * of owned mutexes.
-		 */
-		mutex_rescan_owned(curthread, pthread, m);
-
-		/*
-		 * If this isn't the first time through the loop,
-		 * the current mutex needs to be unlocked.
-		 */
-		if (done == 0)
-			THR_LOCK_RELEASE(curthread, &m->m_lock);
-
-		/* Assume we're done unless told otherwise: */
-		done = 1;
-
-		/*
-		 * If the thread is currently waiting on a mutex, check
-		 * to see if the threads new priority has affected the
-		 * priority of the mutex.
-		 */
-		if ((temp_prio != pthread->active_priority) &&
-		    ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) &&
-		    ((m = pthread->data.mutex) != NULL) &&
-		    (m->m_protocol == PTHREAD_PRIO_INHERIT)) {
-			/* Lock the mutex structure: */
-			THR_LOCK_ACQUIRE(curthread, &m->m_lock);
-
-			/*
-			 * Make sure the thread is still waiting on the
-			 * mutex:
-			 */
-			if (((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) &&
-			    (m == pthread->data.mutex)) {
-				/*
-				 * The priority for this thread has changed.
-				 * Remove and reinsert this thread into the
-				 * list of waiting threads to preserve
-				 * decreasing priority order.
-				 */
-				mutex_queue_remove(m, pthread);
-				mutex_queue_enq(m, pthread);
-
-				/*
-				 * Grab the waiting thread with highest
-				 * priority:
-				 */
-				pthread_next = TAILQ_FIRST(&m->m_queue);
-
-				/*
-				 * Calculate the mutex priority as the maximum
-				 * of the highest active priority of any
-				 * waiting threads and the owning threads
-				 * active priority.
-				 */
-				temp_prio = MAX(pthread_next->active_priority,
-				    MAX(m->m_saved_prio,
-				    m->m_owner->base_priority));
-
-				if (temp_prio != m->m_prio) {
-					/*
-					 * The priority needs to be propagated
-					 * to the mutex this thread is waiting
-					 * on and up to the owner of that mutex.
-					 */
-					m->m_prio = temp_prio;
-					pthread = m->m_owner;
-
-					/* We're not done yet: */
-					done = 0;
-				}
-			}
-			/* Only release the mutex if we're done: */
-			if (done != 0)
-				THR_LOCK_RELEASE(curthread, &m->m_lock);
-		}
-	} while (done == 0);
-}
-
-static void
-mutex_rescan_owned(struct pthread *curthread, struct pthread *pthread,
-    struct pthread_mutex *mutex)
-{
-	struct pthread_mutex	*m;
-	struct pthread		*pthread_next;
-	int			active_prio, inherited_prio;
+	if (__predict_false(m->m_owner != curthread))
+		return (EPERM);
 
 	/*
-	 * Start walking the mutexes the thread has taken since
-	 * taking this mutex.
+	 * Clear the count in case this is a recursive mutex.
 	 */
-	if (mutex == NULL) {
-		/*
-		 * A null mutex means start at the beginning of the owned
-		 * mutex list.
-		 */
-		m = TAILQ_FIRST(&pthread->pri_mutexq);
-
-		/* There is no inherited priority yet. */
-		inherited_prio = 0;
-	} else {
-		/*
-		 * The caller wants to start after a specific mutex.  It
-		 * is assumed that this mutex is a priority inheritence
-		 * mutex and that its priority has been correctly
-		 * calculated.
-		 */
-		m = TAILQ_NEXT(mutex, m_qe);
-
-		/* Start inheriting priority from the specified mutex. */
-		inherited_prio = mutex->m_prio;
-	}
-	active_prio = MAX(inherited_prio, pthread->base_priority);
-
-	for (; m != NULL; m = TAILQ_NEXT(m, m_qe)) {
-		/*
-		 * We only want to deal with priority inheritence
-		 * mutexes.  This might be optimized by only placing
-		 * priority inheritence mutexes into the owned mutex
-		 * list, but it may prove to be useful having all
-		 * owned mutexes in this list.  Consider a thread
-		 * exiting while holding mutexes...
-		 */
-		if (m->m_protocol == PTHREAD_PRIO_INHERIT) {
-			/*
-			 * Fix the owners saved (inherited) priority to
-			 * reflect the priority of the previous mutex.
-			 */
-			m->m_saved_prio = inherited_prio;
-
-			if ((pthread_next = TAILQ_FIRST(&m->m_queue)) != NULL)
-				/* Recalculate the priority of the mutex: */
-				m->m_prio = MAX(active_prio,
-				     pthread_next->active_priority);
-			else
-				m->m_prio = active_prio;
-
-			/* Recalculate new inherited and active priorities: */
-			inherited_prio = m->m_prio;
-			active_prio = MAX(m->m_prio, pthread->base_priority);
-		}
-	}
-
-	/*
-	 * Fix the threads inherited priority and recalculate its
-	 * active priority.
-	 */
-	pthread->inherited_priority = inherited_prio;
-	active_prio = MAX(inherited_prio, pthread->base_priority);
-
-	if (active_prio != pthread->active_priority) {
-		/* Lock the thread's scheduling queue: */
-		THR_THREAD_LOCK(curthread, pthread);
-
-		/* if ((pthread->flags & THR_FLAGS_IN_RUNQ) == 0) */
-		if (1) {
-			/*
-			 * This thread is not in a run queue.  Just set
-			 * its active priority.
-			 */
-			pthread->active_priority = active_prio;
-		}
-		else {
-			/*
-			 * This thread is in a run queue.  Remove it from
-			 * the queue before changing its priority:
-			 */
-			/* THR_RUNQ_REMOVE(pthread);*/
-			/*
-			 * POSIX states that if the priority is being
-			 * lowered, the thread must be inserted at the
-			 * head of the queue for its priority if it owns
-			 * any priority protection or inheritence mutexes.
-			 */
-			if ((active_prio < pthread->active_priority) &&
-			    (pthread->priority_mutex_count > 0)) {
-				/* Set the new active priority. */
-				pthread->active_priority = active_prio;
-				/* THR_RUNQ_INSERT_HEAD(pthread); */
-			} else {
-				/* Set the new active priority. */
-				pthread->active_priority = active_prio;
-				/* THR_RUNQ_INSERT_TAIL(pthread);*/
-			}
-		}
-		THR_THREAD_UNLOCK(curthread, pthread);
+	*count = m->m_count;
+	m->m_refcount++;
+	m->m_count = 0;
+	m->m_owner = NULL;
+	/* Remove the mutex from the threads queue. */
+	MUTEX_ASSERT_IS_OWNED(m);
+	if ((m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)
+		TAILQ_REMOVE(&curthread->mutexq, m, m_qe);
+	else {
+		TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe);
+		set_inherited_priority(curthread, m);
 	}
+	MUTEX_INIT_LINK(m);
+	_thr_umutex_unlock(&m->m_lock, TID(curthread));
+	return (0);
 }
 
 void
@@ -1494,194 +707,61 @@
 {
 	struct pthread_mutex	*m, *m_next;
 
-	for (m = TAILQ_FIRST(&pthread->pri_mutexq); m != NULL; m = m_next) {
-		m_next = TAILQ_NEXT(m, m_qe);
+	TAILQ_FOREACH_SAFE(m, &pthread->mutexq, m_qe, m_next) {
 		if ((m->m_flags & MUTEX_FLAGS_PRIVATE) != 0)
-			pthread_mutex_unlock(&m);
+			_pthread_mutex_unlock(&m);
 	}
 }
 
-/*
- * Dequeue a waiting thread from the head of a mutex queue in descending
- * priority order.
- *
- * In order to properly dequeue a thread from the mutex queue and
- * make it runnable without the possibility of errant wakeups, it
- * is necessary to lock the thread's scheduling queue while also
- * holding the mutex lock.
- */
-static long
-mutex_handoff(struct pthread *curthread, struct pthread_mutex *mutex)
+int
+_pthread_mutex_getprioceiling(pthread_mutex_t *mutex,
+			      int *prioceiling)
 {
-	struct pthread *pthread;
-	long tid = -1;
-
-	/* Keep dequeueing until we find a valid thread: */
-	mutex->m_owner = NULL;
-	pthread = TAILQ_FIRST(&mutex->m_queue);
-	while (pthread != NULL) {
-		/* Take the thread's scheduling lock: */
-		THR_THREAD_LOCK(curthread, pthread);
-
-		/* Remove the thread from the mutex queue: */
-		TAILQ_REMOVE(&mutex->m_queue, pthread, sqe);
-		pthread->sflags &= ~THR_FLAGS_IN_SYNCQ;
-
-		/*
-		 * Only exit the loop if the thread hasn't been
-		 * cancelled.
-		 */
-		switch (mutex->m_protocol) {
-		case PTHREAD_PRIO_NONE:
-			/*
-			 * Assign the new owner and add the mutex to the
-			 * thread's list of owned mutexes.
-			 */
-			mutex->m_owner = pthread;
-			TAILQ_INSERT_TAIL(&pthread->pri_mutexq, mutex, m_qe);
-			break;
-
-		case PTHREAD_PRIO_INHERIT:
-			/*
-			 * Assign the new owner and add the mutex to the
-			 * thread's list of owned mutexes.
-			 */
-			mutex->m_owner = pthread;
-			TAILQ_INSERT_TAIL(&pthread->pri_mutexq, mutex, m_qe);
-
-			/* Track number of priority mutexes owned: */
-			pthread->priority_mutex_count++;
-
-			/*
-			 * Set the priority of the mutex.  Since our waiting
-			 * threads are in descending priority order, the
-			 * priority of the mutex becomes the active priority
-			 * of the thread we just dequeued.
-			 */
-			mutex->m_prio = pthread->active_priority;
-
-			/* Save the owning threads inherited priority: */
-			mutex->m_saved_prio = pthread->inherited_priority;
-
-			/*
-			 * The owning threads inherited priority now becomes
-			 * his active priority (the priority of the mutex).
-			 */
-			pthread->inherited_priority = mutex->m_prio;
-			break;
-
-		case PTHREAD_PRIO_PROTECT:
-			if (pthread->active_priority > mutex->m_prio) {
-				/*
-				 * Either the mutex ceiling priority has
-				 * been lowered and/or this threads priority
-			 	 * has been raised subsequent to the thread
-				 * being queued on the waiting list.
-				 */
-				pthread->error = EINVAL;
-			}
-			else {
-				/*
-				 * Assign the new owner and add the mutex
-				 * to the thread's list of owned mutexes.
-				 */
-				mutex->m_owner = pthread;
-				TAILQ_INSERT_TAIL(&pthread->pri_mutexq,
-				    mutex, m_qe);
-
-				/* Track number of priority mutexes owned: */
-				pthread->priority_mutex_count++;
-
-				/*
-				 * Save the owning threads inherited
-				 * priority:
-				 */
-				mutex->m_saved_prio =
-				    pthread->inherited_priority;
-
-				/*
-				 * The owning thread inherits the ceiling
-				 * priority of the mutex and executes at
-				 * that priority:
-				 */
-				pthread->inherited_priority = mutex->m_prio;
-				pthread->active_priority = mutex->m_prio;
-
-			}
-			break;
-		}
+	int ret;
 
-		/* Make the thread runnable and unlock the scheduling queue: */
-		pthread->cycle++;
-		_thr_umtx_wake(&pthread->cycle, 1);
-
-		THR_THREAD_UNLOCK(curthread, pthread);
-		if (mutex->m_owner == pthread)
-			/* We're done; a valid owner was found. */
-			break;
-		else
-			/* Get the next thread from the waiting queue: */
-			pthread = TAILQ_NEXT(pthread, sqe);
+	if (*mutex == NULL)
+		ret = EINVAL;
+	else if (((*mutex)->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)
+		ret = EINVAL;
+	else {
+		*prioceiling = (*mutex)->m_lock.m_ceilings[0];
+		ret = 0;
 	}
 
-	if ((pthread == NULL) && (mutex->m_protocol == PTHREAD_PRIO_INHERIT))
-		/* This mutex has no priority: */
-		mutex->m_prio = 0;
-	return (tid);
+	return(ret);
 }
 
-#if 0
-/*
- * Dequeue a waiting thread from the head of a mutex queue in descending
- * priority order.
- */
-static pthread_t
-mutex_queue_deq(struct pthread_mutex *mutex)
+int
+_pthread_mutex_setprioceiling(pthread_mutex_t *mutex,
+			      int ceiling, int *old_ceiling)
 {
-	pthread_t pthread;
-
-	while ((pthread = TAILQ_FIRST(&mutex->m_queue)) != NULL) {
-		TAILQ_REMOVE(&mutex->m_queue, pthread, sqe);
-		pthread->sflags &= ~THR_FLAGS_IN_SYNCQ;
-	}
-
-	return (pthread);
-}
-#endif
+	struct pthread *curthread = _get_curthread();
+	struct pthread_mutex *m, *m1, *m2;
+	int ret;
 
-/*
- * Remove a waiting thread from a mutex queue in descending priority order.
- */
-static void
-mutex_queue_remove(pthread_mutex_t mutex, pthread_t pthread)
-{
-	if ((pthread->sflags & THR_FLAGS_IN_SYNCQ) != 0) {
-		TAILQ_REMOVE(&mutex->m_queue, pthread, sqe);
-		pthread->sflags &= ~THR_FLAGS_IN_SYNCQ;
-	}
-}
+	m = *mutex;
+	if (m == NULL || (m->m_lock.m_flags & UMUTEX_PRIO_PROTECT) == 0)
+		return (EINVAL);
 
-/*
- * Enqueue a waiting thread to a queue in descending priority order.
- */
-static void
-mutex_queue_enq(pthread_mutex_t mutex, pthread_t pthread)
-{
-	pthread_t tid = TAILQ_LAST(&mutex->m_queue, mutex_head);
+	ret = __thr_umutex_set_ceiling(&m->m_lock, ceiling, old_ceiling);
+	if (ret != 0)
+		return (ret);
 
-	THR_ASSERT_NOT_IN_SYNCQ(pthread);
-	/*
-	 * For the common case of all threads having equal priority,
-	 * we perform a quick check against the priority of the thread
-	 * at the tail of the queue.
-	 */
-	if ((tid == NULL) || (pthread->active_priority <= tid->active_priority))
-		TAILQ_INSERT_TAIL(&mutex->m_queue, pthread, sqe);
-	else {
-		tid = TAILQ_FIRST(&mutex->m_queue);
-		while (pthread->active_priority <= tid->active_priority)
-			tid = TAILQ_NEXT(tid, sqe);
-		TAILQ_INSERT_BEFORE(tid, pthread, sqe);
+	if (m->m_owner == curthread) {
+		MUTEX_ASSERT_IS_OWNED(m);
+		m1 = TAILQ_PREV(m, mutex_queue, m_qe);
+		m2 = TAILQ_NEXT(m, m_qe);
+		if ((m1 != NULL && m1->m_lock.m_ceilings[0] > ceiling) ||
+		    (m2 != NULL && m2->m_lock.m_ceilings[0] < ceiling)) {
+			TAILQ_REMOVE(&curthread->pp_mutexq, m, m_qe);
+			TAILQ_FOREACH(m2, &curthread->pp_mutexq, m_qe) {
+				if (m2->m_lock.m_ceilings[0] > ceiling) {
+					TAILQ_INSERT_BEFORE(m2, m, m_qe);
+					return (0);
+				}
+			}
+			TAILQ_INSERT_TAIL(&curthread->pp_mutexq, m, m_qe);
+		}
 	}
-	pthread->sflags |= THR_FLAGS_IN_SYNCQ;
+	return (0);
 }
Index: thr_multi_np.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_multi_np.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_multi_np.c -L lib/libthr/thread/thr_multi_np.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_multi_np.c
+++ lib/libthr/thread/thr_multi_np.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,10 +26,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_multi_np.c,v 1.1 2003/04/01 03:46:29 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_multi_np.c,v 1.3 2007/01/12 07:26:20 imp Exp $
  */
+
+#include "namespace.h"
 #include <pthread.h>
 #include <pthread_np.h>
+#include "un-namespace.h"
 
 __weak_reference(_pthread_multi_np, pthread_multi_np);
 
@@ -45,6 +45,6 @@
 	 * XXX - Do we want to do this?
 	 * __is_threaded = 1;
 	 */
-	pthread_resume_all_np();
+	_pthread_resume_all_np();
 	return (0);
 }
Index: thr_info.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_info.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L lib/libthr/thread/thr_info.c -L lib/libthr/thread/thr_info.c -u -r1.2 -r1.3
--- lib/libthr/thread/thr_info.c
+++ lib/libthr/thread/thr_info.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,13 +26,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $MidnightBSD$
- * $FreeBSD: src/lib/libthr/thread/thr_info.c,v 1.4.2.2 2006/01/24 02:04:21 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_info.c,v 1.10 2007/04/05 07:20:31 davidxu Exp $
  */
 
-#include <stdio.h>
+#include "namespace.h"
 #include <stdlib.h>
 #include <string.h>
+#include <pthread.h>
+#include <pthread_np.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -43,20 +42,29 @@
 
 /* Set the thread name for debug. */
 void
-_pthread_set_name_np(pthread_t thread, char *name)
+_pthread_set_name_np(pthread_t thread, const char *name)
 {
-#if 0
 	struct pthread *curthread = _get_curthread();
+	int ret = 0;
 
-	if (thread != NULL && thread->magic == THR_MAGIC) {
-		THR_THREAD_LOCK(curthread, thread);
-		if (thread->name != NULL) {
-			free(thread->name);
-			thread->name = NULL;
+	if (curthread == thread) {
+		if (thr_set_name(thread->tid, name))
+			ret = errno;
+	} else {
+		if (_thr_ref_add(curthread, thread, 0) == 0) {
+			THR_THREAD_LOCK(curthread, thread);
+			if (thread->state != PS_DEAD) {
+				if (thr_set_name(thread->tid, name))
+					ret = errno;
+			}
+			THR_THREAD_UNLOCK(curthread, thread);
+			_thr_ref_delete(curthread, thread);
+		} else {
+			ret = ESRCH;
 		}
-		if (name != NULL)
-			thread->name = strdup(name);
-		THR_THREAD_UNLOCK(curthread, thread);
 	}
+#if 0
+	/* XXX should return error code. */
+	return (ret);
 #endif
 }
Index: thr_switch_np.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_switch_np.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_switch_np.c -L lib/libthr/thread/thr_switch_np.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_switch_np.c
+++ lib/libthr/thread/thr_switch_np.c
@@ -29,12 +29,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_switch_np.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_switch_np.c,v 1.2 2006/04/04 02:57:49 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
 #include <pthread_np.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -43,13 +45,13 @@
 __weak_reference(_pthread_switch_delete_np, pthread_switch_delete_np);
 
 int
-_pthread_switch_add_np(pthread_switch_routine_t routine)
+_pthread_switch_add_np(pthread_switch_routine_t routine __unused)
 {
 	return (ENOTSUP);
 }
 
 int
-_pthread_switch_delete_np(pthread_switch_routine_t routine)
+_pthread_switch_delete_np(pthread_switch_routine_t routine __unused)
 {
 	return (ENOTSUP);
 }
Index: thr_kill.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_kill.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_kill.c -L lib/libthr/thread/thr_kill.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_kill.c
+++ lib/libthr/thread/thr_kill.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,12 +26,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_kill.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_kill.c,v 1.3 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <signal.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
--- lib/libthr/thread/thr_mutex_protocol.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (c) 1998 Daniel Eischen <eischen at vigrid.com>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by Daniel Eischen.
- * 4. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY DANIEL EISCHEN AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libthr/thread/thr_mutex_protocol.c,v 1.3 2005/04/02 01:20:00 davidxu Exp $
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <pthread.h>
-#include "thr_private.h"
-
-__weak_reference(_pthread_mutexattr_getprotocol, pthread_mutexattr_getprotocol);
-__weak_reference(_pthread_mutexattr_setprotocol, pthread_mutexattr_setprotocol);
-
-int
-_pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol)
-{
-	int ret = 0;
-
-	if ((mattr == NULL) || (*mattr == NULL))
-		ret = EINVAL;
-	else
-		*protocol = (*mattr)->m_protocol;
-
-	return(ret);
-}
-
-int
-_pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol)
-{
-	int ret = 0;
-
-	if ((mattr == NULL) || (*mattr == NULL) ||
-	    (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT))
-		ret = EINVAL;
-	else {
-		(*mattr)->m_protocol = protocol;
-		(*mattr)->m_ceiling = THR_MAX_PRIORITY;
-	}
-	return(ret);
-}
-
--- lib/libthr/thread/thr_sigmask.c
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (c) 1997 John Birrell <jb at cimlogic.com.au>.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY JOHN BIRRELL AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/lib/libthr/thread/thr_sigmask.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
- */
-
-#include <errno.h>
-#include <signal.h>
-#include <pthread.h>
-#include "thr_private.h"
-
-__weak_reference(_pthread_sigmask, pthread_sigmask);
-
-extern int
-_sigprocmask(int how, const sigset_t *set, sigset_t *oset);
-
-int
-_pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
-{
-	/* use our overridden verion of _sigprocmask */
-	if (_sigprocmask(how, set, oset))
-		return (errno);
-	return (0);
-}
Index: thr_self.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_self.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_self.c -L lib/libthr/thread/thr_self.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_self.c
+++ lib/libthr/thread/thr_self.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,10 +26,12 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_self.c,v 1.3 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_self.c,v 1.5 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_concurrency.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_concurrency.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_concurrency.c -L lib/libthr/thread/thr_concurrency.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_concurrency.c
+++ lib/libthr/thread/thr_concurrency.c
@@ -29,11 +29,13 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_concurrency.c,v 1.2 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_concurrency.c,v 1.3 2006/04/04 02:57:49 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_syscalls.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_syscalls.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L lib/libthr/thread/thr_syscalls.c -L lib/libthr/thread/thr_syscalls.c -u -r1.2 -r1.3
--- lib/libthr/thread/thr_syscalls.c
+++ lib/libthr/thread/thr_syscalls.c
@@ -28,7 +28,7 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
  * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_syscalls.c,v 1.9.2.2 2005/12/01 00:49:45 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_syscalls.c,v 1.16 2007/01/12 07:26:21 imp Exp $
  */
 
 /*
@@ -43,10 +43,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -64,6 +61,7 @@
  *
  */
 
+#include "namespace.h"
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <sys/param.h>
@@ -87,50 +85,100 @@
 #include <termios.h>
 #include <unistd.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
-extern int __creat(const char *, mode_t);
-extern int __pause(void);
-extern int __pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds,
-		const struct timespec *timo, const sigset_t *mask);
-extern unsigned int __sleep(unsigned int);
-extern int __system(const char *);
-extern int __tcdrain(int);
-extern int __usleep(useconds_t);
-extern pid_t __wait(int *);
-extern pid_t __sys_wait4(pid_t, int *, int, struct rusage *);
-extern pid_t __waitpid(pid_t, int *, int);
+extern int	__creat(const char *, mode_t);
+extern int	__pselect(int, fd_set *, fd_set *, fd_set *,
+			const struct timespec *, const sigset_t *);
+extern unsigned	__sleep(unsigned int);
+extern int	__system(const char *);
+extern int	__tcdrain(int);
+extern int	__usleep(useconds_t);
+extern pid_t	__wait(int *);
+extern pid_t	__waitpid(pid_t, int *, int);
+extern int	__sys_aio_suspend(const struct aiocb * const[], int,
+			const struct timespec *);
+extern int	__sys_accept(int, struct sockaddr *, socklen_t *);
+extern int	__sys_connect(int, const struct sockaddr *, socklen_t);
+extern int	__sys_fsync(int);
+extern int	__sys_msync(void *, size_t, int);
+extern int	__sys_poll(struct pollfd *, unsigned, int);
+extern ssize_t	__sys_recv(int, void *, size_t, int);
+extern ssize_t	__sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
+extern ssize_t	__sys_recvmsg(int, struct msghdr *, int);
+extern int	__sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+extern int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
+			off_t *, int);
+extern ssize_t	__sys_sendmsg(int, const struct msghdr *, int);
+extern ssize_t	__sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
+extern ssize_t	__sys_readv(int, const struct iovec *, int);
+extern pid_t	__sys_wait4(pid_t, int *, int, struct rusage *);
+extern ssize_t	__sys_writev(int, const struct iovec *, int);
+
+int	___creat(const char *, mode_t);
+int	___pselect(int, fd_set *, fd_set *, fd_set *, 
+		const struct timespec *, const sigset_t *);
+unsigned	___sleep(unsigned);
+int	___system(const char *);
+int	___tcdrain(int);
+int	___usleep(useconds_t useconds);
+pid_t	___wait(int *);
+pid_t	___waitpid(pid_t, int *, int);
+int	__accept(int, struct sockaddr *, socklen_t *);
+int	__aio_suspend(const struct aiocb * const iocbs[], int,
+		const struct timespec *);
+int	__close(int);
+int	__connect(int, const struct sockaddr *, socklen_t);
+int	__fcntl(int, int,...);
+int	__fsync(int);
+int	__msync(void *, size_t, int);
+int	__nanosleep(const struct timespec *, struct timespec *);
+int	__open(const char *, int,...);
+int	__poll(struct pollfd *, unsigned int, int);
+ssize_t	__read(int, void *buf, size_t);
+ssize_t	__readv(int, const struct iovec *, int);
+ssize_t	__recvfrom(int, void *, size_t, int f, struct sockaddr *, socklen_t *);
+ssize_t	__recvmsg(int, struct msghdr *, int);
+int	__select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
+ssize_t	__sendmsg(int, const struct msghdr *, int);
+ssize_t	__sendto(int, const void *, size_t, int,
+		const struct sockaddr *, socklen_t);
+pid_t	__wait3(int *, int, struct rusage *);
+pid_t	__wait4(pid_t, int *, int, struct rusage *);
+ssize_t	__write(int, const void *, size_t);
+ssize_t	__writev(int, const struct iovec *, int);
+int	_vfork(void);
 
 __weak_reference(__accept, accept);
+
 int
 __accept(int s, struct sockaddr *addr, socklen_t *addrlen)
 {
 	struct pthread *curthread;
-	int oldcancel;
 	int ret;
 
 	curthread = _get_curthread();
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_accept(s, addr, addrlen);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
  	return (ret);
 }
 
-__weak_reference(_aio_suspend, aio_suspend);
+__weak_reference(__aio_suspend, aio_suspend);
 
 int
-_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
+__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
     timespec *timeout)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	int ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_aio_suspend(iocbs, niocb, timeout);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
@@ -141,13 +189,12 @@
 __close(int fd)
 {
 	struct pthread	*curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_close(fd);
-	_thr_cancel_leave(curthread, oldcancel);
-
+	_thr_cancel_leave(curthread);
+	
 	return (ret);
 }
 
@@ -157,12 +204,11 @@
 __connect(int fd, const struct sockaddr *name, socklen_t namelen)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	int ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_connect(fd, name, namelen);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
  	return (ret);
 }
@@ -173,12 +219,11 @@
 ___creat(const char *path, mode_t mode)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	int ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __creat(path, mode);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	
 	return ret;
 }
@@ -189,11 +234,10 @@
 __fcntl(int fd, int cmd,...)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 	va_list	ap;
 	
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 
 	va_start(ap, cmd);
 	switch (cmd) {
@@ -213,7 +257,7 @@
 	}
 	va_end(ap);
 
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
@@ -224,12 +268,11 @@
 __fsync(int fd)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_fsync(fd);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
@@ -240,12 +283,11 @@
 __msync(void *addr, size_t len, int flags)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_msync(addr, len, flags);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
@@ -257,12 +299,11 @@
     struct timespec *time_remaining)
 {
 	struct pthread *curthread = _get_curthread();
-	int		oldcancel;
 	int		ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_nanosleep(time_to_sleep, time_remaining);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
@@ -273,12 +314,11 @@
 __open(const char *path, int flags,...)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 	int	mode = 0;
 	va_list	ap;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	
 	/* Check if the file is being created: */
 	if (flags & O_CREAT) {
@@ -290,24 +330,8 @@
 	
 	ret = __sys_open(path, flags, mode);
 
-	_thr_cancel_leave(curthread, oldcancel);
-
-	return ret;
-}
-
-__weak_reference(_pause, pause);
-
-int
-_pause(void)
-{
-	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
-	int	ret;
+	_thr_cancel_leave(curthread);
 
-	oldcancel = _thr_cancel_enter(curthread);
-	ret = __pause();
-	_thr_cancel_leave(curthread, oldcancel);
-	
 	return ret;
 }
 
@@ -317,59 +341,42 @@
 __poll(struct pollfd *fds, unsigned int nfds, int timeout)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	int ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_poll(fds, nfds, timeout);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
 
-__weak_reference(_pselect, pselect);
+__weak_reference(___pselect, pselect);
 
 int 
-_pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, 
+___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, 
 	const struct timespec *timo, const sigset_t *mask)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	int ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __pselect(count, rfds, wfds, efds, timo, mask);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
 
-__weak_reference(_raise, raise);
-
-int
-_raise(int sig)
-{
-	int ret;
-
-	if (!_thr_isthreaded())
-		ret = kill(getpid(), sig);
-	else
-		ret = _thr_send_sig(_get_curthread(), sig);
-	return (ret);
-}
-
 __weak_reference(__read, read);
 
 ssize_t
 __read(int fd, void *buf, size_t nbytes)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	ssize_t	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_read(fd, buf, nbytes);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
@@ -380,12 +387,11 @@
 __readv(int fd, const struct iovec *iov, int iovcnt)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	ssize_t ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_readv(fd, iov, iovcnt);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
@@ -397,12 +403,11 @@
     socklen_t *fl)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	ssize_t ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_recvfrom(s, b, l, f, from, fl);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	return (ret);
 }
 
@@ -413,11 +418,10 @@
 {
 	struct pthread *curthread = _get_curthread();
 	ssize_t ret;
-	int oldcancel;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_recvmsg(s, m, f);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	return (ret);
 }
 
@@ -428,12 +432,11 @@
 	struct timeval *timeout)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	int ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	return ret;
 }
 
@@ -444,11 +447,10 @@
 {
 	struct pthread *curthread = _get_curthread();
 	ssize_t ret;
-	int oldcancel;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_sendmsg(s, m, f);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	return (ret);
 }
 
@@ -460,74 +462,69 @@
 {
 	struct pthread *curthread = _get_curthread();
 	ssize_t ret;
-	int oldcancel;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_sendto(s, m, l, f, t, tl);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	return (ret);
 }
 
-__weak_reference(_sleep, sleep);
+__weak_reference(___sleep, sleep);
 
 unsigned int
-_sleep(unsigned int seconds)
+___sleep(unsigned int seconds)
 {
 	struct pthread *curthread = _get_curthread();
-	int		oldcancel;
 	unsigned int	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sleep(seconds);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	
 	return (ret);
 }
 
-__weak_reference(_system, system);
+__weak_reference(___system, system);
 
 int
-_system(const char *string)
+___system(const char *string)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __system(string);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	
 	return ret;
 }
 
-__weak_reference(_tcdrain, tcdrain);
+__weak_reference(___tcdrain, tcdrain);
 
 int
-_tcdrain(int fd)
+___tcdrain(int fd)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	int	ret;
 	
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __tcdrain(fd);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
 
-__weak_reference(_usleep, usleep);
+__weak_reference(___usleep, usleep);
 
 int
-_usleep(useconds_t useconds)
+___usleep(useconds_t useconds)
 {
 	struct pthread *curthread = _get_curthread();
-	int		oldcancel;
 	int		ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __usleep(useconds);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	
 	return (ret);
 }
@@ -540,50 +537,62 @@
 	return (fork());
 }
 
-__weak_reference(_wait, wait);
+__weak_reference(___wait, wait);
 
 pid_t
-_wait(int *istat)
+___wait(int *istat)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	pid_t	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __wait(istat);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
 
+__weak_reference(__wait3, wait3);
+
+pid_t
+__wait3(int *status, int options, struct rusage *rusage)
+{
+	struct pthread *curthread = _get_curthread();
+	pid_t ret;
+
+	_thr_cancel_enter(curthread);
+	ret = _wait4(WAIT_ANY, status, options, rusage);
+	_thr_cancel_leave(curthread);
+
+	return (ret);
+}
+
 __weak_reference(__wait4, wait4);
 
 pid_t
-__wait4(pid_t pid, int *istat, int options, struct rusage *rusage)
+__wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldcancel;
 	pid_t ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
-	ret = __sys_wait4(pid, istat, options, rusage);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_enter(curthread);
+	ret = __sys_wait4(pid, status, options, rusage);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
 
-__weak_reference(_waitpid, waitpid);
+__weak_reference(___waitpid, waitpid);
 
 pid_t
-_waitpid(pid_t wpid, int *status, int options)
+___waitpid(pid_t wpid, int *status, int options)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	pid_t	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __waitpid(wpid, status, options);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	
 	return ret;
 }
@@ -594,12 +603,11 @@
 __write(int fd, const void *buf, size_t nbytes)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	ssize_t	ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_write(fd, buf, nbytes);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
@@ -610,12 +618,11 @@
 __writev(int fd, const struct iovec *iov, int iovcnt)
 {
 	struct pthread *curthread = _get_curthread();
-	int	oldcancel;
 	ssize_t ret;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_writev(fd, iov, iovcnt);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return ret;
 }
Index: thr_cond.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_cond.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_cond.c -L lib/libthr/thread/thr_cond.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_cond.c
+++ lib/libthr/thread/thr_cond.c
@@ -23,20 +23,25 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_cond.c,v 1.16 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_cond.c,v 1.23 2006/12/12 03:08:49 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
 #include <pthread.h>
 #include <limits.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
 /*
  * Prototypes
  */
+int	__pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
+int	__pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
+		       const struct timespec * abstime);
 static int cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
 static int cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex,
 		    const struct timespec *abstime, int cancel);
@@ -62,16 +67,12 @@
 	int             rval = 0;
 
 	if ((pcond = (pthread_cond_t)
-	    malloc(sizeof(struct pthread_cond))) == NULL) {
+	    calloc(1, sizeof(struct pthread_cond))) == NULL) {
 		rval = ENOMEM;
 	} else {
 		/*
 		 * Initialise the condition variable structure:
 		 */
-		_thr_umtx_init(&pcond->c_lock);
-		pcond->c_seqno = 0;
-		pcond->c_waiters = 0;
-		pcond->c_wakeups = 0;
 		if (cond_attr == NULL || *cond_attr == NULL) {
 			pcond->c_pshared = 0;
 			pcond->c_clockid = CLOCK_REALTIME;
@@ -79,6 +80,7 @@
 			pcond->c_pshared = (*cond_attr)->c_pshared;
 			pcond->c_clockid = (*cond_attr)->c_clockid;
 		}
+		_thr_umutex_init(&pcond->c_lock);
 		*cond = pcond;
 	}
 	/* Return the completion status: */
@@ -113,38 +115,27 @@
 int
 _pthread_cond_destroy(pthread_cond_t *cond)
 {
-	struct pthread_cond	*cv;
 	struct pthread		*curthread = _get_curthread();
+	struct pthread_cond	*cv;
 	int			rval = 0;
 
 	if (*cond == NULL)
 		rval = EINVAL;
 	else {
-		/* Lock the condition variable structure: */
-		THR_LOCK_ACQUIRE(curthread, &(*cond)->c_lock);
-		if ((*cond)->c_waiters + (*cond)->c_wakeups != 0) {
-			THR_LOCK_RELEASE(curthread, &(*cond)->c_lock);
-			return (EBUSY);
-		}
-
+		cv = *cond;
+		THR_UMUTEX_LOCK(curthread, &cv->c_lock);
 		/*
 		 * NULL the caller's pointer now that the condition
 		 * variable has been destroyed:
 		 */
-		cv = *cond;
 		*cond = NULL;
-
-		/* Unlock the condition variable structure: */
-		THR_LOCK_RELEASE(curthread, &cv->c_lock);
-
-		/* Free the cond lock structure: */
+		THR_UMUTEX_UNLOCK(curthread, &cv->c_lock);
 
 		/*
 		 * Free the memory allocated for the condition
 		 * variable structure:
 		 */
 		free(cv);
-
 	}
 	/* Return the completion status: */
 	return (rval);
@@ -154,30 +145,21 @@
 {
 	pthread_mutex_t	*mutex;
 	pthread_cond_t	*cond;
-	long		seqno;
+	int		count;
 };
 
 static void
 cond_cancel_handler(void *arg)
 {
 	struct pthread *curthread = _get_curthread();
-	struct cond_cancel_info *cci = (struct cond_cancel_info *)arg;
-	pthread_cond_t cv;
+	struct cond_cancel_info *info = (struct cond_cancel_info *)arg;
+	pthread_cond_t  cv;
 
-	cv = *(cci->cond);
-	THR_LOCK_ACQUIRE(curthread, &cv->c_lock);
-	if (cv->c_seqno != cci->seqno && cv->c_wakeups != 0) {
-		if (cv->c_waiters > 0) {
-			cv->c_seqno++;
-			_thr_umtx_wake(&cv->c_seqno, 1);
-		} else
-			cv->c_wakeups--;
-	} else {
-		cv->c_waiters--;
+	if (info->cond != NULL) {
+		cv = *(info->cond);
+		THR_UMUTEX_UNLOCK(curthread, &cv->c_lock);
 	}
-	THR_LOCK_RELEASE(curthread, &cv->c_lock);
-
-	_mutex_cv_lock(cci->mutex);
+	_mutex_cv_lock(info->mutex, info->count);
 }
 
 static int
@@ -186,10 +168,8 @@
 {
 	struct pthread	*curthread = _get_curthread();
 	struct timespec ts, ts2, *tsp;
-	struct cond_cancel_info cci;
+	struct cond_cancel_info info;
 	pthread_cond_t  cv;
-	long		seq, oldseq;
-	int		oldcancel;
 	int		ret = 0;
 
 	/*
@@ -201,57 +181,36 @@
 		return (ret);
 
 	cv = *cond;
-	THR_LOCK_ACQUIRE(curthread, &cv->c_lock);
-	ret = _mutex_cv_unlock(mutex);
+	THR_UMUTEX_LOCK(curthread, &cv->c_lock);
+	ret = _mutex_cv_unlock(mutex, &info.count);
 	if (ret) {
-		THR_LOCK_RELEASE(curthread, &cv->c_lock);
+		THR_UMUTEX_UNLOCK(curthread, &cv->c_lock);
 		return (ret);
 	}
-	oldseq = seq = cv->c_seqno;
-	cci.mutex = mutex;
-	cci.cond  = cond;
-	cci.seqno = oldseq;
-
-	cv->c_waiters++;
-	do {
-		THR_LOCK_RELEASE(curthread, &cv->c_lock);
-
-		if (abstime != NULL) {
-			clock_gettime(cv->c_clockid, &ts);
-			TIMESPEC_SUB(&ts2, abstime, &ts);
-			tsp = &ts2;
-		} else
-			tsp = NULL;
-
-		if (cancel) {
-			THR_CLEANUP_PUSH(curthread, cond_cancel_handler, &cci);
-			oldcancel = _thr_cancel_enter(curthread);
-			ret = _thr_umtx_wait(&cv->c_seqno, seq, tsp);
-			_thr_cancel_leave(curthread, oldcancel);
-			THR_CLEANUP_POP(curthread, 0);
-		} else {
-			ret = _thr_umtx_wait(&cv->c_seqno, seq, tsp);
-		}
 
-		THR_LOCK_ACQUIRE(curthread, &cv->c_lock);
-		seq = cv->c_seqno;
-		if (abstime != NULL && ret == ETIMEDOUT)
-			break;
+	info.mutex = mutex;
+	info.cond  = cond;
 
-		/*
-		 * loop if we have never been told to wake up
-		 * or we lost a race.
-		 */
-	} while (seq == oldseq || cv->c_wakeups == 0);
-	
-	if (seq != oldseq && cv->c_wakeups != 0) {
-		cv->c_wakeups--;
-		ret = 0;
+	if (abstime != NULL) {
+		clock_gettime(cv->c_clockid, &ts);
+		TIMESPEC_SUB(&ts2, abstime, &ts);
+		tsp = &ts2;
+	} else
+		tsp = NULL;
+
+	if (cancel) {
+		THR_CLEANUP_PUSH(curthread, cond_cancel_handler, &info);
+		_thr_cancel_enter_defer(curthread);
+		ret = _thr_ucond_wait(&cv->c_kerncv, &cv->c_lock, tsp, 1);
+		info.cond = NULL;
+		_thr_cancel_leave_defer(curthread, ret);
+		THR_CLEANUP_POP(curthread, 0);
 	} else {
-		cv->c_waiters--;
+		ret = _thr_ucond_wait(&cv->c_kerncv, &cv->c_lock, tsp, 0);
 	}
-	THR_LOCK_RELEASE(curthread, &cv->c_lock);
-	_mutex_cv_lock(mutex);
+	if (ret == EINTR)
+		ret = 0;
+	_mutex_cv_lock(mutex, info.count);
 	return (ret);
 }
 
@@ -298,7 +257,7 @@
 {
 	struct pthread	*curthread = _get_curthread();
 	pthread_cond_t	cv;
-	int		ret = 0, oldwaiters;
+	int		ret = 0;
 
 	/*
 	 * If the condition variable is statically initialized, perform dynamic
@@ -309,23 +268,12 @@
 		return (ret);
 
 	cv = *cond;
-	/* Lock the condition variable structure. */
-	THR_LOCK_ACQUIRE(curthread, &cv->c_lock);
-	if (cv->c_waiters) {
-		if (!broadcast) {
-			cv->c_wakeups++;
-			cv->c_waiters--;
-			cv->c_seqno++;
-			_thr_umtx_wake(&cv->c_seqno, 1);
-		} else {
-			oldwaiters = cv->c_waiters;
-			cv->c_wakeups += cv->c_waiters;
-			cv->c_waiters = 0;
-			cv->c_seqno++;
-			_thr_umtx_wake(&cv->c_seqno, oldwaiters);
-		}
-	}
-	THR_LOCK_RELEASE(curthread, &cv->c_lock);
+	THR_UMUTEX_LOCK(curthread, &cv->c_lock);
+	if (!broadcast)
+		ret = _thr_ucond_signal(&cv->c_kerncv);
+	else
+		ret = _thr_ucond_broadcast(&cv->c_kerncv);
+	THR_UMUTEX_UNLOCK(curthread, &cv->c_lock);
 	return (ret);
 }
 
Index: thr_init.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_init.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_init.c -L lib/libthr/thread/thr_init.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_init.c
+++ lib/libthr/thread/thr_init.c
@@ -30,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_init.c,v 1.23.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_init.c,v 1.46.2.1 2007/11/14 01:10:12 kris Exp $
  */
 
 #include "namespace.h"
@@ -40,6 +40,7 @@
 #include <sys/sysctl.h>
 #include <sys/ttycom.h>
 #include <sys/mman.h>
+#include <sys/rtprio.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <paths.h>
@@ -55,9 +56,8 @@
 #include "libc_private.h"
 #include "thr_private.h"
 
-void		*_usrstack;
+char		*_usrstack;
 struct pthread	*_thr_initial;
-int		_thr_scope_system;
 int		_libthr_debug;
 int		_thread_event_mask;
 struct pthread	*_thread_last_event;
@@ -65,17 +65,20 @@
 pthreadlist 	_thread_gc_list = TAILQ_HEAD_INITIALIZER(_thread_gc_list);
 int		_thread_active_threads = 1;
 atfork_head	_thr_atfork_list = TAILQ_HEAD_INITIALIZER(_thr_atfork_list);
-umtx_t		_thr_atfork_lock;
+struct umutex	_thr_atfork_lock = DEFAULT_UMUTEX;
+
+struct pthread_prio	_thr_priorities[3] = {
+	{RTP_PRIO_MIN,  RTP_PRIO_MAX, 0}, /* FIFO */
+	{0, 0, 63}, /* OTHER */
+	{RTP_PRIO_MIN, RTP_PRIO_MAX, 0}  /* RR */
+};
 
 struct pthread_attr _pthread_attr_default = {
-	.sched_policy = SCHED_RR,
+	.sched_policy = SCHED_OTHER,
 	.sched_inherit = 0,
-	.sched_interval = TIMESLICE_USEC,
-	.prio = THR_DEFAULT_PRIORITY,
+	.prio = 0,
 	.suspend = THR_CREATE_RUNNING,
-	.flags = 0,
-	.arg_attr = NULL,
-	.cleanup_attr = NULL,
+	.flags = PTHREAD_SCOPE_SYSTEM,
 	.stackaddr_attr = NULL,
 	.stacksize_attr = THR_STACK_DEFAULT,
 	.guardsize_attr = 0
@@ -95,17 +98,20 @@
 };
 
 pid_t		_thr_pid;
-int		_thr_guard_default;
-int		_thr_stack_default = THR_STACK_DEFAULT;
-int		_thr_stack_initial = THR_STACK_INITIAL;
+int		_thr_is_smp = 0;
+size_t		_thr_guard_default;
+size_t		_thr_stack_default = THR_STACK_DEFAULT;
+size_t		_thr_stack_initial = THR_STACK_INITIAL;
 int		_thr_page_size;
+int		_thr_spinloops;
+int		_thr_yieldloops;
 int		_gc_count;
-umtx_t		_mutex_static_lock;
-umtx_t		_cond_static_lock;
-umtx_t		_rwlock_static_lock;
-umtx_t		_keytable_lock;
-umtx_t		_thr_list_lock;
-umtx_t		_thr_event_lock;
+struct umutex	_mutex_static_lock = DEFAULT_UMUTEX;
+struct umutex	_cond_static_lock = DEFAULT_UMUTEX;
+struct umutex	_rwlock_static_lock = DEFAULT_UMUTEX;
+struct umutex	_keytable_lock = DEFAULT_UMUTEX;
+struct umutex	_thr_list_lock = DEFAULT_UMUTEX;
+struct umutex	_thr_event_lock = DEFAULT_UMUTEX;
 
 int	__pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
 int	__pthread_mutex_lock(pthread_mutex_t *);
@@ -119,29 +125,8 @@
  * All weak references used within libc should be in this table.
  * This is so that static libraries will work.
  */
-STATIC_LIB_REQUIRE(_accept);
-STATIC_LIB_REQUIRE(_bind);
-STATIC_LIB_REQUIRE(_close);
-STATIC_LIB_REQUIRE(_connect);
-STATIC_LIB_REQUIRE(_dup);
-STATIC_LIB_REQUIRE(_dup2);
-STATIC_LIB_REQUIRE(_execve);
-STATIC_LIB_REQUIRE(_fcntl);
-STATIC_LIB_REQUIRE(_flock);
-STATIC_LIB_REQUIRE(_flockfile);
-STATIC_LIB_REQUIRE(_fstat);
-STATIC_LIB_REQUIRE(_fstatfs);
-STATIC_LIB_REQUIRE(_fsync);
-STATIC_LIB_REQUIRE(_getdirentries);
-STATIC_LIB_REQUIRE(_getlogin);
-STATIC_LIB_REQUIRE(_getpeername);
-STATIC_LIB_REQUIRE(_getsockname);
-STATIC_LIB_REQUIRE(_getsockopt);
-STATIC_LIB_REQUIRE(_ioctl);
-STATIC_LIB_REQUIRE(_kevent);
-STATIC_LIB_REQUIRE(_listen);
-STATIC_LIB_REQUIRE(_nanosleep);
-STATIC_LIB_REQUIRE(_open);
+
+STATIC_LIB_REQUIRE(_fork);
 STATIC_LIB_REQUIRE(_pthread_getspecific);
 STATIC_LIB_REQUIRE(_pthread_key_create);
 STATIC_LIB_REQUIRE(_pthread_key_delete);
@@ -155,23 +140,25 @@
 STATIC_LIB_REQUIRE(_pthread_mutexattr_settype);
 STATIC_LIB_REQUIRE(_pthread_once);
 STATIC_LIB_REQUIRE(_pthread_setspecific);
-STATIC_LIB_REQUIRE(_read);
-STATIC_LIB_REQUIRE(_readv);
-STATIC_LIB_REQUIRE(_recvfrom);
-STATIC_LIB_REQUIRE(_recvmsg);
-STATIC_LIB_REQUIRE(_select);
-STATIC_LIB_REQUIRE(_sendmsg);
-STATIC_LIB_REQUIRE(_sendto);
-STATIC_LIB_REQUIRE(_setsockopt);
+STATIC_LIB_REQUIRE(_raise);
+STATIC_LIB_REQUIRE(_sem_destroy);
+STATIC_LIB_REQUIRE(_sem_getvalue);
+STATIC_LIB_REQUIRE(_sem_init);
+STATIC_LIB_REQUIRE(_sem_post);
+STATIC_LIB_REQUIRE(_sem_timedwait);
+STATIC_LIB_REQUIRE(_sem_trywait);
+STATIC_LIB_REQUIRE(_sem_wait);
 STATIC_LIB_REQUIRE(_sigaction);
 STATIC_LIB_REQUIRE(_sigprocmask);
 STATIC_LIB_REQUIRE(_sigsuspend);
-STATIC_LIB_REQUIRE(_socket);
-STATIC_LIB_REQUIRE(_socketpair);
+STATIC_LIB_REQUIRE(_sigtimedwait);
+STATIC_LIB_REQUIRE(_sigwait);
+STATIC_LIB_REQUIRE(_sigwaitinfo);
+STATIC_LIB_REQUIRE(_spinlock);
+STATIC_LIB_REQUIRE(_spinlock_debug);
+STATIC_LIB_REQUIRE(_spinunlock);
 STATIC_LIB_REQUIRE(_thread_init_hack);
-STATIC_LIB_REQUIRE(_wait4);
-STATIC_LIB_REQUIRE(_write);
-STATIC_LIB_REQUIRE(_writev);
+STATIC_LIB_REQUIRE(_vfork);
 
 /*
  * These are needed when linking statically.  All references within
@@ -198,16 +185,47 @@
 	(pthread_func_t)entry, (pthread_func_t)entry
 
 static pthread_func_t jmp_table[][2] = {
+	{DUAL_ENTRY(_pthread_atfork)},	/* PJT_ATFORK */
+	{DUAL_ENTRY(_pthread_attr_destroy)},	/* PJT_ATTR_DESTROY */
+	{DUAL_ENTRY(_pthread_attr_getdetachstate)},	/* PJT_ATTR_GETDETACHSTATE */
+	{DUAL_ENTRY(_pthread_attr_getguardsize)},	/* PJT_ATTR_GETGUARDSIZE */
+	{DUAL_ENTRY(_pthread_attr_getinheritsched)},	/* PJT_ATTR_GETINHERITSCHED */
+	{DUAL_ENTRY(_pthread_attr_getschedparam)},	/* PJT_ATTR_GETSCHEDPARAM */
+	{DUAL_ENTRY(_pthread_attr_getschedpolicy)},	/* PJT_ATTR_GETSCHEDPOLICY */
+	{DUAL_ENTRY(_pthread_attr_getscope)},	/* PJT_ATTR_GETSCOPE */
+	{DUAL_ENTRY(_pthread_attr_getstackaddr)},	/* PJT_ATTR_GETSTACKADDR */
+	{DUAL_ENTRY(_pthread_attr_getstacksize)},	/* PJT_ATTR_GETSTACKSIZE */
+	{DUAL_ENTRY(_pthread_attr_init)},	/* PJT_ATTR_INIT */
+	{DUAL_ENTRY(_pthread_attr_setdetachstate)},	/* PJT_ATTR_SETDETACHSTATE */
+	{DUAL_ENTRY(_pthread_attr_setguardsize)},	/* PJT_ATTR_SETGUARDSIZE */
+	{DUAL_ENTRY(_pthread_attr_setinheritsched)},	/* PJT_ATTR_SETINHERITSCHED */
+	{DUAL_ENTRY(_pthread_attr_setschedparam)},	/* PJT_ATTR_SETSCHEDPARAM */
+	{DUAL_ENTRY(_pthread_attr_setschedpolicy)},	/* PJT_ATTR_SETSCHEDPOLICY */
+	{DUAL_ENTRY(_pthread_attr_setscope)},	/* PJT_ATTR_SETSCOPE */
+	{DUAL_ENTRY(_pthread_attr_setstackaddr)},	/* PJT_ATTR_SETSTACKADDR */
+	{DUAL_ENTRY(_pthread_attr_setstacksize)},	/* PJT_ATTR_SETSTACKSIZE */
+	{DUAL_ENTRY(_pthread_cancel)},	/* PJT_CANCEL */
+	{DUAL_ENTRY(_pthread_cleanup_pop)},	/* PJT_CLEANUP_POP */
+	{DUAL_ENTRY(_pthread_cleanup_push)},	/* PJT_CLEANUP_PUSH */
 	{DUAL_ENTRY(_pthread_cond_broadcast)},	/* PJT_COND_BROADCAST */
 	{DUAL_ENTRY(_pthread_cond_destroy)},	/* PJT_COND_DESTROY */
 	{DUAL_ENTRY(_pthread_cond_init)},	/* PJT_COND_INIT */
 	{DUAL_ENTRY(_pthread_cond_signal)},	/* PJT_COND_SIGNAL */
+	{DUAL_ENTRY(_pthread_cond_timedwait)},	/* PJT_COND_TIMEDWAIT */
 	{(pthread_func_t)__pthread_cond_wait,
 	 (pthread_func_t)_pthread_cond_wait},	/* PJT_COND_WAIT */
+	{DUAL_ENTRY(_pthread_detach)},	/* PJT_DETACH */
+	{DUAL_ENTRY(_pthread_equal)},	/* PJT_EQUAL */
+	{DUAL_ENTRY(_pthread_exit)},	/* PJT_EXIT */
 	{DUAL_ENTRY(_pthread_getspecific)},	/* PJT_GETSPECIFIC */
+	{DUAL_ENTRY(_pthread_join)},	/* PJT_JOIN */
 	{DUAL_ENTRY(_pthread_key_create)},	/* PJT_KEY_CREATE */
 	{DUAL_ENTRY(_pthread_key_delete)},	/* PJT_KEY_DELETE*/
+	{DUAL_ENTRY(_pthread_kill)},	/* PJT_KILL */
 	{DUAL_ENTRY(_pthread_main_np)},		/* PJT_MAIN_NP */
+	{DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */
+	{DUAL_ENTRY(_pthread_mutexattr_init)},	/* PJT_MUTEXATTR_INIT */
+	{DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */
 	{DUAL_ENTRY(_pthread_mutex_destroy)},	/* PJT_MUTEX_DESTROY */
 	{DUAL_ENTRY(_pthread_mutex_init)},	/* PJT_MUTEX_INIT */
 	{(pthread_func_t)__pthread_mutex_lock,
@@ -215,9 +233,6 @@
 	{(pthread_func_t)__pthread_mutex_trylock,
 	 (pthread_func_t)_pthread_mutex_trylock},/* PJT_MUTEX_TRYLOCK */
 	{DUAL_ENTRY(_pthread_mutex_unlock)},	/* PJT_MUTEX_UNLOCK */
-	{DUAL_ENTRY(_pthread_mutexattr_destroy)}, /* PJT_MUTEXATTR_DESTROY */
-	{DUAL_ENTRY(_pthread_mutexattr_init)},	/* PJT_MUTEXATTR_INIT */
-	{DUAL_ENTRY(_pthread_mutexattr_settype)}, /* PJT_MUTEXATTR_SETTYPE */
 	{DUAL_ENTRY(_pthread_once)},		/* PJT_ONCE */
 	{DUAL_ENTRY(_pthread_rwlock_destroy)},	/* PJT_RWLOCK_DESTROY */
 	{DUAL_ENTRY(_pthread_rwlock_init)},	/* PJT_RWLOCK_INIT */
@@ -227,8 +242,11 @@
 	{DUAL_ENTRY(_pthread_rwlock_unlock)},	/* PJT_RWLOCK_UNLOCK */
 	{DUAL_ENTRY(_pthread_rwlock_wrlock)},	/* PJT_RWLOCK_WRLOCK */
 	{DUAL_ENTRY(_pthread_self)},		/* PJT_SELF */
+	{DUAL_ENTRY(_pthread_setcancelstate)},	/* PJT_SETCANCELSTATE */
+	{DUAL_ENTRY(_pthread_setcanceltype)},	/* PJT_SETCANCELTYPE */
 	{DUAL_ENTRY(_pthread_setspecific)},	/* PJT_SETSPECIFIC */
-	{DUAL_ENTRY(_pthread_sigmask)}		/* PJT_SIGMASK */
+	{DUAL_ENTRY(_pthread_sigmask)},		/* PJT_SIGMASK */
+	{DUAL_ENTRY(_pthread_testcancel)}	/* PJT_TESTCANCEL */
 };
 
 static int init_once = 0;
@@ -301,7 +319,7 @@
 			PANIC("Can't open console");
 		if (setlogin("root") == -1)
 			PANIC("Can't set login to root");
-		if (__sys_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1)
+		if (_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1)
 			PANIC("Can't set controlling terminal");
 	}
 
@@ -346,6 +364,8 @@
 static void
 init_main_thread(struct pthread *thread)
 {
+	struct sched_param sched_param;
+
 	/* Setup the thread attributes. */
 	thr_self(&thread->tid);
 	thread->attr = _pthread_attr_default;
@@ -358,7 +378,7 @@
 	 * resource limits, so this stack needs an explicitly mapped
 	 * red zone to protect the thread stack that is just beyond.
 	 */
-	if (mmap((void *)_usrstack - _thr_stack_initial -
+	if (mmap(_usrstack - _thr_stack_initial -
 	    _thr_guard_default, _thr_guard_default, 0, MAP_ANON,
 	    -1, 0) == MAP_FAILED)
 		PANIC("Cannot allocate red zone for initial thread");
@@ -372,7 +392,7 @@
 	 *       actually free() it; it just puts it in the free
 	 *       stack queue for later reuse.
 	 */
-	thread->attr.stackaddr_attr = (void *)_usrstack - _thr_stack_initial;
+	thread->attr.stackaddr_attr = _usrstack - _thr_stack_initial;
 	thread->attr.stacksize_attr = _thr_stack_initial;
 	thread->attr.guardsize_attr = _thr_guard_default;
 	thread->attr.flags |= THR_STACK_USER;
@@ -383,20 +403,20 @@
 	 */
 	thread->magic = THR_MAGIC;
 
-	thread->cancelflags = PTHREAD_CANCEL_ENABLE | PTHREAD_CANCEL_DEFERRED;
-	thread->name = strdup("initial thread");
-
-	/* Default the priority of the initial thread: */
-	thread->base_priority = THR_DEFAULT_PRIORITY;
-	thread->active_priority = THR_DEFAULT_PRIORITY;
-	thread->inherited_priority = 0;
+	thread->cancel_enable = 1;
+	thread->cancel_async = 0;
+	thr_set_name(thread->tid, "initial thread");
 
 	/* Initialize the mutex queue: */
 	TAILQ_INIT(&thread->mutexq);
-	TAILQ_INIT(&thread->pri_mutexq);
+	TAILQ_INIT(&thread->pp_mutexq);
 
 	thread->state = PS_RUNNING;
 
+	_thr_getscheduler(thread->tid, &thread->attr.sched_policy,
+		 &sched_param);
+	thread->attr.prio = sched_param.sched_priority;
+
 	/* Others cleared to zero by thr_alloc() */
 }
 
@@ -405,13 +425,15 @@
 {
 	size_t len;
 	int mib[2];
+	char *env;
 
-	_thr_umtx_init(&_mutex_static_lock);
-	_thr_umtx_init(&_cond_static_lock);
-	_thr_umtx_init(&_rwlock_static_lock);
-	_thr_umtx_init(&_keytable_lock);
-	_thr_umtx_init(&_thr_atfork_lock);
-	_thr_umtx_init(&_thr_event_lock);
+	_thr_umutex_init(&_mutex_static_lock);
+	_thr_umutex_init(&_cond_static_lock);
+	_thr_umutex_init(&_rwlock_static_lock);
+	_thr_umutex_init(&_keytable_lock);
+	_thr_umutex_init(&_thr_atfork_lock);
+	_thr_umutex_init(&_thr_event_lock);
+	_thr_once_init();
 	_thr_spinlock_init();
 	_thr_list_init();
 
@@ -426,20 +448,20 @@
 		len = sizeof (_usrstack);
 		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
 			PANIC("Cannot get kern.usrstack from sysctl");
+		len = sizeof(_thr_is_smp);
+		sysctlbyname("kern.smp.cpus", &_thr_is_smp, &len, NULL, 0);
+		_thr_is_smp = (_thr_is_smp > 1);
 		_thr_page_size = getpagesize();
 		_thr_guard_default = _thr_page_size;
 		_pthread_attr_default.guardsize_attr = _thr_guard_default;
 		_pthread_attr_default.stacksize_attr = _thr_stack_default;
-
+		env = getenv("LIBPTHREAD_SPINLOOPS");
+		if (env)
+			_thr_spinloops = atoi(env);
+		env = getenv("LIBPTHREAD_YIELDLOOPS");
+		if (env)
+			_thr_yieldloops = atoi(env);
 		TAILQ_INIT(&_thr_atfork_list);
-#ifdef SYSTEM_SCOPE_ONLY
-		_thr_scope_system = 1;
-#else
-		if (getenv("LIBPTHREAD_SYSTEM_SCOPE") != NULL)
-			_thr_scope_system = 1;
-		else if (getenv("LIBPTHREAD_PROCESS_SCOPE") != NULL)
-			_thr_scope_system = -1;
-#endif
 	}
 	init_once = 1;
 }
Index: thr_stack.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_stack.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_stack.c -L lib/libthr/thread/thr_stack.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_stack.c
+++ lib/libthr/thread/thr_stack.c
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_stack.c,v 1.6 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_stack.c,v 1.7 2006/04/04 02:57:49 davidxu Exp $
  */
 
 #include <sys/types.h>
@@ -113,7 +113,7 @@
  * high memory
  *
  */
-static void *last_stack = NULL;
+static char *last_stack = NULL;
 
 /*
  * Round size up to the nearest multiple of
@@ -236,8 +236,9 @@
 
 	if ((attr != NULL) && ((attr->flags & THR_STACK_USER) == 0)
 	    && (attr->stackaddr_attr != NULL)) {
-		spare_stack = (attr->stackaddr_attr + attr->stacksize_attr
-		    - sizeof(struct stack));
+		spare_stack = (struct stack *)
+			((char *)attr->stackaddr_attr +
+			attr->stacksize_attr - sizeof(struct stack));
 		spare_stack->stacksize = round_up(attr->stacksize_attr);
 		spare_stack->guardsize = round_up(attr->guardsize_attr);
 		spare_stack->stackaddr = attr->stackaddr_attr;
Index: thr_pspinlock.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_pspinlock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_pspinlock.c -L lib/libthr/thread/thr_pspinlock.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_pspinlock.c
+++ lib/libthr/thread/thr_pspinlock.c
@@ -23,12 +23,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_pspinlock.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_pspinlock.c,v 1.5 2006/12/15 11:52:01 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <stdlib.h>
 #include <pthread.h>
+#include "un-namespace.h"
+
 #include "thr_private.h"
 
 #define SPIN_COUNT 100000
@@ -50,7 +53,7 @@
 	else if ((lck = malloc(sizeof(struct pthread_spinlock))) == NULL)
 		ret = ENOMEM;
 	else {
-		_thr_umtx_init(&lck->s_lock);
+		_thr_umutex_init(&lck->s_lock);
 		*lock = lck;
 		ret = 0;
 	}
@@ -84,7 +87,7 @@
 	if (lock == NULL || (lck = *lock) == NULL)
 		ret = EINVAL;
 	else
-		ret = THR_UMTX_TRYLOCK(curthread, &lck->s_lock);
+		ret = THR_UMUTEX_TRYLOCK(curthread, &lck->s_lock);
 	return (ret);
 }
 
@@ -99,15 +102,17 @@
 		ret = EINVAL;
 	else {
 		count = SPIN_COUNT;
-		while ((ret = THR_UMTX_TRYLOCK(curthread, &lck->s_lock)) != 0) {
-			while (lck->s_lock) {
-#ifdef __i386__
-				/* tell cpu we are spinning */
-				__asm __volatile("pause");
-#endif
-				if (--count <= 0) {
-					count = SPIN_COUNT;
+		while ((ret = THR_UMUTEX_TRYLOCK(curthread, &lck->s_lock)) != 0) {
+			while (lck->s_lock.m_owner) {
+				if (_thr_is_smp) {
 					_pthread_yield();
+				} else {
+					CPU_SPINWAIT;
+
+					if (--count <= 0) {
+						count = SPIN_COUNT;
+						_pthread_yield();
+					}
 				}
 			}
 		}
@@ -127,7 +132,7 @@
 	if (lock == NULL || (lck = *lock) == NULL)
 		ret = EINVAL;
 	else {
-		ret = THR_UMTX_UNLOCK(curthread, &lck->s_lock);
+		ret = THR_UMUTEX_UNLOCK(curthread, &lck->s_lock);
 	}
 	return (ret);
 }
Index: thr_kern.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_kern.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_kern.c -L lib/libthr/thread/thr_kern.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_kern.c
+++ lib/libthr/thread/thr_kern.c
@@ -24,11 +24,12 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_kern.c,v 1.19 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_kern.c,v 1.21 2006/09/21 04:21:30 davidxu Exp $
  */
 
 #include <sys/types.h>
 #include <sys/signalvar.h>
+#include <sys/rtprio.h>
 #include <pthread.h>
 
 #include "thr_private.h"
@@ -51,13 +52,11 @@
 		return (0);
 
 	__isthreaded = threaded;
-#if 0
 	if (threaded != 0) {
 		_thr_rtld_init();
 	} else {
 		_thr_rtld_fini();
 	}
-#endif
 	return (0);
 }
 
@@ -98,3 +97,68 @@
 {
 	PANIC("locklevel <= 0");
 }
+
+int
+_rtp_to_schedparam(const struct rtprio *rtp, int *policy,
+	struct sched_param *param)
+{
+	switch(rtp->type) {
+	case RTP_PRIO_REALTIME:
+		*policy = SCHED_RR;
+		param->sched_priority = RTP_PRIO_MAX - rtp->prio;
+		break;
+	case RTP_PRIO_FIFO:
+		*policy = SCHED_FIFO;
+		param->sched_priority = RTP_PRIO_MAX - rtp->prio;
+		break;
+	default:
+		*policy = SCHED_OTHER;
+		param->sched_priority = 0;
+		break;
+	}
+	return (0);
+}
+
+int
+_schedparam_to_rtp(int policy, const struct sched_param *param,
+	struct rtprio *rtp)
+{
+	switch(policy) {
+	case SCHED_RR:
+		rtp->type = RTP_PRIO_REALTIME;
+		rtp->prio = RTP_PRIO_MAX - param->sched_priority;
+		break;
+	case SCHED_FIFO:
+		rtp->type = RTP_PRIO_FIFO;
+		rtp->prio = RTP_PRIO_MAX - param->sched_priority;
+		break;
+	case SCHED_OTHER:
+	default:
+		rtp->type = RTP_PRIO_NORMAL;
+		rtp->prio = 0;
+		break;
+	}
+	return (0);
+}
+
+int
+_thr_getscheduler(lwpid_t lwpid, int *policy, struct sched_param *param)
+{
+	struct rtprio rtp;
+	int ret;
+
+	ret = rtprio_thread(RTP_LOOKUP, lwpid, &rtp);
+	if (ret == -1)
+		return (ret);
+	_rtp_to_schedparam(&rtp, policy, param);
+	return (0);
+}
+
+int
+_thr_setscheduler(lwpid_t lwpid, int policy, const struct sched_param *param)
+{
+	struct rtprio rtp;
+
+	_schedparam_to_rtp(policy, param, &rtp);
+	return (rtprio_thread(RTP_SET, lwpid, &rtp));
+}
Index: thr_suspend_np.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_suspend_np.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_suspend_np.c -L lib/libthr/thread/thr_suspend_np.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_suspend_np.c
+++ lib/libthr/thread/thr_suspend_np.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,11 +26,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_suspend_np.c,v 1.3.2.2 2006/02/23 03:56:03 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_suspend_np.c,v 1.8 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
+#include <pthread_np.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_symbols.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_symbols.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_symbols.c -L lib/libthr/thread/thr_symbols.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_symbols.c
+++ lib/libthr/thread/thr_symbols.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_symbols.c,v 1.2.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_symbols.c,v 1.4 2007/01/12 07:26:21 imp Exp $
  */
 
 #include <sys/types.h>
Index: thr_attr.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_attr.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_attr.c -L lib/libthr/thread/thr_attr.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_attr.c
+++ lib/libthr/thread/thr_attr.c
@@ -74,10 +74,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -93,14 +90,16 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_attr.c,v 1.3.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_attr.c,v 1.8 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <pthread.h>
 #include <stdlib.h>
 #include <string.h>
 #include <pthread_np.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -422,20 +421,31 @@
 int
 _pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *param)
 {
-	int ret = 0;
+	int policy;
 
 	if ((attr == NULL) || (*attr == NULL))
-		ret = EINVAL;
-	else if (param == NULL) {
-		ret = ENOTSUP;
-	} else if ((param->sched_priority < THR_MIN_PRIORITY) ||
-	    (param->sched_priority > THR_MAX_PRIORITY)) {
-		/* Return an unsupported value error. */
-		ret = ENOTSUP;
-	} else
-		(*attr)->prio = param->sched_priority;
+		return (EINVAL);
 
-	return(ret);
+	if (param == NULL)
+		return (ENOTSUP);
+
+	policy = (*attr)->sched_policy;
+
+	if (policy == SCHED_FIFO || policy == SCHED_RR) {
+		if (param->sched_priority < _thr_priorities[policy-1].pri_min ||
+		    param->sched_priority > _thr_priorities[policy-1].pri_max)
+		return (ENOTSUP);
+	} else {
+		/*
+		 * Ignore it for SCHED_OTHER now, patches for glib ports
+		 * are wrongly using M:N thread library's internal macro
+		 * THR_MIN_PRIORITY and THR_MAX_PRIORITY.
+		 */
+	}
+
+	(*attr)->prio = param->sched_priority;
+
+	return (0);
 }
 
 __weak_reference(_pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
@@ -449,9 +459,10 @@
 		ret = EINVAL;
 	else if ((policy < SCHED_FIFO) || (policy > SCHED_RR)) {
 		ret = ENOTSUP;
-	} else
+	} else {
 		(*attr)->sched_policy = policy;
-
+		(*attr)->prio = _thr_priorities[policy-1].pri_default;
+	}
 	return(ret);
 }
 
Index: thr_atfork.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_atfork.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_atfork.c -L lib/libthr/thread/thr_atfork.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_atfork.c
+++ lib/libthr/thread/thr_atfork.c
@@ -23,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_atfork.c,v 1.2 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_atfork.c,v 1.3 2006/09/06 04:04:10 davidxu Exp $
  */
 
 #include <errno.h>
@@ -50,8 +50,8 @@
 	af->prepare = prepare;
 	af->parent = parent;
 	af->child = child;
-	THR_UMTX_LOCK(curthread, &_thr_atfork_lock);
+	THR_UMUTEX_LOCK(curthread, &_thr_atfork_lock);
 	TAILQ_INSERT_TAIL(&_thr_atfork_list, af, qe);
-	THR_UMTX_UNLOCK(curthread, &_thr_atfork_lock);
+	THR_UMUTEX_UNLOCK(curthread, &_thr_atfork_lock);
 	return (0);
 }
Index: thr_spec.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_spec.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L lib/libthr/thread/thr_spec.c -L lib/libthr/thread/thr_spec.c -u -r1.2 -r1.3
--- lib/libthr/thread/thr_spec.c
+++ lib/libthr/thread/thr_spec.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,14 +26,16 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_spec.c,v 1.3 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_spec.c,v 1.6.2.1 2007/11/09 21:15:58 marius Exp $
  */
 
+#include "namespace.h"
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -55,8 +54,7 @@
 	struct pthread *curthread;
 	int i;
 
-	if (_thr_initial == NULL)
-		_libpthread_init(NULL);
+	_thr_check_init();
 
 	curthread = _get_curthread();
 
@@ -108,7 +106,7 @@
 {
 	struct pthread	*curthread = _get_curthread();
 	void		(*destructor)( void *);
-	void		*data = NULL;
+	const void	*data = NULL;
 	int		key;
 	int		i;
 
@@ -127,8 +125,7 @@
 			    (curthread->specific[key].data != NULL)) {
 				if (curthread->specific[key].seqno ==
 				    _thread_keytable[key].seqno) {
-					data = (void *)
-					    curthread->specific[key].data;
+					data = curthread->specific[key].data;
 					destructor = _thread_keytable[key].destructor;
 				}
 				curthread->specific[key].data = NULL;
@@ -145,7 +142,7 @@
 				 * destructor:
 				 */
 				THR_LOCK_RELEASE(curthread, &_keytable_lock);
-				destructor(data);
+				destructor(__DECONST(void *, data));
 				THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
 			}
 		}
@@ -165,11 +162,7 @@
 	struct pthread_specific_elem *new_data;
 
 	new_data = (struct pthread_specific_elem *)
-	    malloc(sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX);
-	if (new_data != NULL) {
-		memset((void *) new_data, 0,
-		    sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX);
-	}
+	    calloc(1, sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX);
 	return (new_data);
 }
 
@@ -208,7 +201,7 @@
 _pthread_getspecific(pthread_key_t key)
 {
 	struct pthread	*pthread;
-	void		*data;
+	const void	*data;
 
 	/* Point to the running thread: */
 	pthread = _get_curthread();
@@ -219,7 +212,7 @@
 		if (_thread_keytable[key].allocated &&
 		    (pthread->specific[key].seqno == _thread_keytable[key].seqno)) {
 			/* Return the value: */
-			data = (void *) pthread->specific[key].data;
+			data = pthread->specific[key].data;
 		} else {
 			/*
 			 * This key has not been used before, so return NULL
@@ -230,5 +223,5 @@
 	} else
 		/* No specific data has been created, so just return NULL: */
 		data = NULL;
-	return (data);
+	return (__DECONST(void *, data));
 }
Index: thr_sig.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_sig.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_sig.c -L lib/libthr/thread/thr_sig.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_sig.c
+++ lib/libthr/thread/thr_sig.c
@@ -23,9 +23,10 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_sig.c,v 1.13.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_sig.c,v 1.23 2006/12/06 00:15:35 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/signalvar.h>
@@ -35,6 +36,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -45,13 +47,22 @@
 #define DBG_MSG(x...)
 #endif
 
+extern int	__pause(void);
+int	___pause(void);
+int	_raise(int);
+int	__sigtimedwait(const sigset_t *set, siginfo_t *info,
+	const struct timespec * timeout);
+int	__sigwaitinfo(const sigset_t *set, siginfo_t *info);
+int	__sigwait(const sigset_t *set, int *sig);
+
 static void
-sigcancel_handler(int sig, siginfo_t *info, ucontext_t *ucp)
+sigcancel_handler(int sig __unused,
+	siginfo_t *info __unused, ucontext_t *ucp __unused)
 {
 	struct pthread *curthread = _get_curthread();
 
-	if (curthread->cancelflags & THR_CANCEL_AT_POINT)
-		pthread_testcancel();
+	if (curthread->cancel_defer && curthread->cancel_pending)
+		thr_wake(curthread->tid);
 	_thr_ast(curthread);
 }
 
@@ -59,6 +70,7 @@
 _thr_ast(struct pthread *curthread)
 {
 	if (!THR_IN_CRITICAL(curthread)) {
+		_thr_testcancel(curthread);
 		if (__predict_false((curthread->flags &
 		    (THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED))
 			== THR_FLAGS_NEED_SUSPEND))
@@ -70,7 +82,9 @@
 _thr_suspend_check(struct pthread *curthread)
 {
 	umtx_t cycle;
+	int err;
 
+	err = errno;
 	/* 
 	 * Blocks SIGCANCEL which other threads must send.
 	 */
@@ -82,7 +96,7 @@
 	 * ourself.
 	 */
 	curthread->critical_count++;
-	THR_UMTX_LOCK(curthread, &(curthread)->lock);
+	THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
 	while ((curthread->flags & (THR_FLAGS_NEED_SUSPEND |
 		THR_FLAGS_SUSPENDED)) == THR_FLAGS_NEED_SUSPEND) {
 		curthread->cycle++;
@@ -98,12 +112,12 @@
 		if (curthread->state == PS_DEAD)
 			break;
 		curthread->flags |= THR_FLAGS_SUSPENDED;
-		THR_UMTX_UNLOCK(curthread, &(curthread)->lock);
+		THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
 		_thr_umtx_wait(&curthread->cycle, cycle, NULL);
-		THR_UMTX_LOCK(curthread, &(curthread)->lock);
+		THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
 		curthread->flags &= ~THR_FLAGS_SUSPENDED;
 	}
-	THR_UMTX_UNLOCK(curthread, &(curthread)->lock);
+	THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
 	curthread->critical_count--;
 
 	/* 
@@ -114,6 +128,7 @@
 	 * have one nesting signal frame, this should be fine.
 	 */
 	_thr_signal_unblock(curthread);
+	errno = err;
 }
 
 void
@@ -133,6 +148,35 @@
 {
 }
 
+__weak_reference(___pause, pause);
+
+int
+___pause(void)
+{
+	struct pthread *curthread = _get_curthread();
+	int	ret;
+
+	_thr_cancel_enter(curthread);
+	ret = __pause();
+	_thr_cancel_leave(curthread);
+	
+	return ret;
+}
+
+__weak_reference(_raise, raise);
+
+int
+_raise(int sig)
+{
+	int ret;
+
+	if (!_thr_isthreaded())
+		ret = kill(getpid(), sig);
+	else
+		ret = _thr_send_sig(_get_curthread(), sig);
+	return (ret);
+}
+
 __weak_reference(_sigaction, sigaction);
 
 int
@@ -176,15 +220,33 @@
 	return (0);
 }
 
-__weak_reference(_sigsuspend, sigsuspend);
+__weak_reference(__sigsuspend, sigsuspend);
 
 int
 _sigsuspend(const sigset_t * set)
 {
+	sigset_t newset;
+	const sigset_t *pset;
+	int ret;
+
+	if (SIGISMEMBER(*set, SIGCANCEL)) {
+		newset = *set;
+		SIGDELSET(newset, SIGCANCEL);
+		pset = &newset;
+	} else
+		pset = set;
+
+	ret = __sys_sigsuspend(pset);
+
+	return (ret);
+}
+
+int
+__sigsuspend(const sigset_t * set)
+{
 	struct pthread *curthread = _get_curthread();
 	sigset_t newset;
 	const sigset_t *pset;
-	int oldcancel;
 	int ret;
 
 	if (SIGISMEMBER(*set, SIGCANCEL)) {
@@ -194,9 +256,9 @@
 	} else
 		pset = set;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_sigsuspend(pset);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 
 	return (ret);
 }
@@ -206,13 +268,30 @@
 __weak_reference(__sigwaitinfo, sigwaitinfo);
 
 int
+_sigtimedwait(const sigset_t *set, siginfo_t *info,
+	const struct timespec * timeout)
+{
+	sigset_t newset;
+	const sigset_t *pset;
+	int ret;
+
+	if (SIGISMEMBER(*set, SIGCANCEL)) {
+		newset = *set;
+		SIGDELSET(newset, SIGCANCEL);
+		pset = &newset;
+	} else
+		pset = set;
+	ret = __sys_sigtimedwait(pset, info, timeout);
+	return (ret);
+}
+
+int
 __sigtimedwait(const sigset_t *set, siginfo_t *info,
 	const struct timespec * timeout)
 {
 	struct pthread	*curthread = _get_curthread();
 	sigset_t newset;
 	const sigset_t *pset;
-	int oldcancel;
 	int ret;
 
 	if (SIGISMEMBER(*set, SIGCANCEL)) {
@@ -221,9 +300,27 @@
 		pset = &newset;
 	} else
 		pset = set;
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_sigtimedwait(pset, info, timeout);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
+	return (ret);
+}
+
+int
+_sigwaitinfo(const sigset_t *set, siginfo_t *info)
+{
+	sigset_t newset;
+	const sigset_t *pset;
+	int ret;
+
+	if (SIGISMEMBER(*set, SIGCANCEL)) {
+		newset = *set;
+		SIGDELSET(newset, SIGCANCEL);
+		pset = &newset;
+	} else
+		pset = set;
+
+	ret = __sys_sigwaitinfo(pset, info);
 	return (ret);
 }
 
@@ -233,7 +330,6 @@
 	struct pthread	*curthread = _get_curthread();
 	sigset_t newset;
 	const sigset_t *pset;
-	int oldcancel;
 	int ret;
 
 	if (SIGISMEMBER(*set, SIGCANCEL)) {
@@ -243,9 +339,27 @@
 	} else
 		pset = set;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_sigwaitinfo(pset, info);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
+	return (ret);
+}
+
+int
+_sigwait(const sigset_t *set, int *sig)
+{
+	sigset_t newset;
+	const sigset_t *pset;
+	int ret;
+
+	if (SIGISMEMBER(*set, SIGCANCEL)) {
+		newset = *set;
+		SIGDELSET(newset, SIGCANCEL);
+		pset = &newset;
+	} else 
+		pset = set;
+
+	ret = __sys_sigwait(pset, sig);
 	return (ret);
 }
 
@@ -255,7 +369,6 @@
 	struct pthread	*curthread = _get_curthread();
 	sigset_t newset;
 	const sigset_t *pset;
-	int oldcancel;
 	int ret;
 
 	if (SIGISMEMBER(*set, SIGCANCEL)) {
@@ -265,8 +378,8 @@
 	} else 
 		pset = set;
 
-	oldcancel = _thr_cancel_enter(curthread);
+	_thr_cancel_enter(curthread);
 	ret = __sys_sigwait(pset, sig);
-	_thr_cancel_leave(curthread, oldcancel);
+	_thr_cancel_leave(curthread);
 	return (ret);
 }
Index: thr_rwlockattr.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_rwlockattr.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_rwlockattr.c -L lib/libthr/thread/thr_rwlockattr.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_rwlockattr.c
+++ lib/libthr/thread/thr_rwlockattr.c
@@ -23,13 +23,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_rwlockattr.c,v 1.1 2003/04/01 03:46:29 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_rwlockattr.c,v 1.2 2006/04/04 02:57:49 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <stdlib.h>
-
 #include <pthread.h>
+#include "un-namespace.h"
+
 #include "thr_private.h"
 
 __weak_reference(_pthread_rwlockattr_destroy, pthread_rwlockattr_destroy);
Index: thr_private.h
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_private.h,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_private.h -L lib/libthr/thread/thr_private.h -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_private.h
+++ lib/libthr/thread/thr_private.h
@@ -26,7 +26,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_private.h,v 1.47.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_private.h,v 1.78.2.1 2007/11/14 01:10:12 kris Exp $
  */
 
 #ifndef _THR_PRIVATE_H
@@ -45,7 +45,6 @@
 #include <signal.h>
 #include <stddef.h>
 #include <stdio.h>
-#include <sched.h>
 #include <unistd.h>
 #include <ucontext.h>
 #include <sys/thr.h>
@@ -61,6 +60,7 @@
 
 typedef TAILQ_HEAD(pthreadlist, pthread) pthreadlist;
 typedef TAILQ_HEAD(atfork_head, pthread_atfork) atfork_head;
+TAILQ_HEAD(mutex_queue, pthread_mutex);
 
 /* Signal to do cancellation */
 #define	SIGCANCEL		32
@@ -72,7 +72,7 @@
 
 /* Output debug messages like this: */
 #define stdout_debug(args...)	_thread_printf(STDOUT_FILENO, ##args)
-#define stderr_debug(args...)	_thread_printf(STDOUT_FILENO, ##args)
+#define stderr_debug(args...)	_thread_printf(STDERR_FILENO, ##args)
 
 #ifdef _PTHREADS_INVARIANTS
 #define THR_ASSERT(cond, msg) do {	\
@@ -113,31 +113,14 @@
 	/*
 	 * Lock for accesses to this structure.
 	 */
-	volatile umtx_t			m_lock;
+	struct umutex			m_lock;
 	enum pthread_mutextype		m_type;
-	int				m_protocol;
-	TAILQ_HEAD(mutex_head, pthread)	m_queue;
 	struct pthread			*m_owner;
-	long				m_flags;
+	int				m_flags;
 	int				m_count;
 	int				m_refcount;
-
-	/*
-	 * Used for priority inheritence and protection.
-	 *
-	 *   m_prio       - For priority inheritence, the highest active
-	 *                  priority (threads locking the mutex inherit
-	 *                  this priority).  For priority protection, the
-	 *                  ceiling priority of this mutex.
-	 *   m_saved_prio - mutex owners inherited priority before
-	 *                  taking the mutex, restored when the owner
-	 *                  unlocks the mutex.
-	 */
-	int				m_prio;
-	int				m_saved_prio;
-
 	/*
-	 * Link for list of all mutexes a thread currently owns.
+	 * Link for all mutexes a thread currently owns.
 	 */
 	TAILQ_ENTRY(pthread_mutex)	m_qe;
 };
@@ -153,20 +136,15 @@
 	enum pthread_mutextype	m_type;
 	int			m_protocol;
 	int			m_ceiling;
-	long			m_flags;
+	int			m_flags;
 };
 
 #define PTHREAD_MUTEXATTR_STATIC_INITIALIZER \
 	{ PTHREAD_MUTEX_DEFAULT, PTHREAD_PRIO_NONE, 0, MUTEX_FLAGS_PRIVATE }
 
 struct pthread_cond {
-	/*
-	 * Lock for accesses to this structure.
-	 */
-	volatile umtx_t	c_lock;
-	volatile umtx_t	c_seqno;
-	volatile int	c_waiters;
-	volatile int	c_wakeups;
+	struct umutex	c_lock;
+	struct ucond	c_kerncv;
 	int		c_pshared;
 	int		c_clockid;
 };
@@ -177,10 +155,11 @@
 };
 
 struct pthread_barrier {
-	volatile umtx_t	b_lock;
-	volatile umtx_t	b_cycle;
-	volatile int	b_count;
-	volatile int	b_waiters;
+	struct umutex		b_lock;
+	struct ucond		b_cv;
+	volatile int64_t	b_cycle;
+	volatile int		b_count;
+	volatile int		b_waiters;
 };
 
 struct pthread_barrierattr {
@@ -188,7 +167,7 @@
 };
 
 struct pthread_spinlock {
-	volatile umtx_t	s_lock;
+	struct umutex	s_lock;
 };
 
 /*
@@ -203,7 +182,7 @@
  */
 struct pthread_cleanup {
 	struct pthread_cleanup	*next;
-	void			(*routine)();
+	void			(*routine)(void *args);
 	void			*routine_arg;
 	int			onstack;
 };
@@ -233,13 +212,10 @@
 struct pthread_attr {
 	int	sched_policy;
 	int	sched_inherit;
-	int	sched_interval;
 	int	prio;
 	int	suspend;
 #define	THR_STACK_USER		0x100	/* 0xFF reserved for <pthread.h> */
 	int	flags;
-	void	*arg_attr;
-	void	(*cleanup_attr)();
 	void	*stackaddr_attr;
 	size_t	stacksize_attr;
 	size_t	guardsize_attr;
@@ -264,33 +240,26 @@
 #define THR_STACK_INITIAL		(THR_STACK_DEFAULT * 2)
 
 /*
- * Define the different priority ranges.  All applications have thread
- * priorities constrained within 0-31.  The threads library raises the
- * priority when delivering signals in order to ensure that signal
- * delivery happens (from the POSIX spec) "as soon as possible".
- * In the future, the threads library will also be able to map specific
- * threads into real-time (cooperating) processes or kernel threads.
- * The RT and SIGNAL priorities will be used internally and added to
- * thread base priorities so that the scheduling queue can handle both
- * normal and RT priority threads with and without signal handling.
- *
- * The approach taken is that, within each class, signal delivery
- * always has priority over thread execution.
- */
-#define THR_DEFAULT_PRIORITY			15
-#define THR_MIN_PRIORITY			0
-#define THR_MAX_PRIORITY			31	/* 0x1F */
-#define THR_SIGNAL_PRIORITY			32	/* 0x20 */
-#define THR_RT_PRIORITY				64	/* 0x40 */
-#define THR_FIRST_PRIORITY			THR_MIN_PRIORITY
-#define THR_LAST_PRIORITY	\
-	(THR_MAX_PRIORITY + THR_SIGNAL_PRIORITY + THR_RT_PRIORITY)
-#define THR_BASE_PRIORITY(prio)	((prio) & THR_MAX_PRIORITY)
-
-/*
- * Time slice period in microseconds.
+ * Define priorities returned by kernel.
  */
-#define TIMESLICE_USEC				20000
+#define THR_MIN_PRIORITY		(_thr_priorities[SCHED_OTHER-1].pri_min)
+#define THR_MAX_PRIORITY		(_thr_priorities[SCHED_OTHER-1].pri_max)
+#define THR_DEF_PRIORITY		(_thr_priorities[SCHED_OTHER-1].pri_default)
+
+#define THR_MIN_RR_PRIORITY		(_thr_priorities[SCHED_RR-1].pri_min)
+#define THR_MAX_RR_PRIORITY		(_thr_priorities[SCHED_RR-1].pri_max)
+#define THR_DEF_RR_PRIORITY		(_thr_priorities[SCHED_RR-1].pri_default)
+
+/* XXX The SCHED_FIFO should have same priority range as SCHED_RR */
+#define THR_MIN_FIFO_PRIORITY		(_thr_priorities[SCHED_FIFO_1].pri_min)
+#define THR_MAX_FIFO_PRIORITY		(_thr_priorities[SCHED_FIFO-1].pri_max)
+#define THR_DEF_FIFO_PRIORITY		(_thr_priorities[SCHED_FIFO-1].pri_default)
+
+struct pthread_prio {
+	int	pri_min;
+	int	pri_max;
+	int	pri_default;
+};
 
 struct pthread_rwlockattr {
 	int		pshared;
@@ -312,10 +281,6 @@
 	PS_DEAD
 };
 
-union pthread_wait_data {
-	pthread_mutex_t	mutex;
-};
-
 struct pthread_specific_elem {
 	const void	*data;
 	int		seqno;
@@ -323,31 +288,28 @@
 
 struct pthread_key {
 	volatile int	allocated;
-	volatile int	count;
 	int		seqno;
 	void            (*destructor)(void *);
 };
 
 /*
+ * lwpid_t is 32bit but kernel thr API exports tid as long type
+ * in very earily date.
+ */
+#define TID(thread)	((uint32_t) ((thread)->tid))
+
+/*
  * Thread structure.
  */
 struct pthread {
-	/*
-	 * Magic value to help recognize a valid thread structure
-	 * from an invalid one:
-	 */
-#define	THR_MAGIC		((u_int32_t) 0xd09ba115)
-	u_int32_t		magic;
-	char			*name;
+	/* Kernel thread id. */
+	long			tid;
+#define	TID_TERMINATED		1
 
 	/*
 	 * Lock for accesses to this thread structure.
 	 */
-	umtx_t			lock;
-
-	/* Kernel thread id. */
-	long			tid;
-#define	TID_TERMINATED		1
+	struct umutex		lock;
 
 	/* Internal condition variable cycle number. */
 	umtx_t			cycle;
@@ -384,28 +346,34 @@
 	void			*arg;
 	struct pthread_attr	attr;
 
- 	/*
-	 * Cancelability flags 
-	 */
-#define	THR_CANCEL_DISABLE		0x0001
-#define	THR_CANCEL_EXITING		0x0002
-#define THR_CANCEL_AT_POINT		0x0004
-#define THR_CANCEL_NEEDED		0x0008
-#define	SHOULD_CANCEL(val)					\
-	(((val) & (THR_CANCEL_DISABLE | THR_CANCEL_EXITING |	\
-		 THR_CANCEL_NEEDED)) == THR_CANCEL_NEEDED)
-
-#define	SHOULD_ASYNC_CANCEL(val)				\
-	(((val) & (THR_CANCEL_DISABLE | THR_CANCEL_EXITING |	\
-		 THR_CANCEL_NEEDED | THR_CANCEL_AT_POINT)) ==	\
-		 (THR_CANCEL_NEEDED | THR_CANCEL_AT_POINT))
-	int			cancelflags;
+#define	SHOULD_CANCEL(thr)					\
+	((thr)->cancel_pending &&				\
+	 ((thr)->cancel_point || (thr)->cancel_async) &&	\
+	 (thr)->cancel_enable && (thr)->cancelling == 0)
+
+	/* Cancellation is enabled */
+	int			cancel_enable;
+
+	/* Cancellation request is pending */
+	int			cancel_pending;
+
+	/* Thread is at cancellation point */
+	int			cancel_point;
+
+	/* Cancellation should be synchoronized */
+	int			cancel_defer;
+
+	/* Asynchronouse cancellation is enabled */
+	int			cancel_async;
+
+	/* Cancellation is in progress */
+	int			cancelling;
 
 	/* Thread temporary signal mask. */
 	sigset_t		sigmask;
 
 	/* Thread state: */
-	umtx_t			state;
+	enum pthread_state 	state;
 
 	/*
 	 * Error variable used instead of errno. The function __error()
@@ -419,18 +387,6 @@
 	 */
 	struct pthread		*joiner;
 
-	/*
-	 * The current thread can belong to a priority mutex queue.
-	 * This is the synchronization queue link.
-	 */
-	TAILQ_ENTRY(pthread)	sqe;
-
-	/* Wait data. */
-	union pthread_wait_data data;
-
-	int			sflags;
-#define THR_FLAGS_IN_SYNCQ	0x0001
-
 	/* Miscellaneous flags; only set with scheduling lock held. */
 	int			flags;
 #define THR_FLAGS_PRIVATE	0x0001
@@ -444,40 +400,11 @@
 #define	TLFLAGS_IN_GCLIST	0x0004	/* thread in gc list */
 #define	TLFLAGS_DETACHED	0x0008	/* thread is detached */
 
-	/*
-	 * Base priority is the user setable and retrievable priority
-	 * of the thread.  It is only affected by explicit calls to
-	 * set thread priority and upon thread creation via a thread
-	 * attribute or default priority.
-	 */
-	char			base_priority;
+	/* Queue of currently owned NORMAL or PRIO_INHERIT type mutexes. */
+	struct mutex_queue	mutexq;
 
-	/*
-	 * Inherited priority is the priority a thread inherits by
-	 * taking a priority inheritence or protection mutex.  It
-	 * is not affected by base priority changes.  Inherited
-	 * priority defaults to and remains 0 until a mutex is taken
-	 * that is being waited on by any other thread whose priority
-	 * is non-zero.
-	 */
-	char			inherited_priority;
-
-	/*
-	 * Active priority is always the maximum of the threads base
-	 * priority and inherited priority.  When there is a change
-	 * in either the base or inherited priority, the active
-	 * priority must be recalculated.
-	 */
-	char			active_priority;
-
-	/* Number of priority ceiling or protection mutexes owned. */
-	int			priority_mutex_count;
-
-	/* Queue of currently owned simple type mutexes. */
-	TAILQ_HEAD(, pthread_mutex)	mutexq;
-
-	/* Queue of currently owned priority type mutexs. */
-	TAILQ_HEAD(, pthread_mutex)	pri_mutexq;
+	/* Queue of all owned PRIO_PROTECT mutexes. */
+	struct mutex_queue	pp_mutexq;
 
 	void				*ret;
 	struct pthread_specific_elem	*specific;
@@ -496,6 +423,13 @@
 	/* Cleanup handlers Link List */
 	struct pthread_cleanup	*cleanup;
 
+	/*
+	 * Magic value to help recognize a valid thread structure
+	 * from an invalid one:
+	 */
+#define	THR_MAGIC		((u_int32_t) 0xd09ba115)
+	u_int32_t		magic;
+
 	/* Enable event reporting */
 	int			report_events;
 
@@ -510,22 +444,29 @@
 	(((thrd)->locklevel > 0) ||			\
 	((thrd)->critical_count > 0))
 
-#define THR_UMTX_TRYLOCK(thrd, lck)			\
-	_thr_umtx_trylock((lck), (thrd)->tid)
+#define	THR_CRITICAL_ENTER(thrd)			\
+	(thrd)->critical_count++
+
+#define	THR_CRITICAL_LEAVE(thrd)			\
+	(thrd)->critical_count--;			\
+	_thr_ast(thrd);
+
+#define THR_UMUTEX_TRYLOCK(thrd, lck)			\
+	_thr_umutex_trylock((lck), TID(thrd))
 
-#define	THR_UMTX_LOCK(thrd, lck)			\
-	_thr_umtx_lock((lck), (thrd)->tid)
+#define	THR_UMUTEX_LOCK(thrd, lck)			\
+	_thr_umutex_lock((lck), TID(thrd))
 
-#define	THR_UMTX_TIMEDLOCK(thrd, lck, timo)		\
-	_thr_umtx_timedlock((lck), (thrd)->tid, (timo))
+#define	THR_UMUTEX_TIMEDLOCK(thrd, lck, timo)		\
+	_thr_umutex_timedlock((lck), TID(thrd), (timo))
 
-#define	THR_UMTX_UNLOCK(thrd, lck)			\
-	_thr_umtx_unlock((lck), (thrd)->tid)
+#define	THR_UMUTEX_UNLOCK(thrd, lck)			\
+	_thr_umutex_unlock((lck), TID(thrd))
 
 #define	THR_LOCK_ACQUIRE(thrd, lck)			\
 do {							\
 	(thrd)->locklevel++;				\
-	_thr_umtx_lock(lck, (thrd)->tid);		\
+	_thr_umutex_lock(lck, TID(thrd));		\
 } while (0)
 
 #ifdef	_PTHREADS_INVARIANTS
@@ -541,7 +482,7 @@
 #define	THR_LOCK_RELEASE(thrd, lck)			\
 do {							\
 	THR_ASSERT_LOCKLEVEL(thrd);			\
-	_thr_umtx_unlock((lck), (thrd)->tid);		\
+	_thr_umutex_unlock((lck), TID(thrd));		\
 	(thrd)->locklevel--;				\
 	_thr_ast(thrd);					\
 } while (0)
@@ -596,8 +537,6 @@
 
 #define GC_NEEDED()	(_gc_count >= 5)
 
-#define	THR_IN_SYNCQ(thrd)	(((thrd)->sflags & THR_FLAGS_IN_SYNCQ) != 0)
-
 #define SHOULD_REPORT_EVENT(curthr, e)			\
 	(curthr->report_events && 			\
 	 (((curthr)->event_mask | _thread_event_mask ) & e) != 0)
@@ -608,9 +547,8 @@
  * Global variables for the pthread kernel.
  */
 
-extern void		*_usrstack __hidden;
+extern char		*_usrstack __hidden;
 extern struct pthread	*_thr_initial __hidden;
-extern int		_thr_scope_system __hidden;
 
 /* For debugger */
 extern int		_libthr_debug;
@@ -625,7 +563,7 @@
 
 extern int		_thread_active_threads;
 extern atfork_head	_thr_atfork_list __hidden;
-extern umtx_t		_thr_atfork_lock __hidden;
+extern struct umutex	_thr_atfork_lock __hidden;
 
 /* Default thread attributes: */
 extern struct pthread_attr _pthread_attr_default __hidden;
@@ -636,64 +574,41 @@
 /* Default condition variable attributes: */
 extern struct pthread_cond_attr _pthread_condattr_default __hidden;
 
+extern struct pthread_prio _thr_priorities[] __hidden;
+
 extern pid_t	_thr_pid __hidden;
-extern int	_thr_guard_default __hidden;
-extern int	_thr_stack_default __hidden;
-extern int	_thr_stack_initial __hidden;
+extern int	_thr_is_smp __hidden;
+
+extern size_t	_thr_guard_default __hidden;
+extern size_t	_thr_stack_default __hidden;
+extern size_t	_thr_stack_initial __hidden;
 extern int	_thr_page_size __hidden;
+extern int	_thr_spinloops __hidden;
+extern int	_thr_yieldloops __hidden;
+
 /* Garbage thread count. */
 extern int	_gc_count __hidden;
 
-extern umtx_t	_mutex_static_lock __hidden;
-extern umtx_t	_cond_static_lock __hidden;
-extern umtx_t	_rwlock_static_lock __hidden;
-extern umtx_t	_keytable_lock __hidden;
-extern umtx_t	_thr_list_lock __hidden;
-extern umtx_t	_thr_event_lock __hidden;
+extern struct umutex	_mutex_static_lock __hidden;
+extern struct umutex	_cond_static_lock __hidden;
+extern struct umutex	_rwlock_static_lock __hidden;
+extern struct umutex	_keytable_lock __hidden;
+extern struct umutex	_thr_list_lock __hidden;
+extern struct umutex	_thr_event_lock __hidden;
 
 /*
  * Function prototype definitions.
  */
 __BEGIN_DECLS
 int	_thr_setthreaded(int) __hidden;
-int	_mutex_cv_lock(pthread_mutex_t *) __hidden;
-int	_mutex_cv_unlock(pthread_mutex_t *) __hidden;
-void	_mutex_notify_priochange(struct pthread *, struct pthread *, int) __hidden;
+int	_mutex_cv_lock(pthread_mutex_t *, int count) __hidden;
+int	_mutex_cv_unlock(pthread_mutex_t *, int *count) __hidden;
 int	_mutex_reinit(pthread_mutex_t *) __hidden;
 void	_mutex_fork(struct pthread *curthread) __hidden;
 void	_mutex_unlock_private(struct pthread *) __hidden;
 void	_libpthread_init(struct pthread *) __hidden;
-void	*_pthread_getspecific(pthread_key_t);
-int	_pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *);
-int	_pthread_cond_destroy(pthread_cond_t *);
-int	_pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
-int	_pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *,
-	    const struct timespec *);
-int	_pthread_cond_signal(pthread_cond_t *);
-int	_pthread_cond_broadcast(pthread_cond_t *);
-int	_pthread_create(pthread_t * thread, const pthread_attr_t * attr,
-	    void *(*start_routine) (void *), void *arg);
-int	_pthread_key_create(pthread_key_t *, void (*) (void *));
-int	_pthread_key_delete(pthread_key_t);
-int	_pthread_mutex_destroy(pthread_mutex_t *);
-int	_pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *);
-int	_pthread_mutex_lock(pthread_mutex_t *);
-int	_pthread_mutex_trylock(pthread_mutex_t *);
-int	_pthread_mutex_unlock(pthread_mutex_t *);
-int	_pthread_mutexattr_init(pthread_mutexattr_t *);
-int	_pthread_mutexattr_destroy(pthread_mutexattr_t *);
-int	_pthread_mutexattr_settype(pthread_mutexattr_t *, int);
-int	_pthread_once(pthread_once_t *, void (*) (void));
-int	_pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *);
-int	_pthread_rwlock_destroy (pthread_rwlock_t *);
-struct pthread *_pthread_self(void);
-int	_pthread_setspecific(pthread_key_t, const void *);
-void	_pthread_testcancel(void);
-void	_pthread_yield(void);
-void	_pthread_cleanup_push(void (*routine) (void *), void *routine_arg);
-void	_pthread_cleanup_pop(int execute);
 struct pthread *_thr_alloc(struct pthread *) __hidden;
-void	_thread_exit(char *, int, char *) __hidden __dead2;
+void	_thread_exit(const char *, int, const char *) __hidden __dead2;
 void	_thr_exit_cleanup(void) __hidden;
 int	_thr_ref_add(struct pthread *, struct pthread *, int) __hidden;
 void	_thr_ref_delete(struct pthread *, struct pthread *) __hidden;
@@ -709,8 +624,11 @@
 void    _thread_dump_info(void) __hidden;
 void	_thread_printf(int, const char *, ...) __hidden;
 void	_thr_spinlock_init(void) __hidden;
-int	_thr_cancel_enter(struct pthread *) __hidden;
-void	_thr_cancel_leave(struct pthread *, int) __hidden;
+void	_thr_cancel_enter(struct pthread *) __hidden;
+void	_thr_cancel_leave(struct pthread *) __hidden;
+void	_thr_cancel_enter_defer(struct pthread *) __hidden;
+void	_thr_cancel_leave_defer(struct pthread *, int) __hidden;
+void	_thr_testcancel(struct pthread *) __hidden;
 void	_thr_signal_block(struct pthread *) __hidden;
 void	_thr_signal_unblock(struct pthread *) __hidden;
 void	_thr_signal_init(void) __hidden;
@@ -725,17 +643,19 @@
 void	_thr_suspend_check(struct pthread *) __hidden;
 void	_thr_assert_lock_level(void) __hidden __dead2;
 void	_thr_ast(struct pthread *) __hidden;
-void	_thr_timer_init(void) __hidden;
+void	_thr_once_init(void) __hidden;
 void	_thr_report_creation(struct pthread *curthread,
-			   struct pthread *newthread) __hidden;
+	    struct pthread *newthread) __hidden;
 void	_thr_report_death(struct pthread *curthread) __hidden;
+int	_thr_getscheduler(lwpid_t, int *, struct sched_param *) __hidden;
+int	_thr_setscheduler(lwpid_t, int, const struct sched_param *) __hidden;
+int	_rtp_to_schedparam(const struct rtprio *rtp, int *policy,
+		struct sched_param *param) __hidden;
+int	_schedparam_to_rtp(int policy, const struct sched_param *param,
+		struct rtprio *rtp) __hidden;
 void	_thread_bp_create(void);
 void	_thread_bp_death(void);
-
-/* #include <sys/aio.h> */
-#ifdef _SYS_AIO_H_
-int	__sys_aio_suspend(const struct aiocb * const[], int, const struct timespec *);
-#endif
+int	_sched_yield(void);
 
 /* #include <fcntl.h> */
 #ifdef  _SYS_FCNTL_H_
@@ -743,16 +663,6 @@
 int     __sys_open(const char *, int, ...);
 #endif
 
-/* #include <sys/ioctl.h> */
-#ifdef _SYS_IOCTL_H_
-int	__sys_ioctl(int, unsigned long, ...);
-#endif
-
-/* #inclde <sched.h> */
-#ifdef	_SCHED_H_
-int	__sys_sched_yield(void);
-#endif
-
 /* #include <signal.h> */
 #ifdef _SIGNAL_H_
 int	__sys_kill(pid_t, int);
@@ -762,25 +672,10 @@
 int     __sys_sigsuspend(const sigset_t *);
 int     __sys_sigreturn(ucontext_t *);
 int     __sys_sigaltstack(const struct sigaltstack *, struct sigaltstack *);
-#endif
-
-/* #include <sys/socket.h> */
-#ifdef _SYS_SOCKET_H_
-int	__sys_accept(int, struct sockaddr *, socklen_t *);
-int	__sys_connect(int, const struct sockaddr *, socklen_t);
-ssize_t __sys_recv(int, void *, size_t, int);
-ssize_t __sys_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *);
-ssize_t __sys_recvmsg(int, struct msghdr *, int);
-int	__sys_sendfile(int, int, off_t, size_t, struct sf_hdtr *,
-	    off_t *, int);
-ssize_t __sys_sendmsg(int, const struct msghdr *, int);
-ssize_t __sys_sendto(int, const void *,size_t, int, const struct sockaddr *, socklen_t);
-#endif
-
-/* #include <sys/uio.h> */
-#ifdef  _SYS_UIO_H_
-ssize_t __sys_readv(int, const struct iovec *, int);
-ssize_t __sys_writev(int, const struct iovec *, int);
+int	__sys_sigwait(const sigset_t *, int *);
+int	__sys_sigtimedwait(const sigset_t *, siginfo_t *,
+		const struct timespec *);
+int	__sys_sigwaitinfo(const sigset_t *set, siginfo_t *info);
 #endif
 
 /* #include <time.h> */
@@ -791,28 +686,11 @@
 /* #include <unistd.h> */
 #ifdef  _UNISTD_H_
 int     __sys_close(int);
-int     __sys_execve(const char *, char * const *, char * const *);
 int	__sys_fork(void);
-int	__sys_fsync(int);
 pid_t	__sys_getpid(void);
-int     __sys_select(int, fd_set *, fd_set *, fd_set *, struct timeval *);
 ssize_t __sys_read(int, void *, size_t);
 ssize_t __sys_write(int, const void *, size_t);
 void	__sys_exit(int);
-int	__sys_sigwait(const sigset_t *, int *);
-int	__sys_sigtimedwait(const sigset_t *, siginfo_t *,
-		const struct timespec *);
-int	__sys_sigwaitinfo(const sigset_t *set, siginfo_t *info);
-#endif
-
-/* #include <poll.h> */
-#ifdef _SYS_POLL_H_
-int 	__sys_poll(struct pollfd *, unsigned, int);
-#endif
-
-/* #include <sys/mman.h> */
-#ifdef _SYS_MMAN_H_
-int	__sys_msync(void *, size_t, int);
 #endif
 
 static inline int
Index: thr_setschedparam.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_setschedparam.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_setschedparam.c -L lib/libthr/thread/thr_setschedparam.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_setschedparam.c
+++ lib/libthr/thread/thr_setschedparam.c
@@ -29,107 +29,65 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_setschedparam.c,v 1.9 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_setschedparam.c,v 1.17 2006/09/21 04:21:30 davidxu Exp $
  */
 
-#include <errno.h>
+#include "namespace.h"
 #include <sys/param.h>
+#include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
 __weak_reference(_pthread_setschedparam, pthread_setschedparam);
 
+/*
+ * Set a thread's scheduling parameters, this should be done
+ * in kernel, doing it in userland is no-op.
+ */
 int
 _pthread_setschedparam(pthread_t pthread, int policy, 
 	const struct sched_param *param)
 {
-	struct pthread *curthread = _get_curthread();
-	int	in_syncq;
-	int	in_readyq = 0;
-	int	old_prio;
-	int	ret = 0;
-
-	if ((param == NULL) || (policy < SCHED_FIFO) || (policy > SCHED_RR)) {
-		/* Return an invalid argument error: */
-		ret = EINVAL;
-	} else if ((param->sched_priority < THR_MIN_PRIORITY) ||
-	    (param->sched_priority > THR_MAX_PRIORITY)) {
-		/* Return an unsupported value error. */
-		ret = ENOTSUP;
+	struct pthread	*curthread = _get_curthread();
+	int	ret;
 
-	/* Find the thread in the list of active threads: */
+	if (pthread == curthread) {
+		THR_LOCK(curthread);
+		if (curthread->attr.sched_policy == policy &&
+		    (policy == SCHED_OTHER ||
+		     curthread->attr.prio == param->sched_priority)) {
+			pthread->attr.prio = param->sched_priority;
+			THR_UNLOCK(curthread);
+			return (0);
+		}
+		ret = _thr_setscheduler(curthread->tid, policy, param);
+		if (ret == -1)
+			ret = errno;
+		else {
+			curthread->attr.sched_policy = policy;
+			curthread->attr.prio = param->sched_priority;
+		}
+		THR_UNLOCK(curthread);
 	} else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
-	    == 0) {
-		/*
-		 * Lock the threads scheduling queue while we change
-		 * its priority:
-		 */
+		== 0) {
 		THR_THREAD_LOCK(curthread, pthread);
-		if (pthread->state == PS_DEAD) {
+		if (pthread->attr.sched_policy == policy &&
+		    (policy == SCHED_OTHER ||
+		     pthread->attr.prio == param->sched_priority)) {
+			pthread->attr.prio = param->sched_priority;
 			THR_THREAD_UNLOCK(curthread, pthread);
-			_thr_ref_delete(curthread, pthread);
-			return (ESRCH);
+			return (0);
 		}
-		in_syncq = pthread->sflags & THR_FLAGS_IN_SYNCQ;
-
-		/* Set the scheduling policy: */
-		pthread->attr.sched_policy = policy;
-
-		if (param->sched_priority ==
-		    THR_BASE_PRIORITY(pthread->base_priority))
-			/*
-			 * There is nothing to do; unlock the threads
-			 * scheduling queue.
-			 */
-			THR_THREAD_UNLOCK(curthread, pthread);
+		ret = _thr_setscheduler(pthread->tid, policy, param);
+		if (ret == -1)
+			ret = errno;
 		else {
-			/*
-			 * Remove the thread from its current priority
-			 * queue before any adjustments are made to its
-			 * active priority:
-			 */
-			old_prio = pthread->active_priority;
-			/* if ((pthread->flags & THR_FLAGS_IN_RUNQ) != 0) */ {
-				in_readyq = 1;
-				/* THR_RUNQ_REMOVE(pthread); */
-			}
-
-			/* Set the thread base priority: */
-			pthread->base_priority &=
-			    (THR_SIGNAL_PRIORITY | THR_RT_PRIORITY);
-			pthread->base_priority = param->sched_priority;
-
-			/* Recalculate the active priority: */
-			pthread->active_priority = MAX(pthread->base_priority,
-			    pthread->inherited_priority);
-
-			if (in_readyq) {
-				if ((pthread->priority_mutex_count > 0) &&
-				    (old_prio > pthread->active_priority)) {
-					/*
-					 * POSIX states that if the priority is
-					 * being lowered, the thread must be
-					 * inserted at the head of the queue for
-					 * its priority if it owns any priority
-					 * protection or inheritence mutexes.
-					 */
-					/* THR_RUNQ_INSERT_HEAD(pthread); */
-				}
-				else
-					/* THR_RUNQ_INSERT_TAIL(pthread)*/ ;
-			}
-
-			/* Unlock the threads scheduling queue: */
-			THR_THREAD_UNLOCK(curthread, pthread);
-
-			/*
-			 * Check for any mutex priority adjustments.  This
-			 * includes checking for a priority mutex on which
-			 * this thread is waiting.
-			 */
-			_mutex_notify_priochange(curthread, pthread, in_syncq);
+			pthread->attr.sched_policy = policy;
+			pthread->attr.prio = param->sched_priority;
 		}
+		THR_THREAD_UNLOCK(curthread, pthread);
 		_thr_ref_delete(curthread, pthread);
 	}
 	return (ret);
Index: thr_once.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_once.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L lib/libthr/thread/thr_once.c -L lib/libthr/thread/thr_once.c -u -r1.1.1.2 -r1.2
--- lib/libthr/thread/thr_once.c
+++ lib/libthr/thread/thr_once.c
@@ -23,7 +23,7 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_once.c,v 1.2.2.1 2006/01/16 05:36:30 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_once.c,v 1.5 2006/02/15 23:05:03 davidxu Exp $
  *
  */
 
@@ -40,8 +40,8 @@
 #define	ONCE_IN_PROGRESS	0x02
 #define	ONCE_MASK		0x03
 
-static pthread_mutex_t		once_lock = PTHREAD_MUTEX_INITIALIZER;
-static pthread_cond_t		once_cv = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t		_thr_once_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t		_thr_once_cv = PTHREAD_COND_INITIALIZER;
 
 /*
  * POSIX:
@@ -55,10 +55,10 @@
 {
 	pthread_once_t *once_control = arg;
 
-	_pthread_mutex_lock(&once_lock);
+	_pthread_mutex_lock(&_thr_once_lock);
 	once_control->state = ONCE_NEVER_DONE;
-	_pthread_mutex_unlock(&once_lock);
-	_pthread_cond_broadcast(&once_cv);
+	_pthread_mutex_unlock(&_thr_once_lock);
+	_pthread_cond_broadcast(&_thr_once_cv);
 }
 
 int
@@ -68,26 +68,32 @@
 
 	if (once_control->state == ONCE_DONE)
 		return (0);
-	_pthread_mutex_lock(&once_lock);
+	_pthread_mutex_lock(&_thr_once_lock);
 	while (*(volatile int *)&(once_control->state) == ONCE_IN_PROGRESS)
-		_pthread_cond_wait(&once_cv, &once_lock);
+		_pthread_cond_wait(&_thr_once_cv, &_thr_once_lock);
 	/*
 	 * If previous thread was canceled, then the state still
 	 * could be ONCE_NEVER_DONE, we need to check it again.
 	 */
 	if (*(volatile int *)&(once_control->state) == ONCE_NEVER_DONE) {
 		once_control->state = ONCE_IN_PROGRESS;
-		_pthread_mutex_unlock(&once_lock);
+		_pthread_mutex_unlock(&_thr_once_lock);
 		_pthread_cleanup_push(once_cancel_handler, once_control);
 		init_routine();
 		_pthread_cleanup_pop(0);
-		_pthread_mutex_lock(&once_lock);
+		_pthread_mutex_lock(&_thr_once_lock);
 		once_control->state = ONCE_DONE;
 		wakeup = 1;
 	}
-	_pthread_mutex_unlock(&once_lock);
+	_pthread_mutex_unlock(&_thr_once_lock);
 	if (wakeup)
-		_pthread_cond_broadcast(&once_cv);
+		_pthread_cond_broadcast(&_thr_once_cv);
 	return (0);
 }
 
+void
+_thr_once_init()
+{
+	_thr_once_lock = PTHREAD_MUTEX_INITIALIZER;
+	_thr_once_cv = PTHREAD_COND_INITIALIZER;
+}
Index: thr_condattr.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_condattr.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_condattr.c -L lib/libthr/thread/thr_condattr.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_condattr.c
+++ lib/libthr/thread/thr_condattr.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,13 +26,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_condattr.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_condattr.c,v 1.3 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <stdlib.h>
 #include <string.h>
 #include <errno.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_equal.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_equal.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_equal.c -L lib/libthr/thread/thr_equal.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_equal.c
+++ lib/libthr/thread/thr_equal.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,9 +26,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_equal.c,v 1.1 2003/04/01 03:46:28 jeff Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_equal.c,v 1.3 2007/01/12 07:26:20 imp Exp $
  */
+#include "namespace.h"
 #include <pthread.h>
+#include "un-namespace.h"
 #include "thr_private.h"
 
 __weak_reference(_pthread_equal, pthread_equal);
Index: thr_spinlock.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_spinlock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_spinlock.c -L lib/libthr/thread/thr_spinlock.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_spinlock.c
+++ lib/libthr/thread/thr_spinlock.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_spinlock.c,v 1.11 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_spinlock.c,v 1.15 2007/01/12 07:26:20 imp Exp $
  *
  */
 
@@ -40,7 +37,7 @@
 
 #include "thr_private.h"
 
-#define	MAX_SPINLOCKS	20
+#define	MAX_SPINLOCKS	72
 
 /*
  * These data structures are used to trace all spinlocks
@@ -48,9 +45,10 @@
  */
 struct spinlock_extra {
 	spinlock_t	*owner;
+	struct umutex	lock;
 };
 
-static umtx_t			spinlock_static_lock;
+static struct umutex		spinlock_static_lock = DEFAULT_UMUTEX;
 static struct spinlock_extra	extra[MAX_SPINLOCKS];
 static int			spinlock_count;
 static int			initialized;
@@ -65,23 +63,29 @@
 void
 _spinunlock(spinlock_t *lck)
 {
-	THR_UMTX_UNLOCK(_get_curthread(), (umtx_t *)&lck->access_lock);
+	struct spinlock_extra	*extra;
+
+	extra = (struct spinlock_extra *)lck->fname;
+	THR_UMUTEX_UNLOCK(_get_curthread(), &extra->lock);
 }
 
 void
 _spinlock(spinlock_t *lck)
 {
+	struct spinlock_extra *extra;
+
 	if (!__isthreaded)
 		PANIC("Spinlock called when not threaded.");
 	if (!initialized)
 		PANIC("Spinlocks not initialized.");
 	if (lck->fname == NULL)
 		init_spinlock(lck);
-	THR_UMTX_LOCK(_get_curthread(), (umtx_t *)&lck->access_lock);
+	extra = (struct spinlock_extra *)lck->fname;
+	THR_UMUTEX_LOCK(_get_curthread(), &extra->lock);
 }
 
 void
-_spinlock_debug(spinlock_t *lck, char *fname, int lineno)
+_spinlock_debug(spinlock_t *lck, char *fname __unused, int lineno __unused)
 {
 	_spinlock(lck);
 }
@@ -89,17 +93,18 @@
 static void
 init_spinlock(spinlock_t *lck)
 {
-	static int count = 0;
+	struct pthread *curthread = _get_curthread();
 
-	THR_UMTX_LOCK(_get_curthread(), &spinlock_static_lock);
+	THR_UMUTEX_LOCK(curthread, &spinlock_static_lock);
 	if ((lck->fname == NULL) && (spinlock_count < MAX_SPINLOCKS)) {
 		lck->fname = (char *)&extra[spinlock_count];
+		_thr_umutex_init(&extra[spinlock_count].lock);
 		extra[spinlock_count].owner = lck;
 		spinlock_count++;
 	}
-	THR_UMTX_UNLOCK(_get_curthread(), &spinlock_static_lock);
-	if (lck->fname == NULL && ++count < 5)
-		stderr_debug("Warning: exceeded max spinlocks");
+	THR_UMUTEX_UNLOCK(curthread, &spinlock_static_lock);
+	if (lck->fname == NULL)
+		PANIC("Warning: exceeded max spinlocks");
 }
 
 void
@@ -107,7 +112,7 @@
 {
 	int i;
 
-	_thr_umtx_init(&spinlock_static_lock);
+	_thr_umutex_init(&spinlock_static_lock);
 	if (initialized != 0) {
 		/*
 		 * called after fork() to reset state of libc spin locks,
@@ -118,7 +123,7 @@
 		 * it is better to do pthread_atfork in libc.
 		 */
 		for (i = 0; i < spinlock_count; i++)
-			_thr_umtx_init((umtx_t *)&extra[i].owner->access_lock);
+			_thr_umutex_init(&extra[i].lock);
 	} else {
 		initialized = 1;
 	}
Index: thr_umtx.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_umtx.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_umtx.c -L lib/libthr/thread/thr_umtx.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_umtx.c
+++ lib/libthr/thread/thr_umtx.c
@@ -23,38 +23,63 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_umtx.c,v 1.1 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_umtx.c,v 1.12 2007/05/09 08:39:33 davidxu Exp $
  *
  */
 
 #include "thr_private.h"
 #include "thr_umtx.h"
 
+void
+_thr_umutex_init(struct umutex *mtx)
+{
+	static struct umutex default_mtx = DEFAULT_UMUTEX;
+
+	*mtx = default_mtx;
+}
+
 int
-__thr_umtx_lock(volatile umtx_t *mtx, long id)
+__thr_umutex_lock(struct umutex *mtx)
 {
-	while (_umtx_op((struct umtx *)mtx, UMTX_OP_LOCK, id, 0, 0))
-		;
-	return (0);
+	if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, 0) != -1)
+		return 0;
+	return (errno);
 }
 
 int
-__thr_umtx_timedlock(volatile umtx_t *mtx, long id,
+__thr_umutex_timedlock(struct umutex *mtx,
 	const struct timespec *timeout)
 {
 	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
 		timeout->tv_nsec <= 0)))
 		return (ETIMEDOUT);
-	if (_umtx_op((struct umtx *)mtx, UMTX_OP_LOCK, id, 0,
-		(void *)timeout) == 0)
+	if (_umtx_op(mtx, UMTX_OP_MUTEX_LOCK, 0, 0,
+		__DECONST(void *, timeout)) != -1)
+		return (0);
+	return (errno);
+}
+
+int
+__thr_umutex_unlock(struct umutex *mtx)
+{
+	if (_umtx_op(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0) != -1)
+		return (0);
+	return (errno);
+}
+
+int
+__thr_umutex_trylock(struct umutex *mtx)
+{
+	if (_umtx_op(mtx, UMTX_OP_MUTEX_TRYLOCK, 0, 0, 0) != -1)
 		return (0);
 	return (errno);
 }
 
 int
-__thr_umtx_unlock(volatile umtx_t *mtx, long id)
+__thr_umutex_set_ceiling(struct umutex *mtx, uint32_t ceiling,
+	uint32_t *oldceiling)
 {
-	if (_umtx_op((struct umtx *)mtx, UMTX_OP_UNLOCK, id, 0, 0) == 0)
+	if (_umtx_op(mtx, UMTX_OP_SET_CEILING, ceiling, oldceiling, 0) != -1)
 		return (0);
 	return (errno);
 }
@@ -65,8 +90,8 @@
 	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
 		timeout->tv_nsec <= 0)))
 		return (ETIMEDOUT);
-	if (_umtx_op((struct umtx *)mtx, UMTX_OP_WAIT, id, 0,
-		(void*) timeout) == 0)
+	if (_umtx_op(__DEVOLATILE(void *, mtx), UMTX_OP_WAIT, id, 0,
+		__DECONST(void*, timeout)) != -1)
 		return (0);
 	return (errno);
 }
@@ -74,7 +99,51 @@
 int
 _thr_umtx_wake(volatile umtx_t *mtx, int nr_wakeup)
 {
-	if (_umtx_op((struct umtx *)mtx, UMTX_OP_WAKE, nr_wakeup, 0, 0) == 0)
+	if (_umtx_op(__DEVOLATILE(void *, mtx), UMTX_OP_WAKE,
+		nr_wakeup, 0, 0) != -1)
+		return (0);
+	return (errno);
+}
+
+void
+_thr_ucond_init(struct ucond *cv)
+{
+	bzero(cv, sizeof(struct ucond));
+}
+
+int
+_thr_ucond_wait(struct ucond *cv, struct umutex *m,
+	const struct timespec *timeout, int check_unparking)
+{
+	if (timeout && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 &&
+	    timeout->tv_nsec <= 0))) {
+		__thr_umutex_unlock(m);
+                return (ETIMEDOUT);
+	}
+	if (_umtx_op(cv, UMTX_OP_CV_WAIT,
+		     check_unparking ? UMTX_CHECK_UNPARKING : 0, 
+		     m, __DECONST(void*, timeout)) != -1) {
+		return (0);
+	}
+	return (errno);
+}
+ 
+int
+_thr_ucond_signal(struct ucond *cv)
+{
+	if (!cv->c_has_waiters)
+		return (0);
+	if (_umtx_op(cv, UMTX_OP_CV_SIGNAL, 0, NULL, NULL) != -1)
+		return (0);
+	return (errno);
+}
+
+int
+_thr_ucond_broadcast(struct ucond *cv)
+{
+	if (!cv->c_has_waiters)
+		return (0);
+	if (_umtx_op(cv, UMTX_OP_CV_BROADCAST, 0, NULL, NULL) != -1)
 		return (0);
 	return (errno);
 }
Index: thr_barrierattr.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_barrierattr.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_barrierattr.c -L lib/libthr/thread/thr_barrierattr.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_barrierattr.c
+++ lib/libthr/thread/thr_barrierattr.c
@@ -25,12 +25,14 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_barrierattr.c,v 1.2 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_barrierattr.c,v 1.3 2006/04/04 02:57:49 davidxu Exp $
  */
 
+#include "namespace.h"
 #include <errno.h>
 #include <stdlib.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: Makefile.inc
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/Makefile.inc,v
retrieving revision 1.2
retrieving revision 1.3
diff -L lib/libthr/thread/Makefile.inc -L lib/libthr/thread/Makefile.inc -u -r1.2 -r1.3
--- lib/libthr/thread/Makefile.inc
+++ lib/libthr/thread/Makefile.inc
@@ -1,5 +1,4 @@
-# $MidnightBSD$
-# $FreeBSD: src/lib/libthr/thread/Makefile.inc,v 1.10.2.1 2006/01/16 05:36:30 davidxu Exp $
+# $FreeBSD: src/lib/libthr/thread/Makefile.inc,v 1.16 2006/04/04 02:57:49 davidxu Exp $
 
 # thr sources
 .PATH: ${.CURDIR}/thread
@@ -31,17 +30,15 @@
 	thr_multi_np.c \
 	thr_mutex.c \
 	thr_mutexattr.c \
-	thr_mutex_prioceiling.c \
-	thr_mutex_protocol.c \
 	thr_once.c \
 	thr_printf.c \
 	thr_pspinlock.c \
 	thr_resume_np.c \
+	thr_rtld.c \
 	thr_rwlock.c \
 	thr_rwlockattr.c \
 	thr_self.c \
 	thr_sem.c \
-	thr_seterrno.c \
 	thr_setprio.c \
 	thr_setschedparam.c \
 	thr_sig.c \
Index: thr_cancel.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_cancel.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_cancel.c -L lib/libthr/thread/thr_cancel.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_cancel.c
+++ lib/libthr/thread/thr_cancel.c
@@ -23,11 +23,13 @@
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_cancel.c,v 1.11 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_cancel.c,v 1.16 2006/12/05 05:01:57 davidxu Exp $
  *
  */
 
+#include "namespace.h"
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
@@ -36,128 +38,145 @@
 __weak_reference(_pthread_setcanceltype, pthread_setcanceltype);
 __weak_reference(_pthread_testcancel, pthread_testcancel);
 
-int _pthread_setcanceltype(int type, int *oldtype);
+static inline void
+testcancel(struct pthread *curthread)
+{
+	if (__predict_false(SHOULD_CANCEL(curthread) &&
+	    !THR_IN_CRITICAL(curthread) && curthread->cancel_defer == 0))
+		_pthread_exit(PTHREAD_CANCELED);
+}
+
+void
+_thr_testcancel(struct pthread *curthread)
+{
+	testcancel(curthread);
+}
 
 int
 _pthread_cancel(pthread_t pthread)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldval, newval = 0;
-	int oldtype;
 	int ret;
 
 	/*
-	 * POSIX says _pthread_cancel should be async cancellation safe,
-	 * so we temporarily disable async cancellation.
+	 * POSIX says _pthread_cancel should be async cancellation safe.
+	 * _thr_ref_add and _thr_ref_delete will enter and leave critical
+	 * region automatically.
 	 */
-	_pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype);
-	if ((ret = _thr_ref_add(curthread, pthread, 0)) != 0) {
-		_pthread_setcanceltype(oldtype, NULL);
-		return (ret);
-	}
-
-	do {
-		oldval = pthread->cancelflags;
-		if (oldval & THR_CANCEL_NEEDED)
-			break;
-		newval = oldval | THR_CANCEL_NEEDED;
-	} while (!atomic_cmpset_acq_int(&pthread->cancelflags, oldval, newval));
-
-	if (!(oldval & THR_CANCEL_NEEDED) && SHOULD_ASYNC_CANCEL(newval))
-		_thr_send_sig(pthread, SIGCANCEL);
-
-	_thr_ref_delete(curthread, pthread);
-	_pthread_setcanceltype(oldtype, NULL);
-	return (0);
-}
-
-static inline void
-testcancel(struct pthread *curthread)
-{
-	int newval;
-
-	newval = curthread->cancelflags;
-	if (SHOULD_CANCEL(newval))
-		pthread_exit(PTHREAD_CANCELED);
+	if ((ret = _thr_ref_add(curthread, pthread, 0)) == 0) {
+		THR_THREAD_LOCK(curthread, pthread);
+		if (!pthread->cancel_pending) {
+			pthread->cancel_pending = 1;
+			if (pthread->cancel_enable)
+				_thr_send_sig(pthread, SIGCANCEL);
+		}
+		THR_THREAD_UNLOCK(curthread, pthread);
+		_thr_ref_delete(curthread, pthread);
+	}
+	return (ret);
 }
 
 int
 _pthread_setcancelstate(int state, int *oldstate)
 {
 	struct pthread *curthread = _get_curthread();
-	int oldval, ret;
+	int oldval;
 
-	oldval = curthread->cancelflags;
-	if (oldstate != NULL)
-		*oldstate = ((oldval & THR_CANCEL_DISABLE) ?
-		    PTHREAD_CANCEL_DISABLE : PTHREAD_CANCEL_ENABLE);
+	oldval = curthread->cancel_enable;
 	switch (state) {
 	case PTHREAD_CANCEL_DISABLE:
-		atomic_set_int(&curthread->cancelflags, THR_CANCEL_DISABLE);
-		ret = 0;
+		THR_LOCK(curthread);
+		curthread->cancel_enable = 0;
+		THR_UNLOCK(curthread);
 		break;
 	case PTHREAD_CANCEL_ENABLE:
-		atomic_clear_int(&curthread->cancelflags, THR_CANCEL_DISABLE);
-		testcancel(curthread);
-		ret = 0;
+		THR_LOCK(curthread);
+		curthread->cancel_enable = 1;
+		THR_UNLOCK(curthread);
 		break;
 	default:
-		ret = EINVAL;
+		return (EINVAL);
 	}
 
-	return (ret);
+	if (oldstate) {
+		*oldstate = oldval ? PTHREAD_CANCEL_ENABLE :
+			PTHREAD_CANCEL_DISABLE;
+	}
+	return (0);
 }
 
 int
 _pthread_setcanceltype(int type, int *oldtype)
 {
 	struct pthread	*curthread = _get_curthread();
-	int oldval, ret;
+	int oldval;
 
-	oldval = curthread->cancelflags;
-	if (oldtype != NULL)
-		*oldtype = ((oldval & THR_CANCEL_AT_POINT) ?
-				 PTHREAD_CANCEL_ASYNCHRONOUS :
-				 PTHREAD_CANCEL_DEFERRED);
+	oldval = curthread->cancel_async;
 	switch (type) {
 	case PTHREAD_CANCEL_ASYNCHRONOUS:
-		atomic_set_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
+		curthread->cancel_async = 1;
 		testcancel(curthread);
-		ret = 0;
 		break;
 	case PTHREAD_CANCEL_DEFERRED:
-		atomic_clear_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
-		ret = 0;
+		curthread->cancel_async = 0;
 		break;
 	default:
-		ret = EINVAL;
+		return (EINVAL);
 	}
 
-	return (ret);
+	if (oldtype) {
+		*oldtype = oldval ? PTHREAD_CANCEL_ASYNCHRONOUS :
+		 	PTHREAD_CANCEL_DEFERRED;
+	}
+	return (0);
 }
 
 void
 _pthread_testcancel(void)
 {
-	testcancel(_get_curthread());
+	struct pthread *curthread = _get_curthread();
+
+	_thr_cancel_enter(curthread);
+	_thr_cancel_leave(curthread);
 }
 
-int
+void
 _thr_cancel_enter(struct pthread *curthread)
 {
-	int oldval;
+	if (curthread->cancel_enable) {
+		curthread->cancel_point++;
+		testcancel(curthread);
+	}
+}
+
+void
+_thr_cancel_leave(struct pthread *curthread)
+{
+	if (curthread->cancel_enable)
+		curthread->cancel_point--;
+}
 
-	oldval = curthread->cancelflags;
-	if (!(oldval & THR_CANCEL_AT_POINT)) {
-		atomic_set_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
+void
+_thr_cancel_enter_defer(struct pthread *curthread)
+{
+	if (curthread->cancel_enable) {
+		curthread->cancel_point++;
 		testcancel(curthread);
+		curthread->cancel_defer++;
 	}
-	return (oldval);
 }
 
 void
-_thr_cancel_leave(struct pthread *curthread, int previous)
+_thr_cancel_leave_defer(struct pthread *curthread, int check)
 {
-	if (!(previous & THR_CANCEL_AT_POINT))
-		atomic_clear_int(&curthread->cancelflags, THR_CANCEL_AT_POINT);
+	if (curthread->cancel_enable) {
+		if (!check) {
+			curthread->cancel_point--;
+			curthread->cancel_defer--;
+		} else {
+			curthread->cancel_defer--;
+			testcancel(curthread);
+			curthread->cancel_point--;
+		}
+	}
 }
Index: thr_clean.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_clean.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_clean.c -L lib/libthr/thread/thr_clean.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_clean.c
+++ lib/libthr/thread/thr_clean.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,13 +26,15 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_clean.c,v 1.3 2005/04/02 01:20:00 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_clean.c,v 1.5 2007/01/12 07:26:20 imp Exp $
  */
 
+#include "namespace.h"
 #include <signal.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <pthread.h>
+#include "un-namespace.h"
 
 #include "thr_private.h"
 
Index: thr_mutexattr.c
===================================================================
RCS file: /home/cvs/src/lib/libthr/thread/thr_mutexattr.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L lib/libthr/thread/thr_mutexattr.c -L lib/libthr/thread/thr_mutexattr.c -u -r1.1.1.1 -r1.2
--- lib/libthr/thread/thr_mutexattr.c
+++ lib/libthr/thread/thr_mutexattr.c
@@ -10,10 +10,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -29,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.1.2.1 2005/12/15 06:31:43 davidxu Exp $
+ * $FreeBSD: src/lib/libthr/thread/thr_mutexattr.c,v 1.7 2007/01/12 07:26:20 imp Exp $
  */
 
 /*
@@ -44,10 +41,7 @@
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *	This product includes software developed by John Birrell.
- * 4. Neither the name of the author nor the names of any co-contributors
+ * 3. Neither the name of the author nor the names of any co-contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
@@ -65,10 +59,14 @@
  *
  */
 
+#include "namespace.h"
 #include <string.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <pthread.h>
+#include <pthread_np.h>
+#include "un-namespace.h"
+
 #include "thr_private.h"
 
 __weak_reference(_pthread_mutexattr_init, pthread_mutexattr_init);
@@ -79,6 +77,10 @@
 __weak_reference(_pthread_mutexattr_destroy, pthread_mutexattr_destroy);
 __weak_reference(_pthread_mutexattr_getpshared, pthread_mutexattr_getpshared);
 __weak_reference(_pthread_mutexattr_setpshared, pthread_mutexattr_setpshared);
+__weak_reference(_pthread_mutexattr_getprotocol, pthread_mutexattr_getprotocol);
+__weak_reference(_pthread_mutexattr_setprotocol, pthread_mutexattr_setprotocol);
+__weak_reference(_pthread_mutexattr_getprioceiling, pthread_mutexattr_getprioceiling);
+__weak_reference(_pthread_mutexattr_setprioceiling, pthread_mutexattr_setprioceiling);
 
 int
 _pthread_mutexattr_init(pthread_mutexattr_t *attr)
@@ -129,7 +131,7 @@
 _pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
 {
 	int	ret;
-	if (attr == NULL || *attr == NULL || type >= MUTEX_TYPE_MAX) {
+	if (attr == NULL || *attr == NULL || type >= PTHREAD_MUTEX_TYPE_MAX) {
 		errno = EINVAL;
 		ret = -1;
 	} else {
@@ -145,7 +147,7 @@
 	int	ret;
 
 	if (attr == NULL || *attr == NULL || (*attr)->m_type >=
-	    MUTEX_TYPE_MAX) {
+	    PTHREAD_MUTEX_TYPE_MAX) {
 		ret = EINVAL;
 	} else {
 		*type = (*attr)->m_type;
@@ -193,3 +195,62 @@
 
 	return (0);
 }
+
+int
+_pthread_mutexattr_getprotocol(pthread_mutexattr_t *mattr, int *protocol)
+{
+	int ret = 0;
+
+	if ((mattr == NULL) || (*mattr == NULL))
+		ret = EINVAL;
+	else
+		*protocol = (*mattr)->m_protocol;
+
+	return(ret);
+}
+
+int
+_pthread_mutexattr_setprotocol(pthread_mutexattr_t *mattr, int protocol)
+{
+	int ret = 0;
+
+	if ((mattr == NULL) || (*mattr == NULL) ||
+	    (protocol < PTHREAD_PRIO_NONE) || (protocol > PTHREAD_PRIO_PROTECT))
+		ret = EINVAL;
+	else {
+		(*mattr)->m_protocol = protocol;
+		(*mattr)->m_ceiling = THR_MAX_RR_PRIORITY;
+	}
+	return(ret);
+}
+
+int
+_pthread_mutexattr_getprioceiling(pthread_mutexattr_t *mattr, int *prioceiling)
+{
+	int ret = 0;
+
+	if ((mattr == NULL) || (*mattr == NULL))
+		ret = EINVAL;
+	else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+		ret = EINVAL;
+	else
+		*prioceiling = (*mattr)->m_ceiling;
+
+	return(ret);
+}
+
+int
+_pthread_mutexattr_setprioceiling(pthread_mutexattr_t *mattr, int prioceiling)
+{
+	int ret = 0;
+
+	if ((mattr == NULL) || (*mattr == NULL))
+		ret = EINVAL;
+	else if ((*mattr)->m_protocol != PTHREAD_PRIO_PROTECT)
+		ret = EINVAL;
+	else
+		(*mattr)->m_ceiling = prioceiling;
+
+	return(ret);
+}
+


More information about the Midnightbsd-cvs mailing list