[Midnightbsd-cvs] src [10633] trunk/lib/libthr/thread: sync with freebsd

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Sat Jun 9 12:42:32 EDT 2018


Revision: 10633
          http://svnweb.midnightbsd.org/src/?rev=10633
Author:   laffer1
Date:     2018-06-09 12:42:31 -0400 (Sat, 09 Jun 2018)
Log Message:
-----------
sync with freebsd

Modified Paths:
--------------
    trunk/lib/libthr/thread/thr_affinity.c
    trunk/lib/libthr/thread/thr_attr.c
    trunk/lib/libthr/thread/thr_autoinit.c
    trunk/lib/libthr/thread/thr_barrier.c
    trunk/lib/libthr/thread/thr_barrierattr.c
    trunk/lib/libthr/thread/thr_cancel.c
    trunk/lib/libthr/thread/thr_clean.c
    trunk/lib/libthr/thread/thr_concurrency.c
    trunk/lib/libthr/thread/thr_cond.c
    trunk/lib/libthr/thread/thr_condattr.c
    trunk/lib/libthr/thread/thr_create.c
    trunk/lib/libthr/thread/thr_detach.c
    trunk/lib/libthr/thread/thr_equal.c
    trunk/lib/libthr/thread/thr_event.c
    trunk/lib/libthr/thread/thr_exit.c
    trunk/lib/libthr/thread/thr_fork.c
    trunk/lib/libthr/thread/thr_getcpuclockid.c
    trunk/lib/libthr/thread/thr_getprio.c
    trunk/lib/libthr/thread/thr_getschedparam.c
    trunk/lib/libthr/thread/thr_getthreadid_np.c
    trunk/lib/libthr/thread/thr_info.c
    trunk/lib/libthr/thread/thr_init.c
    trunk/lib/libthr/thread/thr_join.c
    trunk/lib/libthr/thread/thr_kern.c
    trunk/lib/libthr/thread/thr_kill.c
    trunk/lib/libthr/thread/thr_list.c
    trunk/lib/libthr/thread/thr_main_np.c
    trunk/lib/libthr/thread/thr_multi_np.c
    trunk/lib/libthr/thread/thr_mutex.c
    trunk/lib/libthr/thread/thr_mutexattr.c
    trunk/lib/libthr/thread/thr_once.c
    trunk/lib/libthr/thread/thr_printf.c
    trunk/lib/libthr/thread/thr_private.h
    trunk/lib/libthr/thread/thr_pspinlock.c
    trunk/lib/libthr/thread/thr_resume_np.c
    trunk/lib/libthr/thread/thr_rtld.c
    trunk/lib/libthr/thread/thr_rwlock.c
    trunk/lib/libthr/thread/thr_rwlockattr.c
    trunk/lib/libthr/thread/thr_self.c
    trunk/lib/libthr/thread/thr_sem.c
    trunk/lib/libthr/thread/thr_setprio.c
    trunk/lib/libthr/thread/thr_setschedparam.c
    trunk/lib/libthr/thread/thr_sig.c
    trunk/lib/libthr/thread/thr_single_np.c
    trunk/lib/libthr/thread/thr_sleepq.c
    trunk/lib/libthr/thread/thr_spec.c
    trunk/lib/libthr/thread/thr_spinlock.c
    trunk/lib/libthr/thread/thr_stack.c
    trunk/lib/libthr/thread/thr_suspend_np.c
    trunk/lib/libthr/thread/thr_switch_np.c
    trunk/lib/libthr/thread/thr_symbols.c
    trunk/lib/libthr/thread/thr_syscalls.c
    trunk/lib/libthr/thread/thr_umtx.c
    trunk/lib/libthr/thread/thr_umtx.h
    trunk/lib/libthr/thread/thr_yield.c

Modified: trunk/lib/libthr/thread/thr_affinity.c
===================================================================
--- trunk/lib/libthr/thread/thr_affinity.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_affinity.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2008, David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_affinity.c 212552 2010-09-13 11:58:42Z davidxu $
  *
  */
 

Modified: trunk/lib/libthr/thread/thr_attr.c
===================================================================
--- trunk/lib/libthr/thread/thr_attr.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_attr.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2003 Craig Rodrigues <rodrigc at attbi.com>.
  * All rights reserved.
@@ -90,7 +91,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_attr.c 214653 2010-11-02 02:13:13Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_autoinit.c
===================================================================
--- trunk/lib/libthr/thread/thr_autoinit.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_autoinit.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2002 Alfred Perlstein <alfred at freebsd.org>.
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
@@ -30,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_autoinit.c 115260 2003-05-23 09:48:20Z mtm $
  */
 
 #include <pthread.h>

Modified: trunk/lib/libthr/thread/thr_barrier.c
===================================================================
--- trunk/lib/libthr/thread/thr_barrier.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_barrier.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_barrier.c 321833 2017-08-01 01:25:18Z pfg $
  */
 
 #include "namespace.h"
@@ -42,13 +43,34 @@
 _pthread_barrier_destroy(pthread_barrier_t *barrier)
 {
 	pthread_barrier_t	bar;
+	struct pthread		*curthread;
 
 	if (barrier == NULL || *barrier == NULL)
 		return (EINVAL);
 
+	curthread = _get_curthread();
 	bar = *barrier;
-	if (bar->b_waiters > 0)
+	THR_UMUTEX_LOCK(curthread, &bar->b_lock);
+	if (bar->b_destroying) {
+		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
 		return (EBUSY);
+	}
+	bar->b_destroying = 1;
+	do {
+		if (bar->b_waiters > 0) {
+			bar->b_destroying = 0;
+			THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
+			return (EBUSY);
+		}
+		if (bar->b_refcount != 0) {
+			_thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
+			THR_UMUTEX_LOCK(curthread, &bar->b_lock);
+		} else
+			break;
+	} while (1);
+	bar->b_destroying = 0;
+	THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
+
 	*barrier = NULL;
 	free(bar);
 	return (0);
@@ -62,17 +84,15 @@
 
 	(void)attr;
 
-	if (barrier == NULL || count <= 0)
+	if (barrier == NULL || count == 0 || count > INT_MAX)
 		return (EINVAL);
 
-	bar = malloc(sizeof(struct pthread_barrier));
+	bar = calloc(1, sizeof(struct pthread_barrier));
 	if (bar == NULL)
 		return (ENOMEM);
 
 	_thr_umutex_init(&bar->b_lock);
 	_thr_ucond_init(&bar->b_cv);
-	bar->b_cycle	= 0;
-	bar->b_waiters	= 0;
 	bar->b_count	= count;
 	*barrier	= bar;
 
@@ -101,11 +121,14 @@
 		ret = PTHREAD_BARRIER_SERIAL_THREAD;
 	} else {
 		cycle = bar->b_cycle;
+		bar->b_refcount++;
 		do {
 			_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);
+		if (--bar->b_refcount == 0 && bar->b_destroying)
+			_thr_ucond_broadcast(&bar->b_cv);
 		THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
 		ret = 0;
 	}

Modified: trunk/lib/libthr/thread/thr_barrierattr.c
===================================================================
--- trunk/lib/libthr/thread/thr_barrierattr.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_barrierattr.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2003 David Xu <davidxu at freebsd.org>.
  * All rights reserved.
@@ -25,7 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  * DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_barrierattr.c 157457 2006-04-04 02:57:49Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_cancel.c
===================================================================
--- trunk/lib/libthr/thread/thr_cancel.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_cancel.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005, David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_cancel.c 332633 2018-04-16 20:45:21Z jhb $
  *
  */
 
@@ -130,8 +131,10 @@
 void
 _pthread_testcancel(void)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 
+	_thr_check_init();
+	curthread = _get_curthread();
 	testcancel(curthread);
 }
 

Modified: trunk/lib/libthr/thread/thr_clean.c
===================================================================
--- trunk/lib/libthr/thread/thr_clean.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_clean.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_clean.c 282224 2015-04-29 15:33:07Z pfg $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_concurrency.c
===================================================================
--- trunk/lib/libthr/thread/thr_concurrency.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_concurrency.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2003 Sergey Osokin <osa at FreeBSD.org.ru>.
  * All rights reserved.
@@ -29,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_concurrency.c 157457 2006-04-04 02:57:49Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_cond.c
===================================================================
--- trunk/lib/libthr/thread/thr_cond.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_cond.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_cond.c 239206 2012-08-12 00:56:56Z davidxu $
  */
 
 #include "namespace.h"
@@ -217,6 +218,7 @@
 	struct sleepqueue *sq;
 	int	recurse;
 	int	error;
+	int	defered;
 
 	if (curthread->wchan != NULL)
 		PANIC("thread was already on queue.");
@@ -230,13 +232,24 @@
 	 * us to check it without locking in pthread_cond_signal().
 	 */
 	cvp->__has_user_waiters = 1; 
-	curthread->will_sleep = 1;
-	(void)_mutex_cv_unlock(mp, &recurse);
+	defered = 0;
+	(void)_mutex_cv_unlock(mp, &recurse, &defered);
 	curthread->mutex_obj = mp;
 	_sleepq_add(cvp, curthread);
 	for(;;) {
 		_thr_clear_wake(curthread);
 		_sleepq_unlock(cvp);
+		if (defered) {
+			defered = 0;
+			if ((mp->m_lock.m_owner & UMUTEX_CONTESTED) == 0)
+				(void)_umtx_op_err(&mp->m_lock, UMTX_OP_MUTEX_WAKE2,
+					 mp->m_lock.m_flags, 0, 0);
+		}
+		if (curthread->nwaiter_defer > 0) {
+			_thr_wake_all(curthread->defer_waiters,
+				curthread->nwaiter_defer);
+			curthread->nwaiter_defer = 0;
+		}
 
 		if (cancel) {
 			_thr_cancel_enter2(curthread, 0);

Modified: trunk/lib/libthr/thread/thr_condattr.c
===================================================================
--- trunk/lib/libthr/thread/thr_condattr.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_condattr.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1997 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_condattr.c 208503 2010-05-24 13:44:39Z deischen $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_create.c
===================================================================
--- trunk/lib/libthr/thread/thr_create.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_create.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2003 Daniel M. Eischen <deischen at gdeb.com>
  * Copyright (c) 2005, David Xu <davidxu at freebsd.org>
@@ -24,7 +25,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_create.c 277317 2015-01-18 11:54:20Z kib $
  */
 
 #include "namespace.h"
@@ -40,6 +41,7 @@
 #include <pthread_np.h>
 #include "un-namespace.h"
 
+#include "libc_private.h"
 #include "thr_private.h"
 
 static int  create_stack(struct pthread_attr *pattr);
@@ -66,8 +68,11 @@
 	/*
 	 * Tell libc and others now they need lock to protect their data.
 	 */
-	if (_thr_isthreaded() == 0 && _thr_setthreaded(1))
-		return (EAGAIN);
+	if (_thr_isthreaded() == 0) {
+		_malloc_first_thread();
+		if (_thr_setthreaded(1))
+			return (EAGAIN);
+	}
 
 	curthread = _get_curthread();
 	if ((new_thread = _thr_alloc(curthread)) == NULL)

Modified: trunk/lib/libthr/thread/thr_detach.c
===================================================================
--- trunk/lib/libthr/thread/thr_detach.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_detach.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * Copyright (C) 2003 Daniel M. Eischen <deischen at freebsd.org>
@@ -24,7 +25,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_detach.c 212536 2010-09-13 07:03:01Z davidxu $
  *
  */
 

Modified: trunk/lib/libthr/thread/thr_equal.c
===================================================================
--- trunk/lib/libthr/thread/thr_equal.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_equal.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_equal.c 165967 2007-01-12 07:26:21Z imp $
  */
 #include "namespace.h"
 #include <pthread.h>

Modified: trunk/lib/libthr/thread/thr_event.c
===================================================================
--- trunk/lib/libthr/thread/thr_event.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_event.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_event.c 183021 2008-09-14 16:07:21Z marcel $
  */
 
 #include "thr_private.h"

Modified: trunk/lib/libthr/thread/thr_exit.c
===================================================================
--- trunk/lib/libthr/thread/thr_exit.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_exit.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995-1998 John Birrell <jb at cimlogic.com.au>
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_exit.c 304527 2016-08-20 12:26:44Z kib $
  */
 
 #include "namespace.h"
@@ -151,8 +152,12 @@
 		__pthread_cleanup_pop_imp(1);
 	}
 
-	if (done)
+	if (done) {
+		/* Tell libc that it should call non-trivial TLS dtors. */
+		__cxa_thread_call_dtors();
+
 		exit_thread(); /* Never return! */
+	}
 
 	return (_URC_NO_REASON);
 }
@@ -246,6 +251,8 @@
 		while (curthread->cleanup != NULL) {
 			__pthread_cleanup_pop_imp(1);
 		}
+		__cxa_thread_call_dtors();
+
 		exit_thread();
 	}
 
@@ -253,6 +260,7 @@
 	while (curthread->cleanup != NULL) {
 		__pthread_cleanup_pop_imp(1);
 	}
+	__cxa_thread_call_dtors();
 
 	exit_thread();
 #endif /* _PTHREAD_FORCED_UNWIND */

Modified: trunk/lib/libthr/thread/thr_fork.c
===================================================================
--- trunk/lib/libthr/thread/thr_fork.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_fork.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * Copyright (c) 2003 Daniel Eischen <deischen at freebsd.org>
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_fork.c 277317 2015-01-18 11:54:20Z kib $
  */
 
 /*
@@ -57,6 +58,7 @@
  *
  */
 
+#include <sys/syscall.h>
 #include "namespace.h"
 #include <errno.h>
 #include <link.h>
@@ -127,12 +129,10 @@
 	_thr_sigact_unload(phdr_info);
 }
 
-__weak_reference(_fork, fork);
+__weak_reference(__thr_fork, _fork);
 
-pid_t _fork(void);
-
 pid_t
-_fork(void)
+__thr_fork(void)
 {
 	struct pthread *curthread;
 	struct pthread_atfork *af;
@@ -174,8 +174,15 @@
 		was_threaded = 0;
 	}
 
-	/* Fork a new process: */
-	if ((ret = __sys_fork()) == 0) {
+	/*
+	 * Fork a new process.
+	 * There is no easy way to pre-resolve the __sys_fork symbol
+	 * without performing the fork.  Use the syscall(2)
+	 * indirection, the syscall symbol is resolved in
+	 * _thr_rtld_init() with side-effect free call.
+	 */
+	ret = syscall(SYS_fork);
+	if (ret == 0) {
 		/* Child process */
 		errsave = errno;
 		curthread->cancel_pending = 0;
@@ -200,9 +207,6 @@
 			_rtld_atfork_post(rtld_locks);
 		_thr_setthreaded(0);
 
-		/* reinitialize libc spinlocks. */
-		_thr_spinlock_init();
-
 		/* reinitalize library. */
 		_libpthread_init(curthread);
 
@@ -253,6 +257,5 @@
 	}
 	errno = errsave;
 
-	/* Return the process ID: */
 	return (ret);
 }

Modified: trunk/lib/libthr/thread/thr_getcpuclockid.c
===================================================================
--- trunk/lib/libthr/thread/thr_getcpuclockid.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_getcpuclockid.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2008 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_getcpuclockid.c 239347 2012-08-17 02:26:31Z davidxu $
  */
 
 #include "namespace.h"
@@ -39,9 +40,11 @@
 int
 _pthread_getcpuclockid(pthread_t pthread, clockid_t *clock_id)
 {
+
 	if (pthread == NULL)
 		return (EINVAL);
 
-	*clock_id = CLOCK_THREAD_CPUTIME_ID;
+	if (clock_getcpuclockid2(TID(pthread), CPUCLOCK_WHICH_TID, clock_id))
+		return (errno);
 	return (0);
 }

Modified: trunk/lib/libthr/thread/thr_getprio.c
===================================================================
--- trunk/lib/libthr/thread/thr_getprio.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_getprio.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_getprio.c 165967 2007-01-12 07:26:21Z imp $
  */
 #include "namespace.h"
 #include <errno.h>

Modified: trunk/lib/libthr/thread/thr_getschedparam.c
===================================================================
--- trunk/lib/libthr/thread/thr_getschedparam.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_getschedparam.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1998 Daniel Eischen <eischen at vigrid.com>.
  * All rights reserved.
@@ -29,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_getschedparam.c 238645 2012-07-20 05:47:12Z davidxu $
  */
 
 #include "namespace.h"
@@ -48,30 +49,21 @@
 	struct sched_param *param)
 {
 	struct pthread *curthread = _get_curthread();
-	int ret;
+	int ret = 0;
 
 	if (policy == NULL || param == NULL)
 		return (EINVAL);
 
-	if (pthread == curthread) {
-		/*
-		 * Avoid searching the thread list when it is the current
-		 * thread.
-		 */
+	/*
+	 * Avoid searching the thread list when it is the current
+	 * thread.
+	 */
+	if (pthread == curthread)
 		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);
-		*policy = pthread->attr.sched_policy;
-		param->sched_priority = pthread->attr.prio;
-		THR_THREAD_UNLOCK(curthread, pthread);
-		_thr_ref_delete(curthread, pthread);
-	}
+	else if ((ret = _thr_find_thread(curthread, pthread, /*include dead*/0)))
+		return (ret);
+	*policy = pthread->attr.sched_policy;
+	param->sched_priority = pthread->attr.prio;
+	THR_THREAD_UNLOCK(curthread, pthread);
 	return (ret);
 }

Modified: trunk/lib/libthr/thread/thr_getthreadid_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_getthreadid_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_getthreadid_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2011 Jung-uk Kim <jkim at FreeBSD.org>
  *
@@ -22,7 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_getthreadid_np.c 218414 2011-02-07 21:26:46Z jkim $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_info.c
===================================================================
--- trunk/lib/libthr/thread/thr_info.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_info.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995-1998 John Birrell <jb at cimlogic.com.au>
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_info.c 238644 2012-07-20 03:37:19Z davidxu $
  */
 
 #include "namespace.h"
@@ -51,16 +52,12 @@
 		if (thr_set_name(thread->tid, name))
 			ret = errno;
 	} else {
-		if (_thr_ref_add(curthread, thread, 0) == 0) {
-			THR_THREAD_LOCK(curthread, thread);
+		if ((ret=_thr_find_thread(curthread, thread, 0)) == 0) {
 			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 0

Modified: trunk/lib/libthr/thread/thr_init.c
===================================================================
--- trunk/lib/libthr/thread/thr_init.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_init.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2003 Daniel M. Eischen <deischen at freebsd.org>
  * Copyright (c) 1995-1998 John Birrell <jb at cimlogic.com.au>
@@ -30,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_init.c 303709 2016-08-03 10:23:42Z kib $
  */
 
 #include "namespace.h"
@@ -37,6 +38,8 @@
 #include <sys/types.h>
 #include <sys/signalvar.h>
 #include <sys/ioctl.h>
+#include <sys/link_elf.h>
+#include <sys/resource.h>
 #include <sys/sysctl.h>
 #include <sys/ttycom.h>
 #include <sys/mman.h>
@@ -104,7 +107,6 @@
 	.c_clockid = CLOCK_REALTIME
 };
 
-pid_t		_thr_pid;
 int		_thr_is_smp = 0;
 size_t		_thr_guard_default;
 size_t		_thr_stack_default = THR_STACK_DEFAULT;
@@ -112,6 +114,7 @@
 int		_thr_page_size;
 int		_thr_spinloops;
 int		_thr_yieldloops;
+int		_thr_queuefifo = 4;
 int		_gc_count;
 struct umutex	_mutex_static_lock = DEFAULT_UMUTEX;
 struct umutex	_cond_static_lock = DEFAULT_UMUTEX;
@@ -119,6 +122,10 @@
 struct umutex	_keytable_lock = DEFAULT_UMUTEX;
 struct urwlock	_thr_list_lock = DEFAULT_URWLOCK;
 struct umutex	_thr_event_lock = DEFAULT_UMUTEX;
+struct umutex	_suspend_all_lock = DEFAULT_UMUTEX;
+struct pthread	*_single_thread;
+int		_suspend_all_cycle;
+int		_suspend_all_waiters;
 
 int	__pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *);
 int	__pthread_mutex_lock(pthread_mutex_t *);
@@ -296,7 +303,7 @@
 void
 _libpthread_init(struct pthread *curthread)
 {
-	int fd, first = 0;
+	int first, dlopened;
 
 	/* Check if this function has already been called: */
 	if ((_thr_initial != NULL) && (curthread == NULL))
@@ -310,28 +317,8 @@
 	if (sizeof(jmp_table) != (sizeof(pthread_func_t) * PJT_MAX * 2))
 		PANIC("Thread jump table not properly initialized");
 	memcpy(__thr_jtable, jmp_table, sizeof(jmp_table));
+	__thr_interpose_libc();
 
-	/*
-	 * Check for the special case of this process running as
-	 * or in place of init as pid = 1:
-	 */
-	if ((_thr_pid = getpid()) == 1) {
-		/*
-		 * Setup a new session for this process which is
-		 * assumed to be running as root.
-		 */
-		if (setsid() == -1)
-			PANIC("Can't set session ID");
-		if (revoke(_PATH_CONSOLE) != 0)
-			PANIC("Can't revoke console");
-		if ((fd = __sys_open(_PATH_CONSOLE, O_RDWR)) < 0)
-			PANIC("Can't open console");
-		if (setlogin("root") == -1)
-			PANIC("Can't set login to root");
-		if (_ioctl(fd, TIOCSCTTY, (char *) NULL) == -1)
-			PANIC("Can't set controlling terminal");
-	}
-
 	/* Initialize pthread private data. */
 	init_private();
 
@@ -343,7 +330,10 @@
 		if (curthread == NULL)
 			PANIC("Can't allocate initial thread");
 		init_main_thread(curthread);
+	} else {
+		first = 0;
 	}
+		
 	/*
 	 * Add the thread to the thread list queue.
 	 */
@@ -355,9 +345,16 @@
 
 	if (first) {
 		_thr_initial = curthread;
-		_thr_signal_init();
+		dlopened = _rtld_is_dlopened(&_thread_autoinit_dummy_decl) != 0;
+		_thr_signal_init(dlopened);
 		if (_thread_event_mask & TD_CREATE)
 			_thr_report_creation(curthread, curthread);
+		/*
+		 * Always use our rtld lock implementation.
+		 * It is faster because it postpones signal handlers
+		 * instead of calling sigprocmask(2).
+		 */
+		_thr_rtld_init();
 	}
 }
 
@@ -430,9 +427,10 @@
 static void
 init_private(void)
 {
+	struct rlimit rlim;
 	size_t len;
 	int mib[2];
-	char *env;
+	char *env, *env_bigstack, *env_splitstack;
 
 	_thr_umutex_init(&_mutex_static_lock);
 	_thr_umutex_init(&_cond_static_lock);
@@ -440,11 +438,13 @@
 	_thr_umutex_init(&_keytable_lock);
 	_thr_urwlock_init(&_thr_atfork_lock);
 	_thr_umutex_init(&_thr_event_lock);
-	_thr_once_init();
+	_thr_umutex_init(&_suspend_all_lock);
 	_thr_spinlock_init();
 	_thr_list_init();
 	_thr_wake_addr_init();
 	_sleepq_init();
+	_single_thread = NULL;
+	_suspend_all_waiters = 0;
 
 	/*
 	 * Avoid reinitializing some things if they don't need to be,
@@ -457,6 +457,13 @@
 		len = sizeof (_usrstack);
 		if (sysctl(mib, 2, &_usrstack, &len, NULL, 0) == -1)
 			PANIC("Cannot get kern.usrstack from sysctl");
+		env_bigstack = getenv("LIBPTHREAD_BIGSTACK_MAIN");
+		env_splitstack = getenv("LIBPTHREAD_SPLITSTACK_MAIN");
+		if (env_bigstack != NULL || env_splitstack == NULL) {
+			if (getrlimit(RLIMIT_STACK, &rlim) == -1)
+				PANIC("Cannot get stack rlimit");
+			_thr_stack_initial = rlim.rlim_cur;
+		}
 		len = sizeof(_thr_is_smp);
 		sysctlbyname("kern.smp.cpus", &_thr_is_smp, &len, NULL, 0);
 		_thr_is_smp = (_thr_is_smp > 1);
@@ -470,6 +477,9 @@
 		env = getenv("LIBPTHREAD_YIELDLOOPS");
 		if (env)
 			_thr_yieldloops = atoi(env);
+		env = getenv("LIBPTHREAD_QUEUE_FIFO");
+		if (env)
+			_thr_queuefifo = atoi(env);
 		TAILQ_INIT(&_thr_atfork_list);
 	}
 	init_once = 1;

Modified: trunk/lib/libthr/thread/thr_join.c
===================================================================
--- trunk/lib/libthr/thread/thr_join.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_join.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005, David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_join.c 212840 2010-09-19 08:55:36Z davidxu $
  *
  */
 

Modified: trunk/lib/libthr/thread/thr_kern.c
===================================================================
--- trunk/lib/libthr/thread/thr_kern.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_kern.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * Copyright (C) 2003 Daniel M. Eischen <deischen at freebsd.org>
@@ -24,7 +25,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_kern.c 245630 2013-01-18 23:08:40Z jilles $
  */
 
 #include <sys/types.h>
@@ -57,11 +58,6 @@
 		return (0);
 
 	__isthreaded = threaded;
-	if (threaded != 0) {
-		_thr_rtld_init();
-	} else {
-		_thr_rtld_fini();
-	}
 	return (0);
 }
 
@@ -199,13 +195,6 @@
 	const struct timespec *abstime)
 {
 
-	curthread->will_sleep = 0;
-	if (curthread->nwaiter_defer > 0) {
-		_thr_wake_all(curthread->defer_waiters,
-			curthread->nwaiter_defer);
-		curthread->nwaiter_defer = 0;
-	}
-
 	if (curthread->wake_addr->value != 0)
 		return (0);
 

Modified: trunk/lib/libthr/thread/thr_kill.c
===================================================================
--- trunk/lib/libthr/thread/thr_kill.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_kill.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1997 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_kill.c 261636 2014-02-08 15:51:24Z kib $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_list.c
===================================================================
--- trunk/lib/libthr/thread/thr_list.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_list.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * Copyright (C) 2003 Daniel M. Eischen <deischen at freebsd.org>
@@ -24,7 +25,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_list.c 231503 2012-02-11 04:12:12Z davidxu $
  */
 
 #include <sys/types.h>

Modified: trunk/lib/libthr/thread/thr_main_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_main_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_main_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2001 Alfred Perlstein
  * Author: Alfred Perlstein <alfred at FreeBSD.org>
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_main_np.c 157457 2006-04-04 02:57:49Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_multi_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_multi_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_multi_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1996 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_multi_np.c 165967 2007-01-12 07:26:21Z imp $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_mutex.c
===================================================================
--- trunk/lib/libthr/thread/thr_mutex.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_mutex.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * Copyright (c) 2006 David Xu <davidxu at freebsd.org>.
@@ -30,7 +31,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_mutex.c 279586 2015-03-04 09:32:59Z kib $
  */
 
 #include "namespace.h"
@@ -92,7 +93,7 @@
 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(struct pthread_mutex *, int);
+static int	mutex_unlock_common(struct pthread_mutex *, int, int *);
 static int	mutex_lock_sleep(struct pthread *, pthread_mutex_t,
 				const struct timespec *);
 
@@ -461,7 +462,7 @@
 	struct pthread_mutex *mp;
 
 	mp = *mutex;
-	return (mutex_unlock_common(mp, 0));
+	return (mutex_unlock_common(mp, 0, NULL));
 }
 
 int
@@ -476,7 +477,7 @@
 }
 
 int
-_mutex_cv_unlock(struct pthread_mutex *m, int *count)
+_mutex_cv_unlock(struct pthread_mutex *m, int *count, int *defer)
 {
 
 	/*
@@ -484,7 +485,7 @@
 	 */
 	*count = m->m_count;
 	m->m_count = 0;
-	(void)mutex_unlock_common(m, 1);
+	(void)mutex_unlock_common(m, 1, defer);
         return (0);
 }
 
@@ -629,11 +630,11 @@
 }
 
 static int
-mutex_unlock_common(struct pthread_mutex *m, int cv)
+mutex_unlock_common(struct pthread_mutex *m, int cv, int *mtx_defer)
 {
 	struct pthread *curthread = _get_curthread();
 	uint32_t id;
-	int defered;
+	int defered, error;
 
 	if (__predict_false(m <= THR_MUTEX_DESTROYED)) {
 		if (m == THR_MUTEX_DESTROYED)
@@ -647,6 +648,7 @@
 	if (__predict_false(m->m_owner != curthread))
 		return (EPERM);
 
+	error = 0;
 	id = TID(curthread);
 	if (__predict_false(
 		PMUTEX_TYPE(m->m_flags) == PTHREAD_MUTEX_RECURSIVE &&
@@ -657,12 +659,12 @@
 			defered = 1;
 			m->m_flags &= ~PMUTEX_FLAG_DEFERED;
         	} else
-                	defered = 0;
+			defered = 0;
 
 		DEQUEUE_MUTEX(curthread, m);
-		_thr_umutex_unlock(&m->m_lock, id);
+		error = _thr_umutex_unlock2(&m->m_lock, id, mtx_defer);
 
-		if (curthread->will_sleep == 0 && defered)  {
+		if (mtx_defer == NULL && defered)  {
 			_thr_wake_all(curthread->defer_waiters,
 				curthread->nwaiter_defer);
 			curthread->nwaiter_defer = 0;
@@ -670,7 +672,7 @@
 	}
 	if (!cv && m->m_flags & PMUTEX_FLAG_PRIVATE)
 		THR_CRITICAL_LEAVE(curthread);
-	return (0);
+	return (error);
 }
 
 int

Modified: trunk/lib/libthr/thread/thr_mutexattr.c
===================================================================
--- trunk/lib/libthr/thread/thr_mutexattr.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_mutexattr.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1996 Jeffrey Hsu <hsu at freebsd.org>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_mutexattr.c 177451 2008-03-20 11:47:08Z ru $
  */
 
 /*

Modified: trunk/lib/libthr/thread/thr_once.c
===================================================================
--- trunk/lib/libthr/thread/thr_once.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_once.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005, David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_once.c 303709 2016-08-03 10:23:42Z kib $
  *
  */
 
@@ -92,8 +93,3 @@
 	_thr_umtx_wake(&once_control->state, INT_MAX, 0);
 	return (0);
 }
-
-void
-_thr_once_init()
-{
-}

Modified: trunk/lib/libthr/thread/thr_printf.c
===================================================================
--- trunk/lib/libthr/thread/thr_printf.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_printf.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2002 Jonathan Mini <mini at freebsd.org>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_printf.c 277317 2015-01-18 11:54:20Z kib $
  */
 
 #include <stdarg.h>
@@ -31,6 +32,7 @@
 #include <unistd.h>
 #include <pthread.h>
 
+#include "libc_private.h"
 #include "thr_private.h"
 
 static void	pchar(int fd, char c);

Modified: trunk/lib/libthr/thread/thr_private.h
===================================================================
--- trunk/lib/libthr/thread/thr_private.h	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_private.h	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (C) 2005 Daniel M. Eischen <deischen at freebsd.org>
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
@@ -26,7 +27,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: stable/9/lib/libthr/thread/thr_private.h 258767 2013-11-30 14:39:56Z kib $
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_private.h 303709 2016-08-03 10:23:42Z kib $
  */
 
 #ifndef _THR_PRIVATE_H
@@ -182,9 +183,11 @@
 struct pthread_barrier {
 	struct umutex		b_lock;
 	struct ucond		b_cv;
-	volatile int64_t	b_cycle;
-	volatile int		b_count;
-	volatile int		b_waiters;
+	int64_t			b_cycle;
+	int			b_count;
+	int			b_waiters;
+	int			b_refcount;
+	int			b_destroying;
 };
 
 struct pthread_barrierattr {
@@ -702,7 +705,6 @@
 
 extern struct pthread_prio _thr_priorities[] __hidden;
 
-extern pid_t	_thr_pid __hidden;
 extern int	_thr_is_smp __hidden;
 
 extern size_t	_thr_guard_default __hidden;
@@ -711,6 +713,7 @@
 extern int	_thr_page_size __hidden;
 extern int	_thr_spinloops __hidden;
 extern int	_thr_yieldloops __hidden;
+extern int	_thr_queuefifo __hidden;
 
 /* Garbage thread count. */
 extern int	_gc_count __hidden;
@@ -721,6 +724,10 @@
 extern struct umutex	_keytable_lock __hidden;
 extern struct urwlock	_thr_list_lock __hidden;
 extern struct umutex	_thr_event_lock __hidden;
+extern struct umutex	_suspend_all_lock __hidden;
+extern int		_suspend_all_waiters __hidden;
+extern int		_suspend_all_cycle __hidden;
+extern struct pthread	*_single_thread __hidden;
 
 /*
  * Function prototype definitions.
@@ -727,10 +734,10 @@
  */
 __BEGIN_DECLS
 int	_thr_setthreaded(int) __hidden;
-int	_mutex_cv_lock(struct pthread_mutex *, int count) __hidden;
-int	_mutex_cv_unlock(struct pthread_mutex *, int *count) __hidden;
-int     _mutex_cv_attach(struct pthread_mutex *, int count) __hidden;
-int     _mutex_cv_detach(struct pthread_mutex *, int *count) __hidden;
+int	_mutex_cv_lock(struct pthread_mutex *, int) __hidden;
+int	_mutex_cv_unlock(struct pthread_mutex *, int *, int *) __hidden;
+int     _mutex_cv_attach(struct pthread_mutex *, int) __hidden;
+int     _mutex_cv_detach(struct pthread_mutex *, int *) __hidden;
 int     _mutex_owned(struct pthread *, const struct pthread_mutex *) __hidden;
 int	_mutex_reinit(pthread_mutex_t *) __hidden;
 void	_mutex_fork(struct pthread *curthread) __hidden;
@@ -742,7 +749,6 @@
 void	_thr_ref_delete_unlocked(struct pthread *, struct pthread *) __hidden;
 int	_thr_find_thread(struct pthread *, struct pthread *, int) __hidden;
 void	_thr_rtld_init(void) __hidden;
-void	_thr_rtld_fini(void) __hidden;
 void	_thr_rtld_postfork_child(void) __hidden;
 int	_thr_stack_alloc(struct pthread_attr *) __hidden;
 void	_thr_stack_free(struct pthread_attr *) __hidden;
@@ -757,7 +763,7 @@
 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;
+void	_thr_signal_init(int) __hidden;
 void	_thr_signal_deinit(void) __hidden;
 int	_thr_send_sig(struct pthread *, int sig) __hidden;
 void	_thr_list_init(void) __hidden;
@@ -768,7 +774,6 @@
 void	_thr_unlink(struct pthread *, struct pthread *) __hidden;
 void	_thr_assert_lock_level(void) __hidden __dead2;
 void	_thr_ast(struct pthread *) __hidden;
-void	_thr_once_init(void) __hidden;
 void	_thr_report_creation(struct pthread *curthread,
 	    struct pthread *newthread) __hidden;
 void	_thr_report_death(struct pthread *curthread) __hidden;
@@ -777,6 +782,8 @@
 void	_thr_signal_prefork(void) __hidden;
 void	_thr_signal_postfork(void) __hidden;
 void	_thr_signal_postfork_child(void) __hidden;
+void	_thr_suspend_all_lock(struct pthread *) __hidden;
+void	_thr_suspend_all_unlock(struct pthread *) __hidden;
 void	_thr_try_gc(struct pthread *, struct pthread *) __hidden;
 int	_rtp_to_schedparam(const struct rtprio *rtp, int *policy,
 		struct sched_param *param) __hidden;
@@ -831,7 +838,6 @@
 int	__sys_fork(void);
 pid_t	__sys_getpid(void);
 ssize_t __sys_read(int, void *, size_t);
-ssize_t __sys_write(int, const void *, size_t);
 void	__sys_exit(int);
 #endif
 
@@ -898,6 +904,9 @@
 void	_sleepq_drop(struct sleepqueue *,
 		void (*cb)(struct pthread *, void *arg), void *) __hidden;
 
+int	_pthread_mutex_init_calloc_cb(pthread_mutex_t *mutex,
+	    void *(calloc_cb)(size_t, size_t));
+
 struct dl_phdr_info;
 void __pthread_cxa_finalize(struct dl_phdr_info *phdr_info);
 void _thr_tsd_unload(struct dl_phdr_info *phdr_info) __hidden;
@@ -904,6 +913,26 @@
 void _thr_sigact_unload(struct dl_phdr_info *phdr_info) __hidden;
 void _thr_stack_fix_protection(struct pthread *thrd);
 
+int *__error_threaded(void) __hidden;
+void __thr_interpose_libc(void) __hidden;
+pid_t __thr_fork(void);
+int __thr_setcontext(const ucontext_t *ucp);
+int __thr_sigaction(int sig, const struct sigaction *act,
+    struct sigaction *oact) __hidden;
+int __thr_sigprocmask(int how, const sigset_t *set, sigset_t *oset);
+int __thr_sigsuspend(const sigset_t * set);
+int __thr_sigtimedwait(const sigset_t *set, siginfo_t *info,
+    const struct timespec * timeout);
+int __thr_sigwait(const sigset_t *set, int *sig);
+int __thr_sigwaitinfo(const sigset_t *set, siginfo_t *info);
+int __thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp);
+
+void __thr_map_stacks_exec(void);
+
+struct _spinlock;
+void __thr_spinunlock(struct _spinlock *lck);
+void __thr_spinlock(struct _spinlock *lck);
+
 __END_DECLS
 
 #endif  /* !_THR_PRIVATE_H */

Modified: trunk/lib/libthr/thread/thr_pspinlock.c
===================================================================
--- trunk/lib/libthr/thread/thr_pspinlock.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_pspinlock.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2003 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_pspinlock.c 172694 2007-10-16 07:36:02Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_resume_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_resume_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_resume_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_resume_np.c 299521 2016-05-12 06:53:22Z kib $
  */
 
 #include "namespace.h"
@@ -63,7 +64,11 @@
 {
 	struct pthread *curthread = _get_curthread();
 	struct pthread *thread;
+	int old_nocancel;
 
+	old_nocancel = curthread->no_cancel;
+	curthread->no_cancel = 1;
+	_thr_suspend_all_lock(curthread);
 	/* Take the thread list lock: */
 	THREAD_LIST_RDLOCK(curthread);
 
@@ -77,6 +82,9 @@
 
 	/* Release the thread list lock: */
 	THREAD_LIST_UNLOCK(curthread);
+	_thr_suspend_all_unlock(curthread);
+	curthread->no_cancel = old_nocancel;
+	_thr_testcancel(curthread);
 }
 
 static void
@@ -83,7 +91,7 @@
 resume_common(struct pthread *thread)
 {
 	/* Clear the suspend flag: */
-	thread->flags &= ~THR_FLAGS_NEED_SUSPEND;
+	thread->flags &= ~(THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED);
 	thread->cycle++;
 	_thr_umtx_wake(&thread->cycle, 1, 0);
 }

Modified: trunk/lib/libthr/thread/thr_rtld.c
===================================================================
--- trunk/lib/libthr/thread/thr_rtld.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_rtld.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2006, David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_rtld.c 297533 2016-04-04 06:49:20Z kib $
  *
  */
 
@@ -32,10 +33,12 @@
   */
 #include <sys/cdefs.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include <link.h>
 #include <stdlib.h>
 #include <string.h>
 
+#include "libc_private.h"
 #include "rtld_lock.h"
 #include "thr_private.h"
 
@@ -183,7 +186,9 @@
 {
 	struct RtldLockInfo	li;
 	struct pthread		*curthread;
+	ucontext_t *uc;
 	long dummy = -1;
+	int uc_len;
 
 	curthread = _get_curthread();
 
@@ -207,20 +212,32 @@
 	li.thread_set_flag = _thr_rtld_set_flag;
 	li.thread_clr_flag = _thr_rtld_clr_flag;
 	li.at_fork = NULL;
-	
+
+	/*
+	 * Preresolve the symbols needed for the fork interposer.  We
+	 * call _rtld_atfork_pre() and _rtld_atfork_post() with NULL
+	 * argument to indicate that no actual locking inside the
+	 * functions should happen.  Neither rtld compat locks nor
+	 * libthr rtld locks cannot work there:
+	 * - compat locks do not handle the case of two locks taken
+	 *   in write mode (the signal mask for the thread is corrupted);
+	 * - libthr locks would work, but locked rtld_bind_lock prevents
+	 *   symbol resolution for _rtld_atfork_post.
+	 */
+	_rtld_atfork_pre(NULL);
+	_rtld_atfork_post(NULL);
+	_malloc_prefork();
+	_malloc_postfork();
+	getpid();
+	syscall(SYS_getpid);
+
 	/* mask signals, also force to resolve __sys_sigprocmask PLT */
 	_thr_signal_block(curthread);
 	_rtld_thread_init(&li);
 	_thr_signal_unblock(curthread);
-}
 
-void
-_thr_rtld_fini(void)
-{
-	struct pthread	*curthread;
-
-	curthread = _get_curthread();
-	_thr_signal_block(curthread);
-	_rtld_thread_init(NULL);
-	_thr_signal_unblock(curthread);
+	uc_len = __getcontextx_size();
+	uc = alloca(uc_len);
+	getcontext(uc);
+	__fillcontextx2((char *)uc);
 }

Modified: trunk/lib/libthr/thread/thr_rwlock.c
===================================================================
--- trunk/lib/libthr/thread/thr_rwlock.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_rwlock.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998 Alex Nash
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_rwlock.c 232209 2012-02-27 13:38:52Z davidxu $
  */
 
 #include <errno.h>
@@ -123,7 +124,6 @@
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_rwlock_t prwlock;
-	struct timespec ts, ts2, *tsp;
 	int flags;
 	int ret;
 
@@ -162,18 +162,8 @@
 		return (EINVAL);
 
 	for (;;) {
-		if (abstime) {
-			clock_gettime(CLOCK_REALTIME, &ts);
-			TIMESPEC_SUB(&ts2, abstime, &ts);
-			if (ts2.tv_sec < 0 || 
-			    (ts2.tv_sec == 0 && ts2.tv_nsec <= 0))
-				return (ETIMEDOUT);
-			tsp = &ts2;
-		} else
-			tsp = NULL;
-
 		/* goto kernel and lock it */
-		ret = __thr_rwlock_rdlock(&prwlock->lock, flags, tsp);
+		ret = __thr_rwlock_rdlock(&prwlock->lock, flags, abstime);
 		if (ret != EINTR)
 			break;
 
@@ -255,7 +245,6 @@
 {
 	struct pthread *curthread = _get_curthread();
 	pthread_rwlock_t prwlock;
-	struct timespec ts, ts2, *tsp;
 	int ret;
 
 	CHECK_AND_INIT_RWLOCK
@@ -275,18 +264,8 @@
 		return (EINVAL);
 
 	for (;;) {
-		if (abstime != NULL) {
-			clock_gettime(CLOCK_REALTIME, &ts);
-			TIMESPEC_SUB(&ts2, abstime, &ts);
-			if (ts2.tv_sec < 0 || 
-			    (ts2.tv_sec == 0 && ts2.tv_nsec <= 0))
-				return (ETIMEDOUT);
-			tsp = &ts2;
-		} else
-			tsp = NULL;
-
 		/* goto kernel and lock it */
-		ret = __thr_rwlock_wrlock(&prwlock->lock, tsp);
+		ret = __thr_rwlock_wrlock(&prwlock->lock, abstime);
 		if (ret == 0) {
 			prwlock->owner = curthread;
 			break;

Modified: trunk/lib/libthr/thread/thr_rwlockattr.c
===================================================================
--- trunk/lib/libthr/thread/thr_rwlockattr.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_rwlockattr.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 1998 Alex Nash
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_rwlockattr.c 214093 2010-10-20 02:34:02Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_self.c
===================================================================
--- trunk/lib/libthr/thread/thr_self.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_self.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_self.c 165967 2007-01-12 07:26:21Z imp $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_sem.c
===================================================================
--- trunk/lib/libthr/thread/thr_sem.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_sem.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (C) 2005 David Xu <davidxu at freebsd.org>.
  * Copyright (C) 2000 Jason Evans <jasone at freebsd.org>.
@@ -27,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_sem.c 201546 2010-01-05 02:37:59Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_setprio.c
===================================================================
--- trunk/lib/libthr/thread/thr_setprio.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_setprio.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_setprio.c 238642 2012-07-20 03:22:17Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_setschedparam.c
===================================================================
--- trunk/lib/libthr/thread/thr_setschedparam.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_setschedparam.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1998 Daniel Eischen <eischen at vigrid.com>.
  * All rights reserved.
@@ -29,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_setschedparam.c 238642 2012-07-20 03:22:17Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_sig.c
===================================================================
--- trunk/lib/libthr/thread/thr_sig.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_sig.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005, David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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: stable/9/lib/libthr/thread/thr_sig.c 258767 2013-11-30 14:39:56Z kib $
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_sig.c 299521 2016-05-12 06:53:22Z kib $
  */
 
 #include "namespace.h"
@@ -30,7 +31,7 @@
 #include <sys/param.h>
 #include <sys/types.h>
 #include <sys/signalvar.h>
-#include <sys/ucontext.h>
+#include <sys/syscall.h>
 #include <signal.h>
 #include <errno.h>
 #include <stdlib.h>
@@ -39,6 +40,7 @@
 #include "un-namespace.h"
 #include "libc_private.h"
 
+#include "libc_private.h"
 #include "thr_private.h"
 
 /* #define DEBUG_SIGNAL */
@@ -55,6 +57,13 @@
 
 static struct usigaction _thr_sigact[_SIG_MAXSIG];
 
+static inline struct usigaction *
+__libc_sigaction_slot(int signo)
+{
+
+	return (&_thr_sigact[signo - 1]);
+}
+
 static void thr_sighandler(int, siginfo_t *, void *);
 static void handle_signal(struct sigaction *, int, siginfo_t *, ucontext_t *);
 static void check_deferred_signal(struct pthread *);
@@ -61,18 +70,10 @@
 static void check_suspend(struct pthread *);
 static void check_cancel(struct pthread *curthread, ucontext_t *ucp);
 
-int	___pause(void);
-int	_raise(int);
-int	__sigtimedwait(const sigset_t *set, siginfo_t *info,
-	const struct timespec * timeout);
 int	_sigtimedwait(const sigset_t *set, siginfo_t *info,
 	const struct timespec * timeout);
-int	__sigwaitinfo(const sigset_t *set, siginfo_t *info);
 int	_sigwaitinfo(const sigset_t *set, siginfo_t *info);
-int	___sigwait(const sigset_t *set, int *sig);
 int	_sigwait(const sigset_t *set, int *sig);
-int	__sigsuspend(const sigset_t *sigmask);
-int	_sigaction(int, const struct sigaction *, struct sigaction *);
 int	_setcontext(const ucontext_t *);
 int	_swapcontext(ucontext_t *, const ucontext_t *);
 
@@ -144,8 +145,8 @@
 	errno = err;
 }
 
-typedef void (*ohandler)(int sig, int code,
-	struct sigcontext *scp, char *addr, __sighandler_t *catcher);
+typedef void (*ohandler)(int sig, int code, struct sigcontext *scp,
+    char *addr, __sighandler_t *catcher);
 
 /*
  * The signal handler wrapper is entered with all signal masked.
@@ -153,15 +154,19 @@
 static void
 thr_sighandler(int sig, siginfo_t *info, void *_ucp)
 {
-	struct pthread *curthread = _get_curthread();
-	ucontext_t *ucp = _ucp;
+	struct pthread *curthread;
+	ucontext_t *ucp;
 	struct sigaction act;
+	struct usigaction *usa;
 	int err;
 
 	err = errno;
-	_thr_rwl_rdlock(&_thr_sigact[sig-1].lock);
-	act = _thr_sigact[sig-1].sigact;
-	_thr_rwl_unlock(&_thr_sigact[sig-1].lock);
+	curthread = _get_curthread();
+	ucp = _ucp;
+	usa = __libc_sigaction_slot(sig);
+	_thr_rwl_rdlock(&usa->lock);
+	act = usa->sigact;
+	_thr_rwl_unlock(&usa->lock);
 	errno = err;
 	curthread->deferred_run = 0;
 
@@ -235,12 +240,12 @@
 	 * so after setjmps() returns once more, the user code may need to
 	 * re-set cancel_enable flag by calling pthread_setcancelstate().
 	 */
-	if ((actp->sa_flags & SA_SIGINFO) != 0)
-		(*(sigfunc))(sig, info, ucp);
-	else {
-		((ohandler)(*sigfunc))(
-			sig, info->si_code, (struct sigcontext *)ucp,
-			info->si_addr, (__sighandler_t *)sigfunc);
+	if ((actp->sa_flags & SA_SIGINFO) != 0) {
+		sigfunc(sig, info, ucp);
+	} else {
+		((ohandler)sigfunc)(sig, info->si_code,
+		    (struct sigcontext *)ucp, info->si_addr,
+		    (__sighandler_t *)sigfunc);
 	}
 	err = errno;
 
@@ -254,7 +259,7 @@
 	/* reschedule cancellation */
 	check_cancel(curthread, &uc2);
 	errno = err;
-	__sys_sigreturn(&uc2);
+	syscall(SYS_sigreturn, &uc2);
 }
 
 void
@@ -290,8 +295,8 @@
 	 * 2) because _thr_ast() may be called by
 	 *    THR_CRITICAL_LEAVE() which is used by rtld rwlock
 	 *    and any libthr internal locks, when rtld rwlock
-	 *    is used, it is mostly caused my an unresolved PLT.
-	 *    those routines may clear the TDP_WAKEUP flag by
+	 *    is used, it is mostly caused by an unresolved PLT.
+	 *    Those routines may clear the TDP_WAKEUP flag by
 	 *    invoking some system calls, in those cases, we
 	 *    also should reenable the flag.
 	 * 3) thread is in sigsuspend(), and the syscall insists
@@ -352,7 +357,8 @@
 		(THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED))
 		!= THR_FLAGS_NEED_SUSPEND))
 		return;
-
+	if (curthread == _single_thread)
+		return;
 	if (curthread->force_exit)
 		return;
 
@@ -368,8 +374,7 @@
 	 */
 	curthread->critical_count++;
 	THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
-	while ((curthread->flags & (THR_FLAGS_NEED_SUSPEND |
-		THR_FLAGS_SUSPENDED)) == THR_FLAGS_NEED_SUSPEND) {
+	while ((curthread->flags & THR_FLAGS_NEED_SUSPEND) != 0) {
 		curthread->cycle++;
 		cycle = curthread->cycle;
 
@@ -386,7 +391,6 @@
 		THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
 		_thr_umtx_wait_uint(&curthread->cycle, cycle, NULL, 0);
 		THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
-		curthread->flags &= ~THR_FLAGS_SUSPENDED;
 	}
 	THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
 	curthread->critical_count--;
@@ -395,10 +399,35 @@
 }
 
 void
-_thr_signal_init(void)
+_thr_signal_init(int dlopened)
 {
-	struct sigaction act;
+	struct sigaction act, nact, oact;
+	struct usigaction *usa;
+	sigset_t oldset;
+	int sig, error;
 
+	if (dlopened) {
+		__sys_sigprocmask(SIG_SETMASK, &_thr_maskset, &oldset);
+		for (sig = 1; sig <= _SIG_MAXSIG; sig++) {
+			if (sig == SIGCANCEL)
+				continue;
+			error = __sys_sigaction(sig, NULL, &oact);
+			if (error == -1 || oact.sa_handler == SIG_DFL ||
+			    oact.sa_handler == SIG_IGN)
+				continue;
+			usa = __libc_sigaction_slot(sig);
+			usa->sigact = oact;
+			nact = oact;
+			remove_thr_signals(&usa->sigact.sa_mask);
+			nact.sa_flags &= ~SA_NODEFER;
+			nact.sa_flags |= SA_SIGINFO;
+			nact.sa_sigaction = thr_sighandler;
+			nact.sa_mask = _thr_maskset;
+			(void)__sys_sigaction(sig, &nact, NULL);
+		}
+		__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
+	}
+
 	/* Install SIGCANCEL handler. */
 	SIGFILLSET(act.sa_mask);
 	act.sa_flags = SA_SIGINFO;
@@ -418,6 +447,7 @@
 	struct pthread *curthread = _get_curthread();
 	struct urwlock *rwlp;
 	struct sigaction *actp;
+	struct usigaction *usa;
 	struct sigaction kact;
 	void (*handler)(int);
 	int sig;
@@ -424,12 +454,13 @@
  
 	_thr_signal_block(curthread);
 	for (sig = 1; sig <= _SIG_MAXSIG; sig++) {
-		actp = &_thr_sigact[sig-1].sigact;
+		usa = __libc_sigaction_slot(sig);
+		actp = &usa->sigact;
 retry:
 		handler = actp->sa_handler;
 		if (handler != SIG_DFL && handler != SIG_IGN &&
 		    __elf_phdr_match_addr(phdr_info, handler)) {
-			rwlp = &_thr_sigact[sig-1].lock;
+			rwlp = &usa->lock;
 			_thr_rwl_wrlock(rwlp);
 			if (handler != actp->sa_handler) {
 				_thr_rwl_unlock(rwlp);
@@ -455,7 +486,7 @@
 	int i;
 
 	for (i = 1; i <= _SIG_MAXSIG; ++i)
-		_thr_rwl_rdlock(&_thr_sigact[i-1].lock);
+		_thr_rwl_rdlock(&__libc_sigaction_slot(i)->lock);
 }
 
 void
@@ -464,7 +495,7 @@
 	int i;
 
 	for (i = 1; i <= _SIG_MAXSIG; ++i)
-		_thr_rwl_unlock(&_thr_sigact[i-1].lock);
+		_thr_rwl_unlock(&__libc_sigaction_slot(i)->lock);
 }
 
 void
@@ -472,8 +503,10 @@
 {
 	int i;
 
-	for (i = 1; i <= _SIG_MAXSIG; ++i)
-		bzero(&_thr_sigact[i-1].lock, sizeof(struct urwlock));
+	for (i = 1; i <= _SIG_MAXSIG; ++i) {
+		bzero(&__libc_sigaction_slot(i) -> lock,
+		    sizeof(struct urwlock));
+	}
 }
 
 void
@@ -481,34 +514,13 @@
 {
 }
 
-__weak_reference(___pause, pause);
-
 int
-___pause(void)
+__thr_sigaction(int sig, const struct sigaction *act, struct sigaction *oact)
 {
-	sigset_t oset;
-
-	if (_sigprocmask(SIG_BLOCK, NULL, &oset) == -1)
-		return (-1);
-	return (__sigsuspend(&oset));
-}
-
-__weak_reference(_raise, raise);
-
-int
-_raise(int sig)
-{
-	return _thr_send_sig(_get_curthread(), sig);
-}
-
-__weak_reference(_sigaction, sigaction);
-
-int
-_sigaction(int sig, const struct sigaction * act, struct sigaction * oact)
-{
 	struct sigaction newact, oldact, oldact2;
 	sigset_t oldset;
-	int ret = 0, err = 0;
+	struct usigaction *usa;
+	int ret, err;
 
 	if (!_SIG_VALID(sig) || sig == SIGCANCEL) {
 		errno = EINVAL;
@@ -515,18 +527,20 @@
 		return (-1);
 	}
 
-	if (act)
-		newact = *act;
+	ret = 0;
+	err = 0;
+	usa = __libc_sigaction_slot(sig);
 
 	__sys_sigprocmask(SIG_SETMASK, &_thr_maskset, &oldset);
-	_thr_rwl_wrlock(&_thr_sigact[sig-1].lock);
+	_thr_rwl_wrlock(&usa->lock);
  
 	if (act != NULL) {
-		oldact2 = _thr_sigact[sig-1].sigact;
+		oldact2 = usa->sigact;
+		newact = *act;
 
  		/*
 		 * if a new sig handler is SIG_DFL or SIG_IGN,
-		 * don't remove old handler from _thr_sigact[],
+		 * don't remove old handler from __libc_sigact[],
 		 * so deferred signals still can use the handlers,
 		 * multiple threads invoking sigaction itself is
 		 * a race condition, so it is not a problem.
@@ -533,17 +547,17 @@
 		 */
 		if (newact.sa_handler != SIG_DFL &&
 		    newact.sa_handler != SIG_IGN) {
-			_thr_sigact[sig-1].sigact = newact;
-			remove_thr_signals(
-				&_thr_sigact[sig-1].sigact.sa_mask);
+			usa->sigact = newact;
+			remove_thr_signals(&usa->sigact.sa_mask);
 			newact.sa_flags &= ~SA_NODEFER;
 			newact.sa_flags |= SA_SIGINFO;
 			newact.sa_sigaction = thr_sighandler;
 			newact.sa_mask = _thr_maskset; /* mask all signals */
 		}
-		if ((ret = __sys_sigaction(sig, &newact, &oldact))) {
+		ret = __sys_sigaction(sig, &newact, &oldact);
+		if (ret == -1) {
 			err = errno;
-			_thr_sigact[sig-1].sigact = oldact2;
+			usa->sigact = oldact2;
 		}
 	} else if (oact != NULL) {
 		ret = __sys_sigaction(sig, NULL, &oldact);
@@ -550,15 +564,14 @@
 		err = errno;
 	}
 
-	if (oldact.sa_handler != SIG_DFL &&
-	    oldact.sa_handler != SIG_IGN) {
+	if (oldact.sa_handler != SIG_DFL && oldact.sa_handler != SIG_IGN) {
 		if (act != NULL)
 			oldact = oldact2;
 		else if (oact != NULL)
-			oldact = _thr_sigact[sig-1].sigact;
+			oldact = usa->sigact;
 	}
 
-	_thr_rwl_unlock(&_thr_sigact[sig-1].lock);
+	_thr_rwl_unlock(&usa->lock);
 	__sys_sigprocmask(SIG_SETMASK, &oldset, NULL);
 
 	if (ret == 0) {
@@ -570,10 +583,8 @@
 	return (ret);
 }
 
-__weak_reference(_sigprocmask, sigprocmask);
-
 int
-_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
+__thr_sigprocmask(int how, const sigset_t *set, sigset_t *oset)
 {
 	const sigset_t *p = set;
 	sigset_t newset;
@@ -593,13 +604,12 @@
 int
 _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
 {
-	if (_sigprocmask(how, set, oset))
+
+	if (__thr_sigprocmask(how, set, oset))
 		return (errno);
 	return (0);
 }
 
-__weak_reference(__sigsuspend, sigsuspend);
-
 int
 _sigsuspend(const sigset_t * set)
 {
@@ -609,7 +619,7 @@
 }
 
 int
-__sigsuspend(const sigset_t * set)
+__thr_sigsuspend(const sigset_t * set)
 {
 	struct pthread *curthread;
 	sigset_t newset;
@@ -633,10 +643,6 @@
 	return (ret);
 }
 
-__weak_reference(___sigwait, sigwait);
-__weak_reference(__sigtimedwait, sigtimedwait);
-__weak_reference(__sigwaitinfo, sigwaitinfo);
-
 int
 _sigtimedwait(const sigset_t *set, siginfo_t *info,
 	const struct timespec * timeout)
@@ -653,8 +659,8 @@
  *   it is not canceled.
  */
 int
-__sigtimedwait(const sigset_t *set, siginfo_t *info,
-	const struct timespec * timeout)
+__thr_sigtimedwait(const sigset_t *set, siginfo_t *info,
+    const struct timespec * timeout)
 {
 	struct pthread	*curthread = _get_curthread();
 	sigset_t newset;
@@ -681,7 +687,7 @@
  *   it is not canceled.
  */ 
 int
-__sigwaitinfo(const sigset_t *set, siginfo_t *info)
+__thr_sigwaitinfo(const sigset_t *set, siginfo_t *info)
 {
 	struct pthread	*curthread = _get_curthread();
 	sigset_t newset;
@@ -707,7 +713,7 @@
  *   it is not canceled.
  */ 
 int
-___sigwait(const sigset_t *set, int *sig)
+__thr_sigwait(const sigset_t *set, int *sig)
 {
 	struct pthread	*curthread = _get_curthread();
 	sigset_t newset;
@@ -721,24 +727,35 @@
 	return (ret);
 }
 
-__weak_reference(_setcontext, setcontext);
 int
-_setcontext(const ucontext_t *ucp)
+__thr_setcontext(const ucontext_t *ucp)
 {
 	ucontext_t uc;
 
+	if (ucp == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+	if (!SIGISMEMBER(uc.uc_sigmask, SIGCANCEL))
+		return __sys_setcontext(ucp);
 	(void) memcpy(&uc, ucp, sizeof(uc));
-	remove_thr_signals(&uc.uc_sigmask);
-	return __sys_setcontext(&uc);
+	SIGDELSET(uc.uc_sigmask, SIGCANCEL);
+	return (__sys_setcontext(&uc));
 }
 
-__weak_reference(_swapcontext, swapcontext);
 int
-_swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
+__thr_swapcontext(ucontext_t *oucp, const ucontext_t *ucp)
 {
 	ucontext_t uc;
 
-	(void) memcpy(&uc, ucp, sizeof(uc));
-	remove_thr_signals(&uc.uc_sigmask);
-	return __sys_swapcontext(oucp, &uc);
+	if (oucp == NULL || ucp == NULL) {
+		errno = EINVAL;
+		return (-1);
+	}
+	if (SIGISMEMBER(ucp->uc_sigmask, SIGCANCEL)) {
+		(void) memcpy(&uc, ucp, sizeof(uc));
+		SIGDELSET(uc.uc_sigmask, SIGCANCEL);
+		ucp = &uc;
+	}
+	return (__sys_swapcontext(oucp, ucp));
 }

Modified: trunk/lib/libthr/thread/thr_single_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_single_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_single_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1996 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_single_np.c 165967 2007-01-12 07:26:21Z imp $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_sleepq.c
===================================================================
--- trunk/lib/libthr/thread/thr_sleepq.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_sleepq.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2010 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_sleepq.c 235218 2012-05-10 09:30:37Z davidxu $
  */
 
 #include <stdlib.h>
@@ -39,6 +40,7 @@
 
 struct sleepqueue_chain {
 	struct umutex		sc_lock;
+	int			sc_enqcnt;
 	LIST_HEAD(, sleepqueue) sc_queues;
 	int			sc_type;
 };
@@ -93,13 +95,11 @@
 	THR_LOCK_RELEASE(curthread, &sc->sc_lock);
 }
 
-struct sleepqueue *
-_sleepq_lookup(void *wchan)
+static inline struct sleepqueue *
+lookup(struct sleepqueue_chain *sc, void *wchan)
 {
-	struct sleepqueue_chain *sc;
 	struct sleepqueue *sq;
 
-	sc = SC_LOOKUP(wchan);
 	LIST_FOREACH(sq, &sc->sc_queues, sq_hash)
 		if (sq->sq_wchan == wchan)
 			return (sq);
@@ -106,6 +106,12 @@
 	return (NULL);
 }
 
+struct sleepqueue *
+_sleepq_lookup(void *wchan)
+{
+	return (lookup(SC_LOOKUP(wchan), wchan));
+}
+
 void
 _sleepq_add(void *wchan, struct pthread *td)
 {
@@ -112,11 +118,11 @@
 	struct sleepqueue_chain *sc;
 	struct sleepqueue *sq;
 
-	sq = _sleepq_lookup(wchan);
+	sc = SC_LOOKUP(wchan);
+	sq = lookup(sc, wchan);
 	if (sq != NULL) {
 		SLIST_INSERT_HEAD(&sq->sq_freeq, td->sleepqueue, sq_flink);
 	} else {
-		sc = SC_LOOKUP(wchan);
 		sq = td->sleepqueue;
 		LIST_INSERT_HEAD(&sc->sc_queues, sq, sq_hash);
 		sq->sq_wchan = wchan;
@@ -124,7 +130,10 @@
 	}
 	td->sleepqueue = NULL;
 	td->wchan = wchan;
-	TAILQ_INSERT_TAIL(&sq->sq_blocked, td, wle);
+	if (((++sc->sc_enqcnt << _thr_queuefifo) & 0xff) != 0)
+		TAILQ_INSERT_HEAD(&sq->sq_blocked, td, wle);
+	else
+		TAILQ_INSERT_TAIL(&sq->sq_blocked, td, wle);
 }
 
 int

Modified: trunk/lib/libthr/thread/thr_spec.c
===================================================================
--- trunk/lib/libthr/thread/thr_spec.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_spec.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,10 +27,11 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: stable/9/lib/libthr/thread/thr_spec.c 262221 2014-02-19 15:00:55Z jhb $
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_spec.c 283690 2015-05-29 07:48:30Z kib $
  */
 
 #include "namespace.h"
+#include <sys/mman.h>
 #include <signal.h>
 #include <stdlib.h>
 #include <string.h>
@@ -40,7 +42,6 @@
 
 #include "thr_private.h"
 
-/* Static variables: */
 struct pthread_key _thread_keytable[PTHREAD_KEYS_MAX];
 
 __weak_reference(_pthread_key_create, pthread_key_create);
@@ -50,7 +51,7 @@
 
 
 int
-_pthread_key_create(pthread_key_t *key, void (*destructor) (void *))
+_pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
 {
 	struct pthread *curthread;
 	int i;
@@ -59,7 +60,6 @@
 
 	curthread = _get_curthread();
 
-	/* Lock the key table: */
 	THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
 	for (i = 0; i < PTHREAD_KEYS_MAX; i++) {
 
@@ -68,7 +68,6 @@
 			_thread_keytable[i].destructor = destructor;
 			_thread_keytable[i].seqno++;
 
-			/* Unlock the key table: */
 			THR_LOCK_RELEASE(curthread, &_keytable_lock);
 			*key = i + 1;
 			return (0);
@@ -75,7 +74,6 @@
 		}
 
 	}
-	/* Unlock the key table: */
 	THR_LOCK_RELEASE(curthread, &_keytable_lock);
 	return (EAGAIN);
 }
@@ -83,23 +81,21 @@
 int
 _pthread_key_delete(pthread_key_t userkey)
 {
-	struct pthread *curthread = _get_curthread();
-	int key = userkey - 1;
-	int ret = 0;
+	struct pthread *curthread;
+	int key, ret;
 
-	if ((unsigned int)key < PTHREAD_KEYS_MAX) {
-		/* Lock the key table: */
-		THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
-
-		if (_thread_keytable[key].allocated)
-			_thread_keytable[key].allocated = 0;
-		else
-			ret = EINVAL;
-
-		/* Unlock the key table: */
-		THR_LOCK_RELEASE(curthread, &_keytable_lock);
-	} else
+	key = userkey - 1;
+	if ((unsigned int)key >= PTHREAD_KEYS_MAX)
+		return (EINVAL);
+	curthread = _get_curthread();
+	THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
+	if (_thread_keytable[key].allocated) {
+		_thread_keytable[key].allocated = 0;
+		ret = 0;
+	} else {
 		ret = EINVAL;
+	}
+	THR_LOCK_RELEASE(curthread, &_keytable_lock);
 	return (ret);
 }
 
@@ -106,21 +102,19 @@
 void 
 _thread_cleanupspecific(void)
 {
-	struct pthread	*curthread = _get_curthread();
-	void		(*destructor)( void *);
-	const void	*data = NULL;
-	int		key;
-	int		i;
+	struct pthread *curthread;
+	void (*destructor)(void *);
+	const void *data;
+	int i, key;
 
+	curthread = _get_curthread();
 	if (curthread->specific == NULL)
 		return;
-
-	/* Lock the key table: */
 	THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
-	for (i = 0; (i < PTHREAD_DESTRUCTOR_ITERATIONS) &&
-	    (curthread->specific_data_count > 0); i++) {
-		for (key = 0; (key < PTHREAD_KEYS_MAX) &&
-		    (curthread->specific_data_count > 0); key++) {
+	for (i = 0; i < PTHREAD_DESTRUCTOR_ITERATIONS &&
+	    curthread->specific_data_count > 0; i++) {
+		for (key = 0; key < PTHREAD_KEYS_MAX &&
+		    curthread->specific_data_count > 0; key++) {
 			destructor = NULL;
 
 			if (_thread_keytable[key].allocated &&
@@ -128,17 +122,19 @@
 				if (curthread->specific[key].seqno ==
 				    _thread_keytable[key].seqno) {
 					data = curthread->specific[key].data;
-					destructor = _thread_keytable[key].destructor;
+					destructor = _thread_keytable[key].
+					    destructor;
 				}
 				curthread->specific[key].data = NULL;
 				curthread->specific_data_count--;
-			}
-			else if (curthread->specific[key].data != NULL) {
+			} else if (curthread->specific[key].data != NULL) {
 				/* 
-				 * This can happen if the key is deleted via
-				 * pthread_key_delete without first setting the value
-				 * to NULL in all threads.  POSIX says that the
-				 * destructor is not invoked in this case.
+				 * This can happen if the key is
+				 * deleted via pthread_key_delete
+				 * without first setting the value to
+				 * NULL in all threads.  POSIX says
+				 * that the destructor is not invoked
+				 * in this case.
 				 */
 				curthread->specific[key].data = NULL;
 				curthread->specific_data_count--;
@@ -145,14 +141,10 @@
 			}
 
 			/*
-			 * If there is a destructor, call it
-			 * with the key table entry unlocked:
+			 * If there is a destructor, call it with the
+			 * key table entry unlocked.
 			 */
 			if (destructor != NULL) {
-				/*
-				 * Don't hold the lock while calling the
-				 * destructor:
-				 */
 				THR_LOCK_RELEASE(curthread, &_keytable_lock);
 				destructor(__DECONST(void *, data));
 				THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
@@ -160,83 +152,72 @@
 		}
 	}
 	THR_LOCK_RELEASE(curthread, &_keytable_lock);
-	free(curthread->specific);
+	munmap(curthread->specific, PTHREAD_KEYS_MAX * sizeof(struct
+	    pthread_specific_elem));
 	curthread->specific = NULL;
-	if (curthread->specific_data_count > 0)
+	if (curthread->specific_data_count > 0) {
 		stderr_debug("Thread %p has exited with leftover "
 		    "thread-specific data after %d destructor iterations\n",
 		    curthread, PTHREAD_DESTRUCTOR_ITERATIONS);
+	}
 }
 
-static inline struct pthread_specific_elem *
-pthread_key_allocate_data(void)
-{
-	struct pthread_specific_elem *new_data;
-
-	new_data = (struct pthread_specific_elem *)
-	    calloc(1, sizeof(struct pthread_specific_elem) * PTHREAD_KEYS_MAX);
-	return (new_data);
-}
-
 int 
 _pthread_setspecific(pthread_key_t userkey, const void *value)
 {
-	struct pthread	*pthread;
-	pthread_key_t	key = userkey - 1;
-	int		ret = 0;
+	struct pthread *pthread;
+	void *tmp;
+	pthread_key_t key;
 
-	/* Point to the running thread: */
+	key = userkey - 1;
+	if ((unsigned int)key >= PTHREAD_KEYS_MAX ||
+	    !_thread_keytable[key].allocated)
+		return (EINVAL);
+
 	pthread = _get_curthread();
-
-	if ((pthread->specific) ||
-	    (pthread->specific = pthread_key_allocate_data())) {
-		if ((unsigned int)key < PTHREAD_KEYS_MAX) {
-			if (_thread_keytable[key].allocated) {
-				if (pthread->specific[key].data == NULL) {
-					if (value != NULL)
-						pthread->specific_data_count++;
-				} else if (value == NULL)
-					pthread->specific_data_count--;
-				pthread->specific[key].data = value;
-				pthread->specific[key].seqno =
-				    _thread_keytable[key].seqno;
-				ret = 0;
-			} else
-				ret = EINVAL;
-		} else
-			ret = EINVAL;
-	} else
-		ret = ENOMEM;
-	return (ret);
+	if (pthread->specific == NULL) {
+		tmp = mmap(NULL, PTHREAD_KEYS_MAX *
+		    sizeof(struct pthread_specific_elem),
+		    PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+		if (tmp == MAP_FAILED)
+			return (ENOMEM);
+		pthread->specific = tmp;
+	}
+	if (pthread->specific[key].data == NULL) {
+		if (value != NULL)
+			pthread->specific_data_count++;
+	} else if (value == NULL)
+		pthread->specific_data_count--;
+	pthread->specific[key].data = value;
+	pthread->specific[key].seqno = _thread_keytable[key].seqno;
+	return (0);
 }
 
 void *
 _pthread_getspecific(pthread_key_t userkey)
 {
-	struct pthread	*pthread;
-	pthread_key_t	key = userkey - 1;
-	const void	*data;
+	struct pthread *pthread;
+	const void *data;
+	pthread_key_t key;
 
-	/* Point to the running thread: */
+	/* Check if there is specific data. */
+	key = userkey - 1;
+	if ((unsigned int)key >= PTHREAD_KEYS_MAX)
+		return (NULL);
+
 	pthread = _get_curthread();
-
-	/* Check if there is specific data: */
-	if (pthread->specific != NULL && (unsigned int)key < PTHREAD_KEYS_MAX) {
-		/* Check if this key has been used before: */
-		if (_thread_keytable[key].allocated &&
-		    (pthread->specific[key].seqno == _thread_keytable[key].seqno)) {
-			/* Return the value: */
-			data = pthread->specific[key].data;
-		} else {
-			/*
-			 * This key has not been used before, so return NULL
-			 * instead: 
-			 */
-			data = NULL;
-		}
-	} else
-		/* No specific data has been created, so just return NULL: */
+	/* Check if this key has been used before. */
+	if (_thread_keytable[key].allocated && pthread->specific != NULL &&
+	    pthread->specific[key].seqno == _thread_keytable[key].seqno) {
+		/* Return the value: */
+		data = pthread->specific[key].data;
+	} else {
+		/*
+		 * This key has not been used before, so return NULL
+		 * instead.
+		 */
 		data = NULL;
+	}
 	return (__DECONST(void *, data));
 }
 
@@ -243,19 +224,20 @@
 void
 _thr_tsd_unload(struct dl_phdr_info *phdr_info)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	void (*destructor)(void *);
 	int key;
 
+	curthread = _get_curthread();
 	THR_LOCK_ACQUIRE(curthread, &_keytable_lock);
 	for (key = 0; key < PTHREAD_KEYS_MAX; key++) {
-		if (_thread_keytable[key].allocated) {
-			destructor = _thread_keytable[key].destructor;
-			if (destructor != NULL) {
-				if (__elf_phdr_match_addr(phdr_info, destructor))
-					_thread_keytable[key].destructor = NULL;
-			}
-		}
+		if (!_thread_keytable[key].allocated)
+			continue;
+		destructor = _thread_keytable[key].destructor;
+		if (destructor == NULL)
+			continue;
+		if (__elf_phdr_match_addr(phdr_info, destructor))
+			_thread_keytable[key].destructor = NULL;
 	}
 	THR_LOCK_RELEASE(curthread, &_keytable_lock);
 }

Modified: trunk/lib/libthr/thread/thr_spinlock.c
===================================================================
--- trunk/lib/libthr/thread/thr_spinlock.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_spinlock.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1997 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_spinlock.c 278875 2015-02-17 01:03:06Z kib $
  *
  */
 
@@ -61,7 +62,7 @@
  */
 
 void
-_spinunlock(spinlock_t *lck)
+__thr_spinunlock(spinlock_t *lck)
 {
 	struct spinlock_extra	*_extra;
 
@@ -70,7 +71,7 @@
 }
 
 void
-_spinlock(spinlock_t *lck)
+__thr_spinlock(spinlock_t *lck)
 {
 	struct spinlock_extra *_extra;
 
@@ -84,12 +85,6 @@
 	THR_UMUTEX_LOCK(_get_curthread(), &_extra->lock);
 }
 
-void
-_spinlock_debug(spinlock_t *lck, char *fname __unused, int lineno __unused)
-{
-	_spinlock(lck);
-}
-
 static void
 init_spinlock(spinlock_t *lck)
 {

Modified: trunk/lib/libthr/thread/thr_stack.c
===================================================================
--- trunk/lib/libthr/thread/thr_stack.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_stack.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2001 Daniel Eischen <deischen at freebsd.org>
  * Copyright (c) 2000-2001 Jason Evans <jasone at freebsd.org>
@@ -24,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_stack.c 296732 2016-03-12 17:33:40Z kib $
  */
 
 #include <sys/types.h>
@@ -161,9 +162,8 @@
 	    rlim.rlim_cur, _rtld_get_stack_prot());
 }
 
-void __pthread_map_stacks_exec(void);
 void
-__pthread_map_stacks_exec(void)
+__thr_map_stacks_exec(void)
 {
 	struct pthread *curthread, *thrd;
 	struct stack *st;
@@ -246,7 +246,10 @@
 		THREAD_LIST_UNLOCK(curthread);
 	}
 	else {
-		/* Allocate a stack from usrstack. */
+		/*
+		 * Allocate a stack from or below usrstack, depending
+		 * on the LIBPTHREAD_BIGSTACK_MAIN env variable.
+		 */
 		if (last_stack == NULL)
 			last_stack = _usrstack - _thr_stack_initial -
 			    _thr_guard_default;
@@ -268,7 +271,7 @@
 
 		/* Map the stack and guard page together, and split guard
 		   page from allocated space: */
-		if ((stackaddr = mmap(stackaddr, stacksize+guardsize,
+		if ((stackaddr = mmap(stackaddr, stacksize + guardsize,
 		     _rtld_get_stack_prot(), MAP_STACK,
 		     -1, 0)) != MAP_FAILED &&
 		    (guardsize == 0 ||

Modified: trunk/lib/libthr/thread/thr_suspend_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_suspend_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_suspend_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995-1998 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_suspend_np.c 239718 2012-08-27 03:09:39Z davidxu $
  */
 
 #include "namespace.h"
@@ -70,14 +71,48 @@
 }
 
 void
+_thr_suspend_all_lock(struct pthread *curthread)
+{
+	int old;
+
+	THR_LOCK_ACQUIRE(curthread, &_suspend_all_lock);
+	while (_single_thread != NULL) {
+		old = _suspend_all_cycle;
+		_suspend_all_waiters++;
+		THR_LOCK_RELEASE(curthread, &_suspend_all_lock);
+		_thr_umtx_wait_uint(&_suspend_all_cycle, old, NULL, 0);
+		THR_LOCK_ACQUIRE(curthread, &_suspend_all_lock);
+		_suspend_all_waiters--;
+	}
+	_single_thread = curthread;
+	THR_LOCK_RELEASE(curthread, &_suspend_all_lock);
+}
+
+void
+_thr_suspend_all_unlock(struct pthread *curthread)
+{
+
+	THR_LOCK_ACQUIRE(curthread, &_suspend_all_lock);
+	_single_thread = NULL;
+	if (_suspend_all_waiters != 0) {
+		_suspend_all_cycle++;
+		_thr_umtx_wake(&_suspend_all_cycle, INT_MAX, 0);
+	}
+	THR_LOCK_RELEASE(curthread, &_suspend_all_lock);
+}
+
+void
 _pthread_suspend_all_np(void)
 {
 	struct pthread *curthread = _get_curthread();
 	struct pthread *thread;
+	int old_nocancel;
 	int ret;
 
+	old_nocancel = curthread->no_cancel;
+	curthread->no_cancel = 1;
+	_thr_suspend_all_lock(curthread);
 	THREAD_LIST_RDLOCK(curthread);
-
 	TAILQ_FOREACH(thread, &_thread_list, tle) {
 		if (thread != curthread) {
 			THR_THREAD_LOCK(curthread, thread);
@@ -115,8 +150,10 @@
 			THR_THREAD_UNLOCK(curthread, thread);
 		}
 	}
-
 	THREAD_LIST_UNLOCK(curthread);
+	_thr_suspend_all_unlock(curthread);
+	curthread->no_cancel = old_nocancel;
+	_thr_testcancel(curthread);
 }
 
 static int
@@ -123,11 +160,14 @@
 suspend_common(struct pthread *curthread, struct pthread *thread,
 	int waitok)
 {
-	long tmp;
+	uint32_t tmp;
 
 	while (thread->state != PS_DEAD &&
 	      !(thread->flags & THR_FLAGS_SUSPENDED)) {
 		thread->flags |= THR_FLAGS_NEED_SUSPEND;
+		/* Thread is in creation. */
+		if (thread->tid == TID_TERMINATED)
+			return (1);
 		tmp = thread->cycle;
 		_thr_send_sig(thread, SIGCANCEL);
 		THR_THREAD_UNLOCK(curthread, thread);

Modified: trunk/lib/libthr/thread/thr_switch_np.c
===================================================================
--- trunk/lib/libthr/thread/thr_switch_np.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_switch_np.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1998 Daniel Eischen <eischen at vigrid.com>.
  * All rights reserved.
@@ -29,7 +30,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_switch_np.c 157457 2006-04-04 02:57:49Z davidxu $
  */
 
 #include "namespace.h"

Modified: trunk/lib/libthr/thread/thr_symbols.c
===================================================================
--- trunk/lib/libthr/thread/thr_symbols.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_symbols.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2004 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_symbols.c 165967 2007-01-12 07:26:21Z imp $
  */
 
 #include <sys/types.h>

Modified: trunk/lib/libthr/thread/thr_syscalls.c
===================================================================
--- trunk/lib/libthr/thread/thr_syscalls.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_syscalls.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,9 +1,14 @@
+/* $MidnightBSD$ */
 /*
+ * Copyright (c) 2014 The FreeBSD Foundation.
  * Copyright (C) 2005 David Xu <davidxu at freebsd.org>.
  * Copyright (c) 2003 Daniel Eischen <deischen at freebsd.org>.
  * Copyright (C) 2000 Jason Evans <jasone at freebsd.org>.
  * All rights reserved.
  * 
+ * Portions of this software were developed by Konstantin Belousov
+ * under sponsorship from the FreeBSD Foundation.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -27,8 +32,6 @@
  * 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$
  */
 
 /*
@@ -61,6 +64,9 @@
  *
  */
 
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: stable/10/lib/libthr/thread/thr_syscalls.c 296732 2016-03-12 17:33:40Z kib $");
+
 #include "namespace.h"
 #include <sys/types.h>
 #include <sys/mman.h>
@@ -87,83 +93,33 @@
 #include <pthread.h>
 #include "un-namespace.h"
 
+#include "libc_private.h"
 #include "thr_private.h"
 
-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_pselect(int, fd_set *, fd_set *, fd_set *,
-			const struct timespec *, const sigset_t *);
-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,...);
 #ifdef SYSCALL_COMPAT
-extern int __fcntl_compat(int, int,...);
+extern int __fcntl_compat(int, int, ...);
 #endif
-int	__fsync(int);
-int	__msync(void *, size_t, int);
-int	__nanosleep(const struct timespec *, struct timespec *);
-int	__open(const char *, int,...);
-int	__openat(int, 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);
 
-__weak_reference(__accept, accept);
+static int
+__thr_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+{
+	struct pthread *curthread;
+	int ret;
 
+	curthread = _get_curthread();
+	_thr_cancel_enter(curthread);
+	ret = __sys_accept(s, addr, addrlen);
+	_thr_cancel_leave(curthread, ret == -1);
+
+ 	return (ret);
+}
+
 /*
  * Cancellation behavior:
  *   If thread is canceled, no socket is created.
  */
-int
-__accept(int s, struct sockaddr *addr, socklen_t *addrlen)
+static int
+__thr_accept4(int s, struct sockaddr *addr, socklen_t *addrlen, int flags)
 {
 	struct pthread *curthread;
 	int ret;
@@ -170,21 +126,20 @@
 
 	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __sys_accept(s, addr, addrlen);
+	ret = __sys_accept4(s, addr, addrlen, flags);
 	_thr_cancel_leave(curthread, ret == -1);
 
  	return (ret);
 }
 
-__weak_reference(__aio_suspend, aio_suspend);
-
-int
-__aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
+static int
+__thr_aio_suspend(const struct aiocb * const iocbs[], int niocb, const struct
     timespec *timeout)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_aio_suspend(iocbs, niocb, timeout);
 	_thr_cancel_leave(curthread, 1);
@@ -192,8 +147,6 @@
 	return (ret);
 }
 
-__weak_reference(__close, close);
-
 /*
  * Cancellation behavior:
  *   According to manual of close(), the file descriptor is always deleted.
@@ -201,12 +154,13 @@
  *   descriptor is always deleted despite whether the thread is canceled
  *   or not.
  */
-int
-__close(int fd)
+static int
+__thr_close(int fd)
 {
-	struct pthread	*curthread = _get_curthread();
-	int	ret;
+	struct pthread *curthread;
+	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter2(curthread, 0);
 	ret = __sys_close(fd);
 	_thr_cancel_leave(curthread, 1);
@@ -214,18 +168,17 @@
 	return (ret);
 }
 
-__weak_reference(__connect, connect);
-
 /*
  * Cancellation behavior:
  *   If the thread is canceled, connection is not made.
  */
-int
-__connect(int fd, const struct sockaddr *name, socklen_t namelen)
+static int
+__thr_connect(int fd, const struct sockaddr *name, socklen_t namelen)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_connect(fd, name, namelen);
 	_thr_cancel_leave(curthread, ret == -1);
@@ -233,41 +186,21 @@
  	return (ret);
 }
 
-__weak_reference(___creat, creat);
-
 /*
  * Cancellation behavior:
- *   If thread is canceled, file is not created.
- */
-int
-___creat(const char *path, mode_t mode)
-{
-	struct pthread *curthread = _get_curthread();
-	int ret;
-
-	_thr_cancel_enter(curthread);
-	ret = __creat(path, mode);
-	_thr_cancel_leave(curthread, ret == -1);
-	
-	return ret;
-}
-
-__weak_reference(__fcntl, fcntl);
-
-/*
- * Cancellation behavior:
  *   According to specification, only F_SETLKW is a cancellation point.
  *   Thread is only canceled at start, or canceled if the system call
  *   is failure, this means the function does not generate side effect
  *   if it is canceled.
  */
-int
-__fcntl(int fd, int cmd,...)
+static int
+__thr_fcntl(int fd, int cmd, ...)
 {
-	struct pthread *curthread = _get_curthread();
-	int	ret;
+	struct pthread *curthread;
+	int ret;
 	va_list	ap;
 
+	curthread = _get_curthread();
 	va_start(ap, cmd);
 	if (cmd == F_OSETLKW || cmd == F_SETLKW) {
 		_thr_cancel_enter(curthread);
@@ -289,18 +222,17 @@
 	return (ret);
 }
 
-__weak_reference(__fsync, fsync);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled after system call.
  */
-int
-__fsync(int fd)
+static int
+__thr_fsync(int fd)
 {
-	struct pthread *curthread = _get_curthread();
-	int	ret;
+	struct pthread *curthread;
+	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter2(curthread, 0);
 	ret = __sys_fsync(fd);
 	_thr_cancel_leave(curthread, 1);
@@ -308,34 +240,32 @@
 	return (ret);
 }
 
-__weak_reference(__msync, msync);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled after system call.
  */
-int
-__msync(void *addr, size_t len, int flags)
+static int
+__thr_msync(void *addr, size_t len, int flags)
 {
-	struct pthread *curthread = _get_curthread();
-	int	ret;
+	struct pthread *curthread;
+	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter2(curthread, 0);
 	ret = __sys_msync(addr, len, flags);
 	_thr_cancel_leave(curthread, 1);
 
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__nanosleep, nanosleep);
-
-int
-__nanosleep(const struct timespec *time_to_sleep,
+static int
+__thr_nanosleep(const struct timespec *time_to_sleep,
     struct timespec *time_remaining)
 {
-	struct pthread *curthread = _get_curthread();
-	int		ret;
+	struct pthread *curthread;
+	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_nanosleep(time_to_sleep, time_remaining);
 	_thr_cancel_leave(curthread, 1);
@@ -343,99 +273,88 @@
 	return (ret);
 }
 
-__weak_reference(__open, open);
-
 /*
  * Cancellation behavior:
  *   If the thread is canceled, file is not opened.
  */
-int
-__open(const char *path, int flags,...)
+static int
+__thr_openat(int fd, const char *path, int flags, ...)
 {
-	struct pthread *curthread = _get_curthread();
-	int	ret;
-	int	mode = 0;
+	struct pthread *curthread;
+	int mode, ret;
 	va_list	ap;
 
+	
 	/* Check if the file is being created: */
-	if (flags & O_CREAT) {
+	if ((flags & O_CREAT) != 0) {
 		/* Get the creation mode: */
 		va_start(ap, flags);
 		mode = va_arg(ap, int);
 		va_end(ap);
+	} else {
+		mode = 0;
 	}
 	
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __sys_open(path, flags, mode);
+	ret = __sys_openat(fd, path, flags, mode);
 	_thr_cancel_leave(curthread, ret == -1);
 
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__openat, openat);
-
 /*
  * Cancellation behavior:
- *   If the thread is canceled, file is not opened.
+ *   Thread may be canceled at start, but if the system call returns something,
+ *   the thread is not canceled.
  */
-int
-__openat(int fd, const char *path, int flags, ...)
+static int
+__thr_poll(struct pollfd *fds, unsigned int nfds, int timeout)
 {
-	struct pthread *curthread = _get_curthread();
-	int	ret;
-	int	mode = 0;
-	va_list	ap;
+	struct pthread *curthread;
+	int ret;
 
-	
-	/* Check if the file is being created: */
-	if (flags & O_CREAT) {
-		/* Get the creation mode: */
-		va_start(ap, flags);
-		mode = va_arg(ap, int);
-		va_end(ap);
-	}
-	
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __sys_openat(fd, path, flags, mode);
+	ret = __sys_poll(fds, nfds, timeout);
 	_thr_cancel_leave(curthread, ret == -1);
 
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__poll, poll);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call returns something,
  *   the thread is not canceled.
  */
-int
-__poll(struct pollfd *fds, unsigned int nfds, int timeout)
+static int
+__thr_ppoll(struct pollfd pfd[], nfds_t nfds, const struct timespec *
+    timeout, const sigset_t *newsigmask)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __sys_poll(fds, nfds, timeout);
+	ret = __sys_ppoll(pfd, nfds, timeout, newsigmask);
 	_thr_cancel_leave(curthread, ret == -1);
 
-	return ret;
+	return (ret);
 }
 
-__weak_reference(___pselect, pselect);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call returns something,
  *   the thread is not canceled.
  */
-int 
-___pselect(int count, fd_set *rfds, fd_set *wfds, fd_set *efds, 
+static int
+__thr_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();
+	struct pthread *curthread;
 	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_pselect(count, rfds, wfds, efds, timo, mask);
 	_thr_cancel_leave(curthread, ret == -1);
@@ -443,59 +362,79 @@
 	return (ret);
 }
 
-__weak_reference(__read, read);
+static int
+__thr_kevent(int kq, const struct kevent *changelist, int nchanges,
+    struct kevent *eventlist, int nevents, const struct timespec *timeout)
+{
+	struct pthread *curthread;
+	int ret;
 
+	if (nevents == 0) {
+		/*
+		 * No blocking, do not make the call cancellable.
+		 */
+		return (__sys_kevent(kq, changelist, nchanges, eventlist,
+		    nevents, timeout));
+	}
+	curthread = _get_curthread();
+	_thr_cancel_enter(curthread);
+	ret = __sys_kevent(kq, changelist, nchanges, eventlist, nevents,
+	    timeout);
+	_thr_cancel_leave(curthread, ret == -1 && nchanges == 0);
+
+	return (ret);
+}
+
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call got some data, 
  *   the thread is not canceled.
  */
-ssize_t
-__read(int fd, void *buf, size_t nbytes)
+static ssize_t
+__thr_read(int fd, void *buf, size_t nbytes)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t	ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_read(fd, buf, nbytes);
 	_thr_cancel_leave(curthread, ret == -1);
 
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__readv, readv);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call got some data, 
  *   the thread is not canceled.
  */
-ssize_t
-__readv(int fd, const struct iovec *iov, int iovcnt)
+static ssize_t
+__thr_readv(int fd, const struct iovec *iov, int iovcnt)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_readv(fd, iov, iovcnt);
 	_thr_cancel_leave(curthread, ret == -1);
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__recvfrom, recvfrom);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call got some data, 
  *   the thread is not canceled.
  */
-ssize_t
-__recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
+static ssize_t
+__thr_recvfrom(int s, void *b, size_t l, int f, struct sockaddr *from,
     socklen_t *fl)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_recvfrom(s, b, l, f, from, fl);
 	_thr_cancel_leave(curthread, ret == -1);
@@ -502,19 +441,18 @@
 	return (ret);
 }
 
-__weak_reference(__recvmsg, recvmsg);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call got some data, 
  *   the thread is not canceled.
  */
-ssize_t
-__recvmsg(int s, struct msghdr *m, int f)
+static ssize_t
+__thr_recvmsg(int s, struct msghdr *m, int f)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_recvmsg(s, m, f);
 	_thr_cancel_leave(curthread, ret == -1);
@@ -521,39 +459,37 @@
 	return (ret);
 }
 
-__weak_reference(__select, select);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call returns something,
  *   the thread is not canceled.
  */
-int 
-__select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+static int 
+__thr_select(int numfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
 	struct timeval *timeout)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_select(numfds, readfds, writefds, exceptfds, timeout);
 	_thr_cancel_leave(curthread, ret == -1);
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__sendmsg, sendmsg);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call sent
  *   data, the thread is not canceled.
  */
-ssize_t
-__sendmsg(int s, const struct msghdr *m, int f)
+static ssize_t
+__thr_sendmsg(int s, const struct msghdr *m, int f)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_sendmsg(s, m, f);
 	_thr_cancel_leave(curthread, ret <= 0);
@@ -560,20 +496,19 @@
 	return (ret);
 }
 
-__weak_reference(__sendto, sendto);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call sent some
  *   data, the thread is not canceled.
  */
-ssize_t
-__sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
+static ssize_t
+__thr_sendto(int s, const void *m, size_t l, int f, const struct sockaddr *t,
     socklen_t tl)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_sendto(s, m, l, f, t, tl);
 	_thr_cancel_leave(curthread, ret <= 0);
@@ -580,184 +515,159 @@
 	return (ret);
 }
 
-__weak_reference(___sleep, sleep);
-
-unsigned int
-___sleep(unsigned int seconds)
+static int
+__thr_system(const char *string)
 {
-	struct pthread *curthread = _get_curthread();
-	unsigned int	ret;
+	struct pthread *curthread;
+	int ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __sleep(seconds);
+	ret = __libc_system(string);
 	_thr_cancel_leave(curthread, 1);
-	
 	return (ret);
 }
 
-__weak_reference(___system, system);
-
-int
-___system(const char *string)
-{
-	struct pthread *curthread = _get_curthread();
-	int	ret;
-
-	_thr_cancel_enter(curthread);
-	ret = __system(string);
-	_thr_cancel_leave(curthread, 1);
-	
-	return ret;
-}
-
-__weak_reference(___tcdrain, tcdrain);
-
 /*
  * Cancellation behavior:
  *   If thread is canceled, the system call is not completed,
  *   this means not all bytes were drained.
  */
-int
-___tcdrain(int fd)
+static int
+__thr_tcdrain(int fd)
 {
-	struct pthread *curthread = _get_curthread();
-	int	ret;
+	struct pthread *curthread;
+	int ret;
 	
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __tcdrain(fd);
+	ret = __libc_tcdrain(fd);
 	_thr_cancel_leave(curthread, ret == -1);
 	return (ret);
 }
 
-__weak_reference(___usleep, usleep);
-
-int
-___usleep(useconds_t useconds)
-{
-	struct pthread *curthread = _get_curthread();
-	int		ret;
-
-	_thr_cancel_enter(curthread);
-	ret = __usleep(useconds);
-	_thr_cancel_leave(curthread, 1);
-	
-	return (ret);
-}
-
-__weak_reference(___wait, wait);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call returns
  *   a child pid, the thread is not canceled.
  */
-pid_t
-___wait(int *istat)
+static pid_t
+__thr_wait4(pid_t pid, int *status, int options, struct rusage *rusage)
 {
-	struct pthread *curthread = _get_curthread();
-	pid_t	ret;
-
-	_thr_cancel_enter(curthread);
-	ret = __wait(istat);
-	_thr_cancel_leave(curthread, ret <= 0);
-
-	return ret;
-}
-
-__weak_reference(__wait3, wait3);
-
-/*
- * Cancellation behavior:
- *   Thread may be canceled at start, but if the system call returns
- *   a child pid, the thread is not canceled.
- */
-pid_t
-__wait3(int *status, int options, struct rusage *rusage)
-{
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	pid_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = _wait4(WAIT_ANY, status, options, rusage);
+	ret = __sys_wait4(pid, status, options, rusage);
 	_thr_cancel_leave(curthread, ret <= 0);
-
 	return (ret);
 }
 
-__weak_reference(__wait4, wait4);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the system call returns
  *   a child pid, the thread is not canceled.
  */
-pid_t
-__wait4(pid_t pid, int *status, int options, struct rusage *rusage)
+static pid_t
+__thr_wait6(idtype_t idtype, id_t id, int *status, int options,
+    struct __wrusage *ru, siginfo_t *infop)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	pid_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
-	ret = __sys_wait4(pid, status, options, rusage);
+	ret = __sys_wait6(idtype, id, status, options, ru, infop);
 	_thr_cancel_leave(curthread, ret <= 0);
-
-	return ret;
+	return (ret);
 }
 
-__weak_reference(___waitpid, waitpid);
-
 /*
  * Cancellation behavior:
- *   Thread may be canceled at start, but if the system call returns
- *   a child pid, the thread is not canceled.
- */
-pid_t
-___waitpid(pid_t wpid, int *status, int options)
-{
-	struct pthread *curthread = _get_curthread();
-	pid_t	ret;
-
-	_thr_cancel_enter(curthread);
-	ret = __waitpid(wpid, status, options);
-	_thr_cancel_leave(curthread, ret <= 0);
-	
-	return ret;
-}
-
-__weak_reference(__write, write);
-
-/*
- * Cancellation behavior:
  *   Thread may be canceled at start, but if the thread wrote some data,
  *   it is not canceled.
  */
-ssize_t
-__write(int fd, const void *buf, size_t nbytes)
+static ssize_t
+__thr_write(int fd, const void *buf, size_t nbytes)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t	ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_write(fd, buf, nbytes);
 	_thr_cancel_leave(curthread, (ret <= 0));
-	return ret;
+	return (ret);
 }
 
-__weak_reference(__writev, writev);
-
 /*
  * Cancellation behavior:
  *   Thread may be canceled at start, but if the thread wrote some data,
  *   it is not canceled.
  */
-ssize_t
-__writev(int fd, const struct iovec *iov, int iovcnt)
+static ssize_t
+__thr_writev(int fd, const struct iovec *iov, int iovcnt)
 {
-	struct pthread *curthread = _get_curthread();
+	struct pthread *curthread;
 	ssize_t ret;
 
+	curthread = _get_curthread();
 	_thr_cancel_enter(curthread);
 	ret = __sys_writev(fd, iov, iovcnt);
 	_thr_cancel_leave(curthread, (ret <= 0));
-	return ret;
+	return (ret);
 }
+
+void
+__thr_interpose_libc(void)
+{
+
+	__set_error_selector(__error_threaded);
+#define	SLOT(name)					\
+	*(__libc_interposing_slot(INTERPOS_##name)) =	\
+	    (interpos_func_t)__thr_##name;
+	SLOT(accept);
+	SLOT(accept4);
+	SLOT(aio_suspend);
+	SLOT(close);
+	SLOT(connect);
+	SLOT(fcntl);
+	SLOT(fsync);
+	SLOT(fork);
+	SLOT(msync);
+	SLOT(nanosleep);
+	SLOT(openat);
+	SLOT(poll);
+	SLOT(pselect);
+	SLOT(read);
+	SLOT(readv);
+	SLOT(recvfrom);
+	SLOT(recvmsg);
+	SLOT(select);
+	SLOT(sendmsg);
+	SLOT(sendto);
+	SLOT(setcontext);
+	SLOT(sigaction);
+	SLOT(sigprocmask);
+	SLOT(sigsuspend);
+	SLOT(sigwait);
+	SLOT(sigtimedwait);
+	SLOT(sigwaitinfo);
+	SLOT(swapcontext);
+	SLOT(system);
+	SLOT(tcdrain);
+	SLOT(wait4);
+	SLOT(write);
+	SLOT(writev);
+	SLOT(spinlock);
+	SLOT(spinunlock);
+	SLOT(kevent);
+	SLOT(wait6);
+	SLOT(ppoll);
+	SLOT(map_stacks_exec);
+#undef SLOT
+	*(__libc_interposing_slot(
+	    INTERPOS__pthread_mutex_init_calloc_cb)) =
+	    (interpos_func_t)_pthread_mutex_init_calloc_cb;
+}

Modified: trunk/lib/libthr/thread/thr_umtx.c
===================================================================
--- trunk/lib/libthr/thread/thr_umtx.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_umtx.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,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$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_umtx.c 294639 2016-01-23 20:49:52Z vangyzen $
  *
  */
 
@@ -51,6 +52,7 @@
 _thr_urwlock_init(struct urwlock *rwl)
 {
 	static const struct urwlock default_rwl = DEFAULT_URWLOCK;
+
 	*rwl = default_rwl;
 }
 
@@ -109,23 +111,30 @@
 
 int
 __thr_umutex_timedlock(struct umutex *mtx, uint32_t id,
-	const struct timespec *ets)
+	const struct timespec *abstime)
 {
-	struct timespec timo, cts;
+	struct _umtx_time *tm_p, timeout;
+	size_t tm_size;
 	uint32_t owner;
 	int ret;
 
-	clock_gettime(CLOCK_REALTIME, &cts);
-	TIMESPEC_SUB(&timo, ets, &cts);
+	if (abstime == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._clockid = CLOCK_REALTIME;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._timeout = *abstime;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
 
-	if (timo.tv_sec < 0)
-		return (ETIMEDOUT);
-
 	for (;;) {
 		if ((mtx->m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
 
 			/* wait in kernel */
-			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT, 0, 0, &timo);
+			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_WAIT, 0,
+				 (void *)tm_size, __DECONST(void *, tm_p));
 
 			/* now try to lock it */
 			owner = mtx->m_owner;
@@ -133,18 +142,13 @@
 			     atomic_cmpset_acq_32(&mtx->m_owner, owner, id|owner))
 				return (0);
 		} else {
-			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0, 0, &timo);
+			ret = _umtx_op_err(mtx, UMTX_OP_MUTEX_LOCK, 0, 
+				 (void *)tm_size, __DECONST(void *, tm_p));
 			if (ret == 0)
 				break;
 		}
 		if (ret == ETIMEDOUT)
 			break;
-		clock_gettime(CLOCK_REALTIME, &cts);
-		TIMESPEC_SUB(&timo, ets, &cts);
-		if (timo.tv_sec < 0 || (timo.tv_sec == 0 && timo.tv_nsec == 0)) {
-			ret = ETIMEDOUT;
-			break;
-		}
 	}
 	return (ret);
 }
@@ -152,35 +156,6 @@
 int
 __thr_umutex_unlock(struct umutex *mtx, uint32_t id)
 {
-	static int wake2_avail = 0;
-
-	if (__predict_false(wake2_avail == 0)) {
-		struct umutex test = DEFAULT_UMUTEX;
-
-		if (_umtx_op(&test, UMTX_OP_MUTEX_WAKE2, test.m_flags, 0, 0) == -1)
-			wake2_avail = -1;
-		else 
-			wake2_avail = 1;
-	}
-
-	if (wake2_avail != 1)
-		goto unlock;
-
-	uint32_t flags = mtx->m_flags;
-
-	if ((flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
-		uint32_t owner;
-		do {
-			owner = mtx->m_owner;
-			if (__predict_false((owner & ~UMUTEX_CONTESTED) != id))
-				return (EPERM);
-		} while (__predict_false(!atomic_cmpset_rel_32(&mtx->m_owner,
-					 owner, UMUTEX_UNOWNED)));
-		if ((owner & UMUTEX_CONTESTED))
-			(void)_umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE2, flags, 0, 0);
-		return (0);
-	}
-unlock:
 	return _umtx_op_err(mtx, UMTX_OP_MUTEX_UNLOCK, 0, 0, 0);
 }
 
@@ -222,20 +197,23 @@
 _thr_umtx_timedwait_uint(volatile u_int *mtx, u_int id, int clockid,
 	const struct timespec *abstime, int shared)
 {
-	struct timespec ts, ts2, *tsp;
+	struct _umtx_time *tm_p, timeout;
+	size_t tm_size;
 
-	if (abstime != NULL) {
-		clock_gettime(clockid, &ts);
-		TIMESPEC_SUB(&ts2, abstime, &ts);
-		if (ts2.tv_sec < 0 || (ts2.tv_sec == 0 && ts2.tv_nsec <= 0))
-			return (ETIMEDOUT);
-		tsp = &ts2;
+	if (abstime == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
 	} else {
-		tsp = NULL;
+		timeout._clockid = clockid;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._timeout = *abstime;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
 	}
+
 	return _umtx_op_err(__DEVOLATILE(void *, mtx), 
-		shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, NULL,
-			tsp);
+		shared ? UMTX_OP_WAIT_UINT : UMTX_OP_WAIT_UINT_PRIVATE, id, 
+		(void *)tm_size, __DECONST(void *, tm_p));
 }
 
 int
@@ -282,15 +260,42 @@
 }
 
 int
-__thr_rwlock_rdlock(struct urwlock *rwlock, int flags, struct timespec *tsp)
+__thr_rwlock_rdlock(struct urwlock *rwlock, int flags,
+	const struct timespec *tsp)
 {
-	return _umtx_op_err(rwlock, UMTX_OP_RW_RDLOCK, flags, NULL, tsp);
+	struct _umtx_time timeout, *tm_p;
+	size_t tm_size;
+
+	if (tsp == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._timeout = *tsp;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._clockid = CLOCK_REALTIME;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
+	return _umtx_op_err(rwlock, UMTX_OP_RW_RDLOCK, flags, (void *)tm_size, tm_p);
 }
 
 int
-__thr_rwlock_wrlock(struct urwlock *rwlock, struct timespec *tsp)
+__thr_rwlock_wrlock(struct urwlock *rwlock, const struct timespec *tsp)
 {
-	return _umtx_op_err(rwlock, UMTX_OP_RW_WRLOCK, 0, NULL, tsp);
+	struct _umtx_time timeout, *tm_p;
+	size_t tm_size;
+
+	if (tsp == NULL) {
+		tm_p = NULL;
+		tm_size = 0;
+	} else {
+		timeout._timeout = *tsp;
+		timeout._flags = UMTX_ABSTIME;
+		timeout._clockid = CLOCK_REALTIME;
+		tm_p = &timeout;
+		tm_size = sizeof(timeout);
+	}
+	return _umtx_op_err(rwlock, UMTX_OP_RW_WRLOCK, 0, (void *)tm_size, tm_p);
 }
 
 int

Modified: trunk/lib/libthr/thread/thr_umtx.h
===================================================================
--- trunk/lib/libthr/thread/thr_umtx.h	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_umtx.h	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*-
  * Copyright (c) 2005 David Xu <davidxu at freebsd.org>
  * All rights reserved.
@@ -23,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_umtx.h 249985 2013-04-27 14:21:36Z jilles $
  */
 
 #ifndef _THR_FBSD_UMTX_H_
@@ -56,13 +57,15 @@
 	const struct timespec *timeout, int shared) __hidden;
 int _thr_umtx_wake(volatile void *mtx, int count, int shared) __hidden;
 int _thr_ucond_wait(struct ucond *cv, struct umutex *m,
-        const struct timespec *timeout, int check_unpaking) __hidden;
+        const struct timespec *timeout, int flags) __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;
 
-int __thr_rwlock_rdlock(struct urwlock *rwlock, int flags, struct timespec *tsp) __hidden;
-int __thr_rwlock_wrlock(struct urwlock *rwlock, struct timespec *tsp) __hidden;
+int __thr_rwlock_rdlock(struct urwlock *rwlock, int flags,
+	const struct timespec *tsp) __hidden;
+int __thr_rwlock_wrlock(struct urwlock *rwlock,
+	const struct timespec *tsp) __hidden;
 int __thr_rwlock_unlock(struct urwlock *rwlock) __hidden;
 
 /* Internal used only */
@@ -118,8 +121,26 @@
 }
 
 static inline int
-_thr_umutex_unlock(struct umutex *mtx, uint32_t id)
+_thr_umutex_unlock2(struct umutex *mtx, uint32_t id, int *defer)
 {
+	uint32_t flags = mtx->m_flags;
+
+	if ((flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT)) == 0) {
+		uint32_t owner;
+		do {
+			owner = mtx->m_owner;
+			if (__predict_false((owner & ~UMUTEX_CONTESTED) != id))
+				return (EPERM);
+		} while (__predict_false(!atomic_cmpset_rel_32(&mtx->m_owner,
+					 owner, UMUTEX_UNOWNED)));
+		if ((owner & UMUTEX_CONTESTED)) {
+			if (defer == NULL)
+				(void)_umtx_op_err(mtx, UMTX_OP_MUTEX_WAKE2, flags, 0, 0);
+			else
+				*defer = 1;
+		}
+		return (0);
+	}
     	if (atomic_cmpset_rel_32(&mtx->m_owner, id, UMUTEX_UNOWNED))
 		return (0);
 	return (__thr_umutex_unlock(mtx, id));
@@ -126,6 +147,12 @@
 }
 
 static inline int
+_thr_umutex_unlock(struct umutex *mtx, uint32_t id)
+{
+	return _thr_umutex_unlock2(mtx, id, NULL);
+}
+
+static inline int
 _thr_rwlock_tryrdlock(struct urwlock *rwlock, int flags)
 {
 	int32_t state;

Modified: trunk/lib/libthr/thread/thr_yield.c
===================================================================
--- trunk/lib/libthr/thread/thr_yield.c	2018-06-09 16:41:21 UTC (rev 10632)
+++ trunk/lib/libthr/thread/thr_yield.c	2018-06-09 16:42:31 UTC (rev 10633)
@@ -1,3 +1,4 @@
+/* $MidnightBSD$ */
 /*
  * Copyright (c) 1995 John Birrell <jb at cimlogic.com.au>.
  * All rights reserved.
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD$
+ * $FreeBSD: stable/10/lib/libthr/thread/thr_yield.c 165967 2007-01-12 07:26:21Z imp $
  */
 
 #include "namespace.h"



More information about the Midnightbsd-cvs mailing list