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