[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