Module Name: src
Committed By: christos
Date: Sun Jul 3 14:24:59 UTC 2016
Modified Files:
src/lib/libc/gen: sysconf.3 sysconf.c
src/lib/libc/sys: Makefile.inc
src/lib/libpthread: Makefile pthread.h pthread_barrier.3
pthread_barrier.c pthread_barrierattr.3 pthread_cond.c
pthread_condattr.3 pthread_mutex.3 pthread_mutex.c
pthread_mutexattr.3 pthread_rwlock.c pthread_rwlockattr.3
pthread_types.h
src/sys/kern: kern_lwp.c kern_sleepq.c kern_synch.c sys_sched.c
syscalls.master
src/sys/sys: lwp.h sched.h unistd.h
src/tests/lib/libpthread: t_cond.c t_mutex.c
Log Message:
GSoC 2016 Charles Cui: Implement thread priority protection based on work
by Andy Doran. Also document the get/set pshared thread calls as not
implemented, and add a skeleton implementation that is disabled.
XXX: document _sched_protect(2).
To generate a diff of this commit:
cvs rdiff -u -r1.48 -r1.49 src/lib/libc/gen/sysconf.3
cvs rdiff -u -r1.39 -r1.40 src/lib/libc/gen/sysconf.c
cvs rdiff -u -r1.230 -r1.231 src/lib/libc/sys/Makefile.inc
cvs rdiff -u -r1.86 -r1.87 src/lib/libpthread/Makefile
cvs rdiff -u -r1.36 -r1.37 src/lib/libpthread/pthread.h
cvs rdiff -u -r1.4 -r1.5 src/lib/libpthread/pthread_barrier.3
cvs rdiff -u -r1.19 -r1.20 src/lib/libpthread/pthread_barrier.c
cvs rdiff -u -r1.9 -r1.10 src/lib/libpthread/pthread_barrierattr.3 \
src/lib/libpthread/pthread_condattr.3
cvs rdiff -u -r1.63 -r1.64 src/lib/libpthread/pthread_cond.c
cvs rdiff -u -r1.6 -r1.7 src/lib/libpthread/pthread_mutex.3
cvs rdiff -u -r1.59 -r1.60 src/lib/libpthread/pthread_mutex.c
cvs rdiff -u -r1.11 -r1.12 src/lib/libpthread/pthread_mutexattr.3
cvs rdiff -u -r1.33 -r1.34 src/lib/libpthread/pthread_rwlock.c
cvs rdiff -u -r1.8 -r1.9 src/lib/libpthread/pthread_rwlockattr.3
cvs rdiff -u -r1.17 -r1.18 src/lib/libpthread/pthread_types.h
cvs rdiff -u -r1.184 -r1.185 src/sys/kern/kern_lwp.c
cvs rdiff -u -r1.50 -r1.51 src/sys/kern/kern_sleepq.c
cvs rdiff -u -r1.310 -r1.311 src/sys/kern/kern_synch.c
cvs rdiff -u -r1.43 -r1.44 src/sys/kern/sys_sched.c
cvs rdiff -u -r1.284 -r1.285 src/sys/kern/syscalls.master
cvs rdiff -u -r1.171 -r1.172 src/sys/sys/lwp.h
cvs rdiff -u -r1.75 -r1.76 src/sys/sys/sched.h
cvs rdiff -u -r1.58 -r1.59 src/sys/sys/unistd.h
cvs rdiff -u -r1.6 -r1.7 src/tests/lib/libpthread/t_cond.c
cvs rdiff -u -r1.7 -r1.8 src/tests/lib/libpthread/t_mutex.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libc/gen/sysconf.3
diff -u src/lib/libc/gen/sysconf.3:1.48 src/lib/libc/gen/sysconf.3:1.49
--- src/lib/libc/gen/sysconf.3:1.48 Fri Jun 10 19:29:20 2016
+++ src/lib/libc/gen/sysconf.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: sysconf.3,v 1.48 2016/06/10 23:29:20 christos Exp $
+.\" $NetBSD: sysconf.3,v 1.49 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 1993
.\" The Regents of the University of California. All rights reserved.
@@ -178,6 +178,8 @@ and its
Threads
option to which the system attempts to conform,
otherwise \-1.
+.It Li _SC_THREAD_PRIO_PROTECT
+System supports the priority ceiling protocol for POSIX threads.
.It Li _SC_TIMERS
The version of
.St -p1003.1
Index: src/lib/libc/gen/sysconf.c
diff -u src/lib/libc/gen/sysconf.c:1.39 src/lib/libc/gen/sysconf.c:1.40
--- src/lib/libc/gen/sysconf.c:1.39 Fri Jun 10 19:29:20 2016
+++ src/lib/libc/gen/sysconf.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: sysconf.c,v 1.39 2016/06/10 23:29:20 christos Exp $ */
+/* $NetBSD: sysconf.c,v 1.40 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)sysconf.c 8.2 (Berkeley) 3/20/94";
#else
-__RCSID("$NetBSD: sysconf.c,v 1.39 2016/06/10 23:29:20 christos Exp $");
+__RCSID("$NetBSD: sysconf.c,v 1.40 2016/07/03 14:24:58 christos Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -411,9 +411,10 @@ yesno: if (sysctl(mib, mib_len, &value,
return _POSIX_THREAD_ATTR_STACKSIZE;
case _SC_THREAD_SAFE_FUNCTIONS:
return _POSIX_THREAD_SAFE_FUNCTIONS;
+ case _SC_THREAD_PRIO_PROTECT:
+ return _POSIX_THREAD_PRIO_PROTECT;
case _SC_THREAD_PRIORITY_SCHEDULING:
case _SC_THREAD_PRIO_INHERIT:
- case _SC_THREAD_PRIO_PROTECT:
case _SC_THREAD_PROCESS_SHARED:
return -1;
case _SC_TTY_NAME_MAX:
Index: src/lib/libc/sys/Makefile.inc
diff -u src/lib/libc/sys/Makefile.inc:1.230 src/lib/libc/sys/Makefile.inc:1.231
--- src/lib/libc/sys/Makefile.inc:1.230 Sat Apr 23 19:11:31 2016
+++ src/lib/libc/sys/Makefile.inc Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile.inc,v 1.230 2016/04/23 23:11:31 christos Exp $
+# $NetBSD: Makefile.inc,v 1.231 2016/07/03 14:24:58 christos Exp $
# @(#)Makefile.inc 8.3 (Berkeley) 10/24/94
# sys sources
@@ -173,7 +173,7 @@ WEAKASM= accept.S __aio_suspend50.S clos
msgrcv.S msgsnd.S __msync13.S __nanosleep50.S open.S poll.S \
__pollts50.S __pselect50.S read.S readlink.S \
readv.S _sched_setparam.S _sched_getparam.S _sched_setaffinity.S \
- _sched_getaffinity.S sched_yield.S \
+ _sched_getaffinity.S sched_yield.S _sched_protect.S \
__select50.S setcontext.S __sigprocmask14.S __sigsuspend14.S sysarch.S \
__wait450.S wait6.S write.S writev.S
Index: src/lib/libpthread/Makefile
diff -u src/lib/libpthread/Makefile:1.86 src/lib/libpthread/Makefile:1.87
--- src/lib/libpthread/Makefile:1.86 Sat Apr 23 19:12:19 2016
+++ src/lib/libpthread/Makefile Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.86 2016/04/23 23:12:19 christos Exp $
+# $NetBSD: Makefile,v 1.87 2016/07/03 14:24:58 christos Exp $
#
WARNS?= 5
@@ -177,6 +177,8 @@ MLINKS+= pthread_barrier.3 pthread_barri
MLINKS+= pthread_barrierattr.3 pthread_barrierattr_init.3
MLINKS+= pthread_barrierattr.3 pthread_barrierattr_destroy.3
+MLINKS+= pthread_barrierattr.3 pthread_barrierattr_getpshared.3
+MLINKS+= pthread_barrierattr.3 pthread_barrierattr_setpshared.3
MLINKS+= pthread_cond.3 pthread_cond_init.3
MLINKS+= pthread_cond.3 pthread_cond_destroy.3
@@ -188,6 +190,9 @@ MLINKS+= pthread_cond.3 pthread_cond_tim
MLINKS+= pthread_condattr.3 pthread_condattr_init.3
MLINKS+= pthread_condattr.3 pthread_condattr_destroy.3
MLINKS+= pthread_condattr.3 pthread_condattr_setclock.3
+MLINKS+= pthread_condattr.3 pthread_condattr_getclock.3
+MLINKS+= pthread_condattr.3 pthread_condattr_getpshared.3
+MLINKS+= pthread_condattr.3 pthread_condattr_setpshared.3
MLINKS+= pthread_getname_np.3 pthread_setname_np.3
MLINKS+= pthread_getspecific.3 pthread_setspecific.3
@@ -198,11 +203,20 @@ MLINKS+= pthread_mutex.3 pthread_mutex_d
MLINKS+= pthread_mutex.3 pthread_mutex_lock.3
MLINKS+= pthread_mutex.3 pthread_mutex_trylock.3
MLINKS+= pthread_mutex.3 pthread_mutex_unlock.3
+MLINKS+= pthread_mutex.3 pthread_mutex_timedlock.3
+MLINKS+= pthread_mutex.3 pthread_mutex_getprioceiling.3
+MLINKS+= pthread_mutex.3 pthread_mutex_setprioceiling.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_init.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_destroy.3
+MLINKS+= pthread_mutexattr.3 pthread_mutexattr_getpshared.3
+MLINKS+= pthread_mutexattr.3 pthread_mutexattr_setpshared.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_settype.3
MLINKS+= pthread_mutexattr.3 pthread_mutexattr_gettype.3
+MLINKS+= pthread_mutexattr.3 pthread_mutexattr_getprotocol.3
+MLINKS+= pthread_mutexattr.3 pthread_mutexattr_setprotocol.3
+MLINKS+= pthread_mutexattr.3 pthread_mutexattr_getprioceiling.3
+MLINKS+= pthread_mutexattr.3 pthread_mutexattr_setprioceiling.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_init.3
MLINKS+= pthread_rwlock.3 pthread_rwlock_destroy.3
@@ -217,6 +231,8 @@ MLINKS+= pthread_rwlock.3 pthread_rwlock
MLINKS+= pthread_rwlockattr.3 pthread_rwlockattr_init.3
MLINKS+= pthread_rwlockattr.3 pthread_rwlockattr_destroy.3
+MLINKS+= pthread_rwlockattr.3 pthread_rwlockattr_getpshared.3
+MLINKS+= pthread_rwlockattr.3 pthread_rwlockattr_setpshared.3
MLINKS+= pthread_spin.3 pthread_spin_init.3
MLINKS+= pthread_spin.3 pthread_spin_destroy.3
Index: src/lib/libpthread/pthread.h
diff -u src/lib/libpthread/pthread.h:1.36 src/lib/libpthread/pthread.h:1.37
--- src/lib/libpthread/pthread.h:1.36 Sat Apr 23 19:12:19 2016
+++ src/lib/libpthread/pthread.h Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread.h,v 1.36 2016/04/23 23:12:19 christos Exp $ */
+/* $NetBSD: pthread.h,v 1.37 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2001 The NetBSD Foundation, Inc.
@@ -94,12 +94,30 @@ int pthread_mutex_destroy(pthread_mutex_
int pthread_mutex_lock(pthread_mutex_t *);
int pthread_mutex_trylock(pthread_mutex_t *);
int pthread_mutex_unlock(pthread_mutex_t *);
+int pthread_mutex_timedlock(pthread_mutex_t *,
+ const struct timespec * __restrict);
+int pthread_mutex_getprioceiling(const pthread_mutex_t * __restrict,
+ int * __restrict);
+int pthread_mutex_setprioceiling(pthread_mutex_t * __restrict, int,
+ int * __restrict);
int pthread_mutexattr_init(pthread_mutexattr_t *);
int pthread_mutexattr_destroy(pthread_mutexattr_t *);
+#ifdef _PTHREAD_PSHARED
+int pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int);
+#endif
int pthread_mutexattr_gettype(const pthread_mutexattr_t * __restrict,
int * __restrict);
int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int);
-
+int pthread_mutexattr_getprotocol(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_setprotocol(pthread_mutexattr_t*,
+ int);
+int pthread_mutexattr_getprioceiling(const pthread_mutexattr_t * __restrict,
+ int * __restrict);
+int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *,
+ int);
int pthread_cond_init(pthread_cond_t * __restrict,
const pthread_condattr_t * __restrict);
int pthread_cond_destroy(pthread_cond_t *);
@@ -114,9 +132,15 @@ int pthread_cond_broadcast(pthread_cond_
int pthread_condattr_init(pthread_condattr_t *);
#if defined(_NETBSD_SOURCE)
int pthread_condattr_setclock(pthread_condattr_t *, clockid_t);
+int pthread_condattr_getclock(const pthread_condattr_t * __restrict,
+ clockid_t * __restrict);
#endif
int pthread_condattr_destroy(pthread_condattr_t *);
-
+#ifdef _PTHREAD_PSHARED
+int pthread_condattr_getpshared(const pthread_condattr_t * __restrict,
+ int * __restrict);
+int pthread_condattr_setpshared(pthread_condattr_t *, int);
+#endif
int pthread_once(pthread_once_t *, void (*)(void));
int pthread_key_create(pthread_key_t *, void (*)(void *));
@@ -178,14 +202,22 @@ int pthread_rwlock_timedwrlock(pthread_r
int pthread_rwlock_unlock(pthread_rwlock_t *);
int pthread_rwlockattr_init(pthread_rwlockattr_t *);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *);
-
+#ifdef _PTHREAD_PSHARED
+int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict,
+ int * __restrict);
+int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int);
+#endif
int pthread_barrier_init(pthread_barrier_t * __restrict,
const pthread_barrierattr_t * __restrict, unsigned int);
int pthread_barrier_wait(pthread_barrier_t *);
int pthread_barrier_destroy(pthread_barrier_t *);
int pthread_barrierattr_init(pthread_barrierattr_t *);
int pthread_barrierattr_destroy(pthread_barrierattr_t *);
-
+#ifdef _PTHREAD_PSHARED
+int pthread_barrierattr_getpshared(const pthread_barrierattr_t * __restrict,
+ int * __restrict);
+int pthread_barrierattr_setpshared(pthread_barrierattr_t *, int);
+#endif
int pthread_getschedparam(pthread_t, int * __restrict,
struct sched_param * __restrict);
int pthread_setschedparam(pthread_t, int, const struct sched_param *);
@@ -251,6 +283,10 @@ __END_DECLS
#define PTHREAD_MUTEX_RECURSIVE 2
#define PTHREAD_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
+#define PTHREAD_PRIO_NONE 0
+#define PTHREAD_PRIO_INHERIT 1
+#define PTHREAD_PRIO_PROTECT 2
+
#define PTHREAD_COND_INITIALIZER _PTHREAD_COND_INITIALIZER
#define PTHREAD_MUTEX_INITIALIZER _PTHREAD_MUTEX_INITIALIZER
#define PTHREAD_ONCE_INIT _PTHREAD_ONCE_INIT
Index: src/lib/libpthread/pthread_barrier.3
diff -u src/lib/libpthread/pthread_barrier.3:1.4 src/lib/libpthread/pthread_barrier.3:1.5
--- src/lib/libpthread/pthread_barrier.3:1.4 Fri Jul 9 14:07:20 2010
+++ src/lib/libpthread/pthread_barrier.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_barrier.3,v 1.4 2010/07/09 18:07:20 jruoho Exp $
+.\" $NetBSD: pthread_barrier.3,v 1.5 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -25,7 +25,8 @@
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.\" ----------------------------------------------------------------------------
-.Dd July 8, 2010
+
+.Dd June 12, 2016
.Dt PTHREAD_BARRIER 3
.Os
.Sh NAME
@@ -42,7 +43,14 @@
.Fn pthread_barrier_destroy "pthread_barrier_t *barrier"
.Ft int
.Fn pthread_barrier_wait "pthread_barrier_t *barrier"
+.Ft int
+.Fn pthread_barrierattr_getpshared "const pthread_barrierattr_t * __restrict attr" \
+"int * __restrict pshared"
+.Ft int
+.Fn pthread_barrierattr_setpshared "pthread_barrierattr_t * attr" \
+"int pshared"
.\" ----------------------------------------------------------------------------
+
.Sh DESCRIPTION
The
.Fn pthread_barrier_init
@@ -87,7 +95,18 @@ call have called
all threads will wake up, return from their respective
.Fn pthread_barrier_wait
calls and continue execution.
+.Pp
+.\" -----
+The
+.Fn pthread_barrierattr_getpshared
+function shall obtain the value of the process-shared attribute from the
+attributes object referenced by attr.
+The
+.Fn pthread_barrierattr_setpshared
+function shall set the process-shared attribute in an initialized attributes
+object referenced by attr.
.\" ----------------------------------------------------------------------------
+
.Sh RETURN VALUES
If successful,
.Fn pthread_barrier_init
@@ -113,7 +132,23 @@ It is the responsibility of this thread
and atomicity of any updates to shared data with respect to the
other threads participating in the barrier.
In the case of failure, an error value will be returned.
+.Pp
+.\" -----
+If successful,
+.Fn pthread_barrierattr_getpshared
+shall return zero and store the value of the process-shared attribute of attr
+into the object referenced by the
+.Fa pshared
+parameter.
+Otherwise, an error number shall be returned to indicate the error.
+.Pp
+.\" -----
+If successful,
+.Fn pthread_barrierattr_setpshared
+shall return zero;
+Otherwise, an error number shall be returned to indicate the error.
.\" ----------------------------------------------------------------------------
+
.Sh ERRORS
The
.Fn pthread_barrier_init
@@ -152,6 +187,20 @@ The value specified by
.Fa barrier
is invalid.
.El
+.Pp
+.\" -----
+The
+.Fn pthread_barrierattr_setpshared
+function and
+the
+.Fn pthread_barrierattr_getpshared
+function may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+
.\" ---------------------------------------------------------------------------
.Sh SEE ALSO
.Xr pthread_barrierattr 3 ,
@@ -160,3 +209,10 @@ is invalid.
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .
+.Sh BUGS
+The
+.Fn pthread_barrierattr_getpshared
+and
+.Fn pthread_barrierattr_setpshared
+functions are hidden by default since only thread shared attributes
+are supported.
Index: src/lib/libpthread/pthread_barrier.c
diff -u src/lib/libpthread/pthread_barrier.c:1.19 src/lib/libpthread/pthread_barrier.c:1.20
--- src/lib/libpthread/pthread_barrier.c:1.19 Thu Jan 29 16:19:35 2009
+++ src/lib/libpthread/pthread_barrier.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_barrier.c,v 1.19 2009/01/29 21:19:35 ad Exp $ */
+/* $NetBSD: pthread_barrier.c,v 1.20 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2001, 2003, 2006, 2007, 2009 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_barrier.c,v 1.19 2009/01/29 21:19:35 ad Exp $");
+__RCSID("$NetBSD: pthread_barrier.c,v 1.20 2016/07/03 14:24:58 christos Exp $");
#include <errno.h>
@@ -117,6 +117,29 @@ pthread_barrier_wait(pthread_barrier_t *
return 0;
}
+#ifdef _PTHREAD_PSHARED
+int
+pthread_barrierattr_getpshared(const pthread_barrierattr_t * __restrict attr,
+ int * __restrict pshared)
+{
+
+ *pshared = PTHREAD_PROCESS_PRIVATE;
+ return 0;
+}
+
+int
+pthread_barrierattr_setpshared(pthread_barrierattr_t *attr, int pshared)
+{
+
+ switch(pshared) {
+ case PTHREAD_PROCESS_PRIVATE:
+ return 0;
+ case PTHREAD_PROCESS_SHARED:
+ return ENOSYS;
+ }
+ return EINVAL;
+}
+#endif
int
pthread_barrierattr_init(pthread_barrierattr_t *attr)
Index: src/lib/libpthread/pthread_barrierattr.3
diff -u src/lib/libpthread/pthread_barrierattr.3:1.9 src/lib/libpthread/pthread_barrierattr.3:1.10
--- src/lib/libpthread/pthread_barrierattr.3:1.9 Fri Jul 9 06:45:36 2010
+++ src/lib/libpthread/pthread_barrierattr.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_barrierattr.3,v 1.9 2010/07/09 10:45:36 wiz Exp $
+.\" $NetBSD: pthread_barrierattr.3,v 1.10 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -22,12 +22,14 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
-.Dd July 9, 2010
+.Dd June 12, 2016
.Dt PTHREAD_BARRIERATTR 3
.Os
.Sh NAME
.Nm pthread_barrierattr_init ,
.Nm pthread_barrierattr_destroy ,
+.Nm pthread_barrierattr_getpshared ,
+.Nm pthread_barrierattr_setpshared
.Nd barrier attribute operations
.Sh LIBRARY
.Lb libpthread
@@ -37,6 +39,10 @@
.Fn pthread_barrierattr_init "pthread_barrierattr_t *attr"
.Ft int
.Fn pthread_barrierattr_destroy "pthread_barrierattr_t *attr"
+.Ft int
+.Fn pthread_barrierattr_getpshared "const pthread_barrierattr_t * __restrict attr" "int * __restrict pshared"
+.Ft int
+.Fn pthread_barrierattr_setpshared "pthread_barrierattr_t * attr" "int pshared"
.Sh DESCRIPTION
Barrier attributes are used to specify parameters to be used with
.Xr pthread_barrier_init 3 .
@@ -54,6 +60,19 @@ The
.Fn pthread_barrierattr_destroy
function destroys
.Fa attr .
+.Pp
+The
+.Fn pthread_barrierattr_getpshared
+function shall obtain the value of the process-shared attribute
+from the attributes object referenced by
+.Fa attr .
+.Pp
+The
+.Fn pthread_barrierattr_setpshared
+function shall set the process-shared attribute in an initialized
+attributes object referenced by
+.Fa attr .
+
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
@@ -70,8 +89,27 @@ The value specified by
.Fa attr
is invalid.
.El
+.Pp
+The
+.Fn pthread_barrierattr_getpshared
+and
+.Fn pthread_barrierattr_setpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
.Sh SEE ALSO
.Xr pthread_barrier_init 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .
+.Sh BUGS
+The
+.Fn pthread_barrierattr_getpshared
+and
+.Fn pthread_barrierattr_setpshared
+functions are hidden by default since only thread shared attributes
+are supported.
Index: src/lib/libpthread/pthread_condattr.3
diff -u src/lib/libpthread/pthread_condattr.3:1.9 src/lib/libpthread/pthread_condattr.3:1.10
--- src/lib/libpthread/pthread_condattr.3:1.9 Sat Nov 3 05:20:36 2012
+++ src/lib/libpthread/pthread_condattr.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_condattr.3,v 1.9 2012/11/03 09:20:36 wiz Exp $
+.\" $NetBSD: pthread_condattr.3,v 1.10 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -50,11 +50,15 @@
.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/lib/libpthread/man/pthread_condattr.3,v 1.10 2002/09/16 19:29:28 mini Exp $
-.Dd November 2, 2012
+.Dd June 12, 2016
.Dt PTHREAD_CONDATTR 3
.Os
.Sh NAME
-.Nm pthread_condattr_init
+.Nm pthread_condattr_init,
+.Nm pthread_condattr_getpshared,
+.Nm pthread_condattr_setpshared,
+.Nm pthread_condattr_getclock,
+.Nm pthread_condattr_setclock
.Nd condition attribute operations
.Sh LIBRARY
.Lb libpthread
@@ -63,9 +67,16 @@
.Ft int
.Fn pthread_condattr_init "pthread_condattr_t *attr"
.Ft int
+.Fn pthread_condattr_getclock "const pthread_condattr_t *__restrict attr" \
+"clockid_t * __restrict clock_id"
+.Ft int
.Fn pthread_condattr_setclock "pthread_condattr_t *attr" "clockid_t clock"
.Ft int
.Fn pthread_condattr_destroy "pthread_condattr_t *attr"
+.Ft int
+.Fn pthread_condattr_getpshared "const pthread_condattr_t * __restrict attr" "int * __restrict pshared"
+.Ft int
+.Fn pshared_condattr_setpshared "pthread_condattr_t *attr" "int pshared"
.Sh DESCRIPTION
Condition attribute objects are used to specify parameters to the
.Xr pthread_cond_init 3
@@ -77,6 +88,12 @@ and the
.Fn pthread_condattr_destroy
function destroys a condition attribute object.
The
+.Fn pthread_condattr_getclock
+function shall obtain the value of the
+.Fa clock
+attributes object referenced by
+.Fa attr.
+The
.Fn pthread_condattr_setclock
function sets the system clock to be used for time comparisons to
the one specified in
@@ -86,6 +103,16 @@ Valid clock values are
and
.Dv CLOCK_REALTIME
(the default).
+The
+.Fn pthread_condattr_getpshared
+function shall obtain the value of the process-shared attribute from the
+attributes object referenced by
+.Fa attr.
+The
+.Fn pthread_condattr_setpshared
+function shall set the process-shared attribute in an initialized attributes
+object referenced by
+.Fa attr.
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
@@ -102,6 +129,28 @@ The value specified by
.Fa attr
is invalid.
.El
+.Pp
+The
+.Fn pthread_condattr_getclock
+and
+.Fn pthread_condattr_setclock
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr is invalid.
+.El
+.Pp
+The
+.Fn pthread_condattr_getpshared
+and
+.Fn pthread_condattr_setpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
.Sh SEE ALSO
.Xr pthread_cond_init 3
.Sh STANDARDS
@@ -115,3 +164,10 @@ These functions do not conform to the
.St -p1003.1-2008
revision of the standard, which mandates two additional attributes,
the clock attribute and the process-shared attribute.
+.Sh BUGS
+The
+.Fn pthread_condattr_getpshared
+and
+.Fn pthread_condattr_setpshared
+functions are hidden by default since only thread shared attributes
+are supported.
Index: src/lib/libpthread/pthread_cond.c
diff -u src/lib/libpthread/pthread_cond.c:1.63 src/lib/libpthread/pthread_cond.c:1.64
--- src/lib/libpthread/pthread_cond.c:1.63 Fri Jan 31 15:44:01 2014
+++ src/lib/libpthread/pthread_cond.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_cond.c,v 1.63 2014/01/31 20:44:01 christos Exp $ */
+/* $NetBSD: pthread_cond.c,v 1.64 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -46,7 +46,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_cond.c,v 1.63 2014/01/31 20:44:01 christos Exp $");
+__RCSID("$NetBSD: pthread_cond.c,v 1.64 2016/07/03 14:24:58 christos Exp $");
#include <stdlib.h>
#include <errno.h>
@@ -370,6 +370,16 @@ pthread_condattr_setclock(pthread_condat
}
int
+pthread_condattr_getclock(const pthread_condattr_t *__restrict attr,
+ clockid_t *__restrict clock_id)
+{
+ if (attr == NULL || attr->ptca_private == NULL)
+ return EINVAL;
+ *clock_id = *(clockid_t *)attr->ptca_private;
+ return 0;
+}
+
+int
pthread_condattr_destroy(pthread_condattr_t *attr)
{
@@ -382,6 +392,30 @@ pthread_condattr_destroy(pthread_condatt
return 0;
}
+#ifdef _PTHREAD_PSHARED
+int
+pthread_condattr_getpshared(const pthread_condattr_t * __restrict attr,
+ int * __restrict pshared)
+{
+
+ *pshared = PTHREAD_PROCESS_PRIVATE;
+ return 0;
+}
+
+int
+pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
+{
+
+ switch(pshared) {
+ case PTHREAD_PROCESS_PRIVATE:
+ return 0;
+ case PTHREAD_PROCESS_SHARED:
+ return ENOSYS;
+ }
+ return EINVAL;
+}
+#endif
+
/* Utility routine to hang out for a while if threads haven't started yet. */
static int
pthread_cond_wait_nothread(pthread_t self, pthread_mutex_t *mutex,
Index: src/lib/libpthread/pthread_mutex.3
diff -u src/lib/libpthread/pthread_mutex.3:1.6 src/lib/libpthread/pthread_mutex.3:1.7
--- src/lib/libpthread/pthread_mutex.3:1.6 Mon Nov 12 18:11:05 2012
+++ src/lib/libpthread/pthread_mutex.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_mutex.3,v 1.6 2012/11/12 23:11:05 uwe Exp $
+.\" $NetBSD: pthread_mutex.3,v 1.7 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -52,7 +52,7 @@
.\" SUCH DAMAGE.
.\"
.\" ----------------------------------------------------------------------------
-.Dd July 8, 2010
+.Dd June 12, 2016
.Dt PTHREAD_MUTEX 3
.Os
.Sh NAME
@@ -75,6 +75,14 @@
.Fn pthread_mutex_trylock "pthread_mutex_t *mutex"
.Ft int
.Fn pthread_mutex_unlock "pthread_mutex_t *mutex"
+.Ft int
+.Fn pthread_mutex_timedlock "pthread_mutex_t * mutex" "const struct timespec *__restrict timeout"
+.Ft int
+.Fn pthread_mutex_getprioceiling "const pthread_mutex_t * __restrict mutex" "int * __restrict prioceiling"
+.Ft int
+.Fn pthread_mutex_setprioceiling "pthread_mutex_t * __restrict mutex" \
+"int prioceiling" "int * __restrict old_ceiling"
+
.\" ----------------------------------------------------------------------------
.Sh DESCRIPTION
The
@@ -135,7 +143,45 @@ When operating with the default mutex ty
undefined behavior follows if a thread tries to unlock a mutex
that has not been locked by it, or if a thread tries to release
a mutex that is already unlocked.
+.Pp
+.\" -----
+The
+.Fn pthread_mutex_timedlock
+function shall lock the mutex object referenced by
+.Fa mutex.
+If the mutex is already locked, the calling thread shall block until
+the mutex becomes available in the
+.Fn pthread_mutex_lock
+function.
+If the mutex cannot be locked without waiting for another thread to
+unlock the mutex, this wait shall be terminated when the specified timeout
+expires.
+The timeout shall expire when the absolute time specified by
+.Fa timeout
+passes, as measured by the clock on which timeouts are based.
+.Pp
+.\" -----
+The
+.Fn pthread_mutex_getprioceiling
+function shall return the current priority ceiling of the mutex.
+.Pp
+.\" -----
+The
+.Fn pthread_mutex_setprioceiling
+function shall either lock the mutex if it is unlocked, or block until
+it can sucessfully lock the mutex, then it shall change the mutex's priority
+ceiling and release the mutex.
+When the change is successful, the previous value of the priority ceiling
+shall be returned
+in
+.Fa old_ceiling.
+The process of locking the mutex need not adhere to the priority
+protect protocol.
+If
+.Fn pthread_mutex_setprioceiling
+function fails, the mutex priority ceiling shall not be changed.
.\" ----------------------------------------------------------------------------
+
.Sh RETURN VALUES
Upon success all described functions return zero.
Otherwise, an error number will be returned to indicate the error.
@@ -203,7 +249,45 @@ is invalid.
The current thread does not hold a lock on
.Fa mutex .
.El
+.Pp
+.\" -----
+.Fn pthread_mutex_timedlock
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The mutex was created with the protocol attribute having the value
+.Dv PTHREAD_PRIO_PROTECT
+and the calling thread's priority is higher than
+the mutex current priority ceiling.
+.It Bq Er EINVAL
+The process or thread would have blocked, and the
+.Fa timeout
+parameter specified a nanoseconds field value less than zero or greater
+than or equal to 1000 million.
+.It Bq Er ETIMEDOUT
+The mutex could not be locked before the specified timeout expired.
+.El
+.Pp
+.\" -----
+The
+.Fn pthread_mutex_getprioceiling
+and
+.Fn pthread_mutex_setprioceiling
+functions may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The priority requested by
+.Fa prioceiling
+is out of range.
+.It Bq Er EINVAL
+The value specified by
+.Fa mutex
+does not refer to a currently existing mutex.
+.It Bq Er EPERM
+The caller does not have the privilege to perform the operation.
+
.\" ----------------------------------------------------------------------------
+
.Sh SEE ALSO
.Xr pthread 3 ,
.Xr pthread_barrier 3 ,
Index: src/lib/libpthread/pthread_mutex.c
diff -u src/lib/libpthread/pthread_mutex.c:1.59 src/lib/libpthread/pthread_mutex.c:1.60
--- src/lib/libpthread/pthread_mutex.c:1.59 Mon Feb 3 10:51:01 2014
+++ src/lib/libpthread/pthread_mutex.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_mutex.c,v 1.59 2014/02/03 15:51:01 rmind Exp $ */
+/* $NetBSD: pthread_mutex.c,v 1.60 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2001, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -47,10 +47,11 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_mutex.c,v 1.59 2014/02/03 15:51:01 rmind Exp $");
+__RCSID("$NetBSD: pthread_mutex.c,v 1.60 2016/07/03 14:24:58 christos Exp $");
#include <sys/types.h>
#include <sys/lwpctl.h>
+#include <sys/sched.h>
#include <sys/lock.h>
#include <errno.h>
@@ -67,12 +68,27 @@ __RCSID("$NetBSD: pthread_mutex.c,v 1.59
#define MUTEX_WAITERS_BIT ((uintptr_t)0x01)
#define MUTEX_RECURSIVE_BIT ((uintptr_t)0x02)
#define MUTEX_DEFERRED_BIT ((uintptr_t)0x04)
-#define MUTEX_THREAD ((uintptr_t)-16L)
+#define MUTEX_PROTECT_BIT ((uintptr_t)0x08)
+#define MUTEX_THREAD ((uintptr_t)~0x0f)
#define MUTEX_HAS_WAITERS(x) ((uintptr_t)(x) & MUTEX_WAITERS_BIT)
#define MUTEX_RECURSIVE(x) ((uintptr_t)(x) & MUTEX_RECURSIVE_BIT)
+#define MUTEX_PROTECT(x) ((uintptr_t)(x) & MUTEX_PROTECT_BIT)
#define MUTEX_OWNER(x) ((uintptr_t)(x) & MUTEX_THREAD)
+#define MUTEX_GET_TYPE(x) \
+ ((int)(((uintptr_t)(x) & 0x000000ff) >> 0))
+#define MUTEX_SET_TYPE(x, t) \
+ (x) = (void *)(((uintptr_t)(x) & ~0x000000ff) | ((t) << 0))
+#define MUTEX_GET_PROTOCOL(x) \
+ ((int)(((uintptr_t)(x) & 0x0000ff00) >> 8))
+#define MUTEX_SET_PROTOCOL(x, p) \
+ (x) = (void *)(((uintptr_t)(x) & ~0x0000ff00) | ((p) << 8))
+#define MUTEX_GET_CEILING(x) \
+ ((int)(((uintptr_t)(x) & 0x00ff0000) >> 16))
+#define MUTEX_SET_CEILING(x, c) \
+ (x) = (void *)(((uintptr_t)(x) & ~0x00ff0000) | ((c) << 16))
+
#if __GNUC_PREREQ__(3, 0)
#define NOINLINE __attribute ((noinline))
#else
@@ -80,7 +96,8 @@ __RCSID("$NetBSD: pthread_mutex.c,v 1.59
#endif
static void pthread__mutex_wakeup(pthread_t, pthread_mutex_t *);
-static int pthread__mutex_lock_slow(pthread_mutex_t *);
+static int pthread__mutex_lock_slow(pthread_mutex_t *,
+ const struct timespec *);
static int pthread__mutex_unlock_slow(pthread_mutex_t *);
static void pthread__mutex_pause(void);
@@ -103,16 +120,22 @@ __strong_alias(__libc_mutexattr_settype,
int
pthread_mutex_init(pthread_mutex_t *ptm, const pthread_mutexattr_t *attr)
{
- intptr_t type;
+ uintptr_t type, proto, val, ceil;
if (__predict_false(__uselibcstub))
return __libc_mutex_init_stub(ptm, attr);
- if (attr == NULL)
+ if (attr == NULL) {
type = PTHREAD_MUTEX_NORMAL;
- else
- type = (intptr_t)attr->ptma_private;
+ proto = PTHREAD_PRIO_NONE;
+ ceil = 0;
+ } else {
+ val = (uintptr_t)attr->ptma_private;
+ type = MUTEX_GET_TYPE(val);
+ proto = MUTEX_GET_PROTOCOL(val);
+ ceil = MUTEX_GET_CEILING(val);
+ }
switch (type) {
case PTHREAD_MUTEX_ERRORCHECK:
__cpu_simple_lock_set(&ptm->ptm_errorcheck);
@@ -127,10 +150,18 @@ pthread_mutex_init(pthread_mutex_t *ptm,
ptm->ptm_owner = NULL;
break;
}
+ switch (proto) {
+ case PTHREAD_PRIO_PROTECT:
+ val = (uintptr_t)ptm->ptm_owner;
+ val |= MUTEX_PROTECT_BIT;
+ ptm->ptm_owner = (void *)val;
+ break;
+ }
ptm->ptm_magic = _PT_MUTEX_MAGIC;
ptm->ptm_waiters = NULL;
ptm->ptm_recursed = 0;
+ ptm->ptm_ceiling = (unsigned char)ceil;
return 0;
}
@@ -168,7 +199,24 @@ pthread_mutex_lock(pthread_mutex_t *ptm)
#endif
return 0;
}
- return pthread__mutex_lock_slow(ptm);
+ return pthread__mutex_lock_slow(ptm, NULL);
+}
+
+int
+pthread_mutex_timedlock(pthread_mutex_t* ptm, const struct timespec *ts)
+{
+ pthread_t self;
+ void *val;
+
+ self = pthread__self();
+ val = atomic_cas_ptr(&ptm->ptm_owner, NULL, self);
+ if (__predict_true(val == NULL)) {
+#ifndef PTHREAD__ATOMIC_IS_MEMBAR
+ membar_enter();
+#endif
+ return 0;
+ }
+ return pthread__mutex_lock_slow(ptm, ts);
}
/* We want function call overhead. */
@@ -258,11 +306,12 @@ again:
}
NOINLINE static int
-pthread__mutex_lock_slow(pthread_mutex_t *ptm)
+pthread__mutex_lock_slow(pthread_mutex_t *ptm, const struct timespec *ts)
{
void *waiters, *new, *owner, *next;
pthread_t self;
int serrno;
+ int error;
pthread__error(EINVAL, "Invalid mutex",
ptm->ptm_magic == _PT_MUTEX_MAGIC);
@@ -282,6 +331,10 @@ pthread__mutex_lock_slow(pthread_mutex_t
return EDEADLK;
}
+ /* priority protect */
+ if (MUTEX_PROTECT(owner) && _sched_protect(ptm->ptm_ceiling) == -1) {
+ return errno;
+ }
serrno = errno;
for (;; owner = ptm->ptm_owner) {
/* Spin while the owner is running. */
@@ -339,12 +392,23 @@ pthread__mutex_lock_slow(pthread_mutex_t
*/
while (self->pt_mutexwait) {
self->pt_blocking++;
- (void)_lwp_park(CLOCK_REALTIME, TIMER_ABSTIME, NULL,
+ error = _lwp_park(CLOCK_REALTIME, TIMER_ABSTIME, ts,
self->pt_unpark, __UNVOLATILE(&ptm->ptm_waiters),
__UNVOLATILE(&ptm->ptm_waiters));
self->pt_unpark = 0;
self->pt_blocking--;
membar_sync();
+ if (__predict_true(error != -1)) {
+ continue;
+ }
+ if (errno == ETIMEDOUT && self->pt_mutexwait) {
+ /*Remove self from waiters list*/
+ pthread__mutex_wakeup(self, ptm);
+ /*priority protect*/
+ if (MUTEX_PROTECT(owner))
+ (void)_sched_protect(-1);
+ return ETIMEDOUT;
+ }
}
}
}
@@ -460,6 +524,10 @@ pthread__mutex_unlock_slow(pthread_mutex
*/
if (new != owner) {
owner = atomic_swap_ptr(&ptm->ptm_owner, new);
+ if (__predict_false(MUTEX_PROTECT(owner))) {
+ /* restore elevated priority */
+ (void)_sched_protect(-1);
+ }
if (MUTEX_HAS_WAITERS(owner) != 0) {
pthread__mutex_wakeup(self, ptm);
return 0;
@@ -591,16 +659,18 @@ pthread_mutexattr_destroy(pthread_mutexa
int
pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *typep)
{
+
pthread__error(EINVAL, "Invalid mutex attribute",
attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
- *typep = (int)(intptr_t)attr->ptma_private;
+ *typep = MUTEX_GET_TYPE(attr->ptma_private);
return 0;
}
int
pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
{
+
if (__predict_false(__uselibcstub))
return __libc_mutexattr_settype_stub(attr, type);
@@ -611,13 +681,92 @@ pthread_mutexattr_settype(pthread_mutexa
case PTHREAD_MUTEX_NORMAL:
case PTHREAD_MUTEX_ERRORCHECK:
case PTHREAD_MUTEX_RECURSIVE:
- attr->ptma_private = (void *)(intptr_t)type;
+ MUTEX_SET_TYPE(attr->ptma_private, type);
+ return 0;
+ default:
+ return EINVAL;
+ }
+}
+
+int
+pthread_mutexattr_getprotocol(const pthread_mutexattr_t *attr, int*proto)
+{
+
+ pthread__error(EINVAL, "Invalid mutex attribute",
+ attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
+
+ *proto = MUTEX_GET_PROTOCOL(attr->ptma_private);
+ return 0;
+}
+
+int
+pthread_mutexattr_setprotocol(pthread_mutexattr_t* attr, int proto)
+{
+
+ pthread__error(EINVAL, "Invalid mutex attribute",
+ attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
+
+ switch (proto) {
+ case PTHREAD_PRIO_NONE:
+ case PTHREAD_PRIO_PROTECT:
+ MUTEX_SET_PROTOCOL(attr->ptma_private, proto);
return 0;
+ case PTHREAD_PRIO_INHERIT:
+ return ENOTSUP;
default:
return EINVAL;
}
}
+int
+pthread_mutexattr_getprioceiling(const pthread_mutexattr_t *attr, int *ceil)
+{
+
+ pthread__error(EINVAL, "Invalid mutex attribute",
+ attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
+
+ *ceil = MUTEX_GET_CEILING(attr->ptma_private);
+ return 0;
+}
+
+int
+pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int ceil)
+{
+
+ pthread__error(EINVAL, "Invalid mutex attribute",
+ attr->ptma_magic == _PT_MUTEXATTR_MAGIC);
+
+ if (ceil & ~0xff)
+ return EINVAL;
+
+ MUTEX_SET_CEILING(attr->ptma_private, ceil);
+ return 0;
+}
+
+#ifdef _PTHREAD_PSHARED
+int
+pthread_mutexattr_getpshared(const pthread_mutexattr_t * __restrict attr,
+ int * __restrict pshared)
+{
+
+ *pshared = PTHREAD_PROCESS_PRIVATE;
+ return 0;
+}
+
+int
+pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
+{
+
+ switch(pshared) {
+ case PTHREAD_PROCESS_PRIVATE:
+ return 0;
+ case PTHREAD_PROCESS_SHARED:
+ return ENOSYS;
+ }
+ return EINVAL;
+}
+#endif
+
/*
* pthread__mutex_deferwake: try to defer unparking threads in self->pt_waiters
*
@@ -645,6 +794,28 @@ pthread__mutex_deferwake(pthread_t self,
}
int
+pthread_mutex_getprioceiling(const pthread_mutex_t *ptm, int*ceil)
+{
+ *ceil = (unsigned int)ptm->ptm_ceiling;
+ return 0;
+}
+
+int
+pthread_mutex_setprioceiling(pthread_mutex_t *ptm, int ceil, int *old_ceil)
+{
+ int error;
+
+ error = pthread_mutex_lock(ptm);
+ if (error == 0) {
+ *old_ceil = (unsigned int)ptm->ptm_ceiling;
+ /*check range*/
+ ptm->ptm_ceiling = (unsigned char)ceil;
+ pthread_mutex_unlock(ptm);
+ }
+ return error;
+}
+
+int
_pthread_mutex_held_np(pthread_mutex_t *ptm)
{
Index: src/lib/libpthread/pthread_mutexattr.3
diff -u src/lib/libpthread/pthread_mutexattr.3:1.11 src/lib/libpthread/pthread_mutexattr.3:1.12
--- src/lib/libpthread/pthread_mutexattr.3:1.11 Thu Jul 8 18:46:34 2010
+++ src/lib/libpthread/pthread_mutexattr.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_mutexattr.3,v 1.11 2010/07/08 22:46:34 jruoho Exp $
+.\" $NetBSD: pthread_mutexattr.3,v 1.12 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 2002, 2010 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -50,18 +50,20 @@
.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
.\"
.\" $FreeBSD: src/lib/libpthread/man/pthread_mutexattr.3,v 1.8 2002/09/16 19:29:29 mini Exp $
-.Dd July 9, 2010
+.Dd June 12, 2016
.Dt PTHREAD_MUTEXATTR 3
.Os
.Sh NAME
.Nm pthread_mutexattr_init ,
.Nm pthread_mutexattr_destroy ,
-.\" .Nm pthread_mutexattr_setprioceiling ,
-.\" .Nm pthread_mutexattr_getprioceiling ,
-.\" .Nm pthread_mutexattr_setprotocol ,
-.\" .Nm pthread_mutexattr_getprotocol ,
+.Nm pthread_mutexattr_setprioceiling ,
+.Nm pthread_mutexattr_getprioceiling ,
+.Nm pthread_mutexattr_setprotocol ,
+.Nm pthread_mutexattr_getprotocol ,
.Nm pthread_mutexattr_settype ,
-.Nm pthread_mutexattr_gettype
+.Nm pthread_mutexattr_gettype ,
+.Nm pthread_mutexattr_getpshared ,
+.Nm pthread_mutexattr_setpshared
.Nd mutex attribute operations
.Sh LIBRARY
.Lb libpthread
@@ -71,23 +73,29 @@
.Fn pthread_mutexattr_init "pthread_mutexattr_t *attr"
.Ft int
.Fn pthread_mutexattr_destroy "pthread_mutexattr_t *attr"
-.\" .Ft int
-.\" .Fn pthread_mutexattr_setprioceiling \
-.\" "pthread_mutexattr_t *attr" "int prioceiling"
-.\" .Ft int
-.\" .Fn pthread_mutexattr_getprioceiling \
-.\" "pthread_mutexattr_t *attr" "int *prioceiling"
-.\" .Ft int
-.\" .Fn pthread_mutexattr_setprotocol \
-.\" "pthread_mutexattr_t *attr" "int protocol"
-.\" .Ft int
-.\" .Fn pthread_mutexattr_getprotocol \
-.\" "pthread_mutexattr_t *attr" "int *protocol"
+.Ft int
+.Fn pthread_mutexattr_setprioceiling \
+"pthread_mutexattr_t *attr" "int prioceiling"
+.Ft int
+.Fn pthread_mutexattr_getprioceiling \
+"pthread_mutexattr_t *attr" "int *prioceiling"
+.Ft int
+.Fn pthread_mutexattr_setprotocol \
+"pthread_mutexattr_t *attr" "int protocol"
+.Ft int
+.Fn pthread_mutexattr_getprotocol \
+"pthread_mutexattr_t *attr" "int *protocol"
.Ft int
.Fn pthread_mutexattr_settype "pthread_mutexattr_t *attr" "int type"
.Ft int
.Fn pthread_mutexattr_gettype \
"pthread_mutexattr_t * restrict attr" "int * restrict type"
+.Ft int
+.Fn pthread_mutexattr_getpshared \
+"const pthread_mutexattr_t * __restrict attr" "int * __restrict pshared"
+.Ft int
+.Fn pthread_mutexattr_setpshared \
+"pthread_mutexattr_t * attr" "int pshared"
.Sh DESCRIPTION
Mutex attributes are used to specify parameters to
.Fn pthread_mutex_init .
@@ -172,6 +180,38 @@ The
.Fn pthread_mutexattr_gettype
functions copy the type value of the attribute to the location
pointed to by the second parameter.
+.Pp
+The
+.Fn pthread_mutexattr_getpshared
+function obtains the value of the process-shared attribute from
+the attributes object referenced by
+.Fa attr.
+.Pp
+The
+.Fn pthread_mutexattr_setpshared
+function is used to set the process-shared attribute in an initialised
+attributes object referenced by
+.Fa attr.
+.Pp
+The
+.Fn pthread_mutexattr_getprotocol
+and
+.Fn pthread_mutexattr_setprotocol
+functions shall get and set the protocol attribute of a mutex attributes
+object pointed to by
+.Fa attr
+which was previously created by the function
+.Fn pthread_mutexattr_init .
+.Pp
+The
+.Fn pthread_mutexattr_getprioceiling
+and
+.Fn pthread_mutexattr_setprioceiling
+functions, shall get and set the priority ceiling attribute of a mutex attributes
+object pointed to by
+.Fa attr
+which was previously created by the function
+.Fn pthread_mutexattr_init .
.Sh RETURN VALUES
If successful, these functions return 0.
Otherwise, an error number is returned to indicate the error.
@@ -201,46 +241,63 @@ No error numbers are defined for the
and
.Fn pthread_mutexattr_gettype
functions.
-.\"
-.\" .Pp
-.\" .Fn pthread_mutexattr_setprioceiling
-.\" may fail if:
-.\" .Bl -tag -width Er
-.\" .It Bq Er EINVAL
-.\" Invalid value for
-.\" .Fa attr ,
-.\" or invalid value for
-.\" .Fa prioceiling .
-.\" .El
-.\" .Pp
-.\" .Fn pthread_mutexattr_getprioceiling
-.\" may fail if:
-.\" .Bl -tag -width Er
-.\" .It Bq Er EINVAL
-.\" Invalid value for
-.\" .Fa attr .
-.\" .El
-.\" .Pp
-.\" .Fn pthread_mutexattr_setprotocol
-.\" may fail if:
-.\" .Bl -tag -width Er
-.\" .It Bq Er EINVAL
-.\" Invalid value for
-.\" .Fa attr ,
-.\" or invalid value for
-.\" .Fa protocol .
-.\" .El
-.\" .Pp
-.\" .Fn pthread_mutexattr_getprotocol
-.\" may fail if:
-.\" .Bl -tag -width Er
-.\" .It Bq Er EINVAL
-.\" Invalid value for
-.\" .Fa attr .
-.\" .El
-.\" .Pp
+.Pp
+.Fn pthread_mutexattr_setprioceiling
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Invalid value for
+.Fa attr ,
+or invalid value for
+.Fa prioceiling .
+.El
+.Pp
+.Fn pthread_mutexattr_getprioceiling
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Invalid value for
+.Fa attr .
+.El
+.Pp
+.Fn pthread_mutexattr_setprotocol
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Invalid value for
+.Fa attr ,
+or invalid value for
+.Fa protocol .
+.El
+.Pp
+.Fn pthread_mutexattr_getprotocol
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+Invalid value for
+.Fa attr .
+.El
+.Pp
+.El
+.Pp
+.Fn pthread_mutexattr_getpshared
+and
+.Fn pthread_mutexattr_setpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+the value specified by
+.Fa attr
+is invalid.
.Sh SEE ALSO
.Xr pthread_mutex_init 3
.Sh STANDARDS
These functions conform to
.St -p1003.1-2001 .
+.Sh BUGS
+The
+.Fn pthread_mutexattr_getpshared
+and
+.Fn pthread_mutexattr_setpshared
+functions are hidden by default since only thread shared attributes
+are supported.
Index: src/lib/libpthread/pthread_rwlock.c
diff -u src/lib/libpthread/pthread_rwlock.c:1.33 src/lib/libpthread/pthread_rwlock.c:1.34
--- src/lib/libpthread/pthread_rwlock.c:1.33 Thu Mar 21 12:49:12 2013
+++ src/lib/libpthread/pthread_rwlock.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_rwlock.c,v 1.33 2013/03/21 16:49:12 christos Exp $ */
+/* $NetBSD: pthread_rwlock.c,v 1.34 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2002, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_rwlock.c,v 1.33 2013/03/21 16:49:12 christos Exp $");
+__RCSID("$NetBSD: pthread_rwlock.c,v 1.34 2016/07/03 14:24:58 christos Exp $");
#include <sys/types.h>
#include <sys/lwpctl.h>
@@ -639,6 +639,29 @@ _pthread_rwlock_wrheld_np(pthread_rwlock
((uintptr_t)pthread__self() | RW_WRITE_LOCKED);
}
+#ifdef _PTHREAD_PSHARED
+int
+pthread_rwlockattr_getpshared(const pthread_rwlockattr_t * __restrict attr,
+ int * __restrict pshared)
+{
+ *pshared = PTHREAD_PROCESS_PRIVATE;
+ return 0;
+}
+
+int
+pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
+{
+
+ switch(pshared) {
+ case PTHREAD_PROCESS_PRIVATE:
+ return 0;
+ case PTHREAD_PROCESS_SHARED:
+ return ENOSYS;
+ }
+ return EINVAL;
+}
+#endif
+
int
pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
{
Index: src/lib/libpthread/pthread_rwlockattr.3
diff -u src/lib/libpthread/pthread_rwlockattr.3:1.8 src/lib/libpthread/pthread_rwlockattr.3:1.9
--- src/lib/libpthread/pthread_rwlockattr.3:1.8 Fri Jul 9 04:51:28 2010
+++ src/lib/libpthread/pthread_rwlockattr.3 Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-.\" $NetBSD: pthread_rwlockattr.3,v 1.8 2010/07/09 08:51:28 jruoho Exp $
+.\" $NetBSD: pthread_rwlockattr.3,v 1.9 2016/07/03 14:24:58 christos Exp $
.\"
.\" Copyright (c) 2002 The NetBSD Foundation, Inc.
.\" All rights reserved.
@@ -48,13 +48,15 @@
.\"
.\" $FreeBSD: src/lib/libpthread/man/pthread_rwlockattr_init.3,v 1.7 2002/09/16 19:29:29 mini Exp $
.\"
-.Dd July 9, 2010
+.Dd June 12, 2016
.Dt PTHREAD_RWLOCKATTR 3
.Os
.Sh NAME
.Nm pthread_rwlockattr_init ,
-.Nm pthread_rwlockattr_destroy
-.Nd initialize or destroy read/write lock attributes
+.Nm pthread_rwlockattr_destroy ,
+.Nm pthread_rwlockattr_getpshared ,
+.Nm pthread_rwlockattr_setpshared
+.Nd initialize, destroy or query read/write lock attributes
.Sh LIBRARY
.Lb libpthread
.Sh SYNOPSIS
@@ -63,6 +65,10 @@
.Fn pthread_rwlockattr_init "pthread_rwlockattr_t *attr"
.Ft int
.Fn pthread_rwlockattr_destroy "pthread_rwlockattr_t *attr"
+.Ft int
+.Fn pthread_rwlockattr_getpshared "const pthread_rwlockattr_t *__restrict attr" "int * __restrict pshared"
+.Ft int
+.Fn pthread_rwlockattr_setpshared "pthread_rwlockattr_t *attr" "int pshared"
.Sh DESCRIPTION
The
.Fn pthread_rwlockattr_init
@@ -73,12 +79,21 @@ The
function is used to destroy a read/write lock attribute object
previously created with
.Fn pthread_rwlockattr_init .
+.Pp
+The
+.Fn pthread_rwlockattr_getpshared
+function shall obtain the value of process-shared attribute from
+the initialized attributes object referenced by
+.Fa attr.
+.Pp
+The
+.Fn pthread_rwlockattr_setpshared
+function shall set the process-shared attribute in an initialized
+attributes object referenced by
+.Fa attr.
.Sh RETURN VALUES
-If successful, the
-.Fn pthread_rwlockattr_init
-and
-.Fn pthread_rwlockattr_destroy
-functions return zero.
+If successful,
+all these functions return zero.
Otherwise an error number will be returned to indicate the error.
.Sh ERRORS
.Fn pthread_rwlockattr_init
@@ -98,8 +113,26 @@ The value specified by
.Fa attr
is invalid.
.El
+.Pp
+.Fn pthread_rwlockattr_getpshared
+and
+.Fn pthread_rwlockattr_setpshared
+may fail if:
+.Bl -tag -width Er
+.It Bq Er EINVAL
+The value specified by
+.Fa attr
+is invalid.
+.El
.Sh SEE ALSO
.Xr pthread_rwlock_init 3
.Sh STANDARDS
Both functions conform to
.St -p1003.1-2001 .
+.Sh BUGS
+The
+.Fn pthread_rwlockattr_getpshared
+and
+.Fn pthread_rwlockattr_setpshared
+functions are hidden by default since only thread shared attributes
+are supported.
Index: src/lib/libpthread/pthread_types.h
diff -u src/lib/libpthread/pthread_types.h:1.17 src/lib/libpthread/pthread_types.h:1.18
--- src/lib/libpthread/pthread_types.h:1.17 Thu Aug 27 08:30:50 2015
+++ src/lib/libpthread/pthread_types.h Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_types.h,v 1.17 2015/08/27 12:30:50 pooka Exp $ */
+/* $NetBSD: pthread_types.h,v 1.18 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2001, 2008 The NetBSD Foundation, Inc.
@@ -115,7 +115,7 @@ struct __pthread_mutex_st {
#ifdef __CPU_SIMPLE_LOCK_PAD
uint8_t ptm_pad1[3];
#endif
- __pthread_spin_t ptm_interlock; /* unused - backwards compat */
+ __pthread_spin_t ptm_ceiling;
#ifdef __CPU_SIMPLE_LOCK_PAD
uint8_t ptm_pad2[3];
#endif
Index: src/sys/kern/kern_lwp.c
diff -u src/sys/kern/kern_lwp.c:1.184 src/sys/kern/kern_lwp.c:1.185
--- src/sys/kern/kern_lwp.c:1.184 Mon Apr 4 19:07:06 2016
+++ src/sys/kern/kern_lwp.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_lwp.c,v 1.184 2016/04/04 23:07:06 christos Exp $ */
+/* $NetBSD: kern_lwp.c,v 1.185 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -211,7 +211,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.184 2016/04/04 23:07:06 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lwp.c,v 1.185 2016/07/03 14:24:58 christos Exp $");
#include "opt_ddb.h"
#include "opt_lockdebug.h"
@@ -829,6 +829,8 @@ lwp_create(lwp_t *l1, proc_t *p2, vaddr_
l2->l_kpribase = PRI_KERNEL;
l2->l_priority = l1->l_priority;
l2->l_inheritedprio = -1;
+ l2->l_protectprio = -1;
+ l2->l_auxprio = -1;
l2->l_flag = 0;
l2->l_pflag = LP_MPSAFE;
TAILQ_INIT(&l2->l_ld_locks);
Index: src/sys/kern/kern_sleepq.c
diff -u src/sys/kern/kern_sleepq.c:1.50 src/sys/kern/kern_sleepq.c:1.51
--- src/sys/kern/kern_sleepq.c:1.50 Fri Sep 5 01:57:21 2014
+++ src/sys/kern/kern_sleepq.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_sleepq.c,v 1.50 2014/09/05 05:57:21 matt Exp $ */
+/* $NetBSD: kern_sleepq.c,v 1.51 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 2006, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -35,7 +35,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.50 2014/09/05 05:57:21 matt Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_sleepq.c,v 1.51 2016/07/03 14:24:58 christos Exp $");
#include <sys/param.h>
#include <sys/kernel.h>
@@ -479,5 +479,6 @@ sleepq_lendpri(lwp_t *l, pri_t pri)
KASSERT(lwp_locked(l, NULL));
l->l_inheritedprio = pri;
+ l->l_auxprio = MAX(l->l_inheritedprio, l->l_protectprio);
sleepq_reinsert(sq, l);
}
Index: src/sys/kern/kern_synch.c
diff -u src/sys/kern/kern_synch.c:1.310 src/sys/kern/kern_synch.c:1.311
--- src/sys/kern/kern_synch.c:1.310 Mon Apr 4 16:47:57 2016
+++ src/sys/kern/kern_synch.c Sun Jul 3 10:24:58 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_synch.c,v 1.310 2016/04/04 20:47:57 christos Exp $ */
+/* $NetBSD: kern_synch.c,v 1.311 2016/07/03 14:24:58 christos Exp $ */
/*-
* Copyright (c) 1999, 2000, 2004, 2006, 2007, 2008, 2009
@@ -69,7 +69,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.310 2016/04/04 20:47:57 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_synch.c,v 1.311 2016/07/03 14:24:58 christos Exp $");
#include "opt_kstack.h"
#include "opt_perfctrs.h"
@@ -1085,9 +1085,11 @@ sched_lendpri(struct lwp *l, pri_t pri)
KASSERT(lwp_locked(l, l->l_cpu->ci_schedstate.spc_mutex));
sched_dequeue(l);
l->l_inheritedprio = pri;
+ l->l_auxprio = MAX(l->l_inheritedprio, l->l_protectprio);
sched_enqueue(l, false);
} else {
l->l_inheritedprio = pri;
+ l->l_auxprio = MAX(l->l_inheritedprio, l->l_protectprio);
}
resched_cpu(l);
}
Index: src/sys/kern/sys_sched.c
diff -u src/sys/kern/sys_sched.c:1.43 src/sys/kern/sys_sched.c:1.44
--- src/sys/kern/sys_sched.c:1.43 Tue Feb 25 13:30:11 2014
+++ src/sys/kern/sys_sched.c Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: sys_sched.c,v 1.43 2014/02/25 18:30:11 pooka Exp $ */
+/* $NetBSD: sys_sched.c,v 1.44 2016/07/03 14:24:59 christos Exp $ */
/*
* Copyright (c) 2008, 2011 Mindaugas Rasiukevicius <rmind at NetBSD org>
@@ -42,7 +42,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.43 2014/02/25 18:30:11 pooka Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sys_sched.c,v 1.44 2016/07/03 14:24:59 christos Exp $");
#include <sys/param.h>
@@ -532,6 +532,68 @@ out:
}
/*
+ * Priority protection for PTHREAD_PRIO_PROTECT. This is a weak
+ * analogue of priority inheritance: temp raise the priority
+ * of the caller when accessing a protected resource.
+ */
+int
+sys__sched_protect(struct lwp *l,
+ const struct sys__sched_protect_args *uap, register_t *retval)
+{
+ /* {
+ syscallarg(int) priority;
+ syscallarg(int *) opriority;
+ } */
+ int error;
+ pri_t pri;
+
+ KASSERT(l->l_inheritedprio == -1);
+ KASSERT(l->l_auxprio == -1 || l->l_auxprio == l->l_protectprio);
+
+ pri = SCARG(uap, priority);
+ error = 0;
+ lwp_lock(l);
+ if (pri == -1) {
+ /* back out priority changes */
+ switch(l->l_protectdepth) {
+ case 0:
+ error = EINVAL;
+ break;
+ case 1:
+ l->l_protectdepth = 0;
+ l->l_protectprio = -1;
+ l->l_auxprio = -1;
+ break;
+ default:
+ l->l_protectdepth--;
+ break;
+ }
+ } else if (pri < 0) {
+ /* Just retrieve the current value, for debugging */
+ if (l->l_protectprio != -1)
+ error = ENOENT;
+ else
+ *retval = l->l_protectprio - PRI_USER_RT;
+ } else if (__predict_false(pri < SCHED_PRI_MIN ||
+ pri > SCHED_PRI_MAX || l->l_priority > pri + PRI_USER_RT)) {
+ /* must fail if existing priority is higher */
+ error = EPERM;
+ } else {
+ /* play along but make no changes if not a realtime LWP. */
+ l->l_protectdepth++;
+ pri += PRI_USER_RT;
+ if (__predict_true(l->l_class != SCHED_OTHER &&
+ pri > l->l_protectprio)) {
+ l->l_protectprio = pri;
+ l->l_auxprio = pri;
+ }
+ }
+ lwp_unlock(l);
+
+ return error;
+}
+
+/*
* Yield.
*/
int
Index: src/sys/kern/syscalls.master
diff -u src/sys/kern/syscalls.master:1.284 src/sys/kern/syscalls.master:1.285
--- src/sys/kern/syscalls.master:1.284 Sat Apr 23 19:08:26 2016
+++ src/sys/kern/syscalls.master Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
- $NetBSD: syscalls.master,v 1.284 2016/04/23 23:08:26 christos Exp $
+ $NetBSD: syscalls.master,v 1.285 2016/07/03 14:24:59 christos Exp $
; @(#)syscalls.master 8.2 (Berkeley) 1/13/94
@@ -692,7 +692,7 @@
349 STD { int|sys||_sched_getaffinity(pid_t pid, lwpid_t lid, \
size_t size, cpuset_t *cpuset); }
350 STD { int|sys||sched_yield(void); }
-351 UNIMPL
+351 STD { int|sys||_sched_protect(int priority); }
352 UNIMPL
353 UNIMPL
Index: src/sys/sys/lwp.h
diff -u src/sys/sys/lwp.h:1.171 src/sys/sys/lwp.h:1.172
--- src/sys/sys/lwp.h:1.171 Wed Jun 15 22:34:33 2016
+++ src/sys/sys/lwp.h Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: lwp.h,v 1.171 2016/06/16 02:34:33 ozaki-r Exp $ */
+/* $NetBSD: lwp.h,v 1.172 2016/07/03 14:24:59 christos Exp $ */
/*-
* Copyright (c) 2001, 2006, 2007, 2008, 2009, 2010
@@ -105,6 +105,9 @@ struct lwp {
pri_t l_kpribase; /* !: kernel priority base level */
pri_t l_priority; /* l: scheduler priority */
pri_t l_inheritedprio;/* l: inherited priority */
+ pri_t l_protectprio; /* l: for PTHREAD_PRIO_PROTECT */
+ pri_t l_auxprio; /* l: max(inherit,protect) priority */
+ int l_protectdepth; /* l: for PTHREAD_PRIO_PROTECT */
SLIST_HEAD(, turnstile) l_pi_lenders; /* l: ts lending us priority */
uint64_t l_ncsw; /* l: total context switches */
uint64_t l_nivcsw; /* l: involuntary context switches */
@@ -403,9 +406,6 @@ lwp_lendpri(lwp_t *l, pri_t pri)
{
KASSERT(mutex_owned(l->l_mutex));
- if (l->l_inheritedprio == pri)
- return;
-
(*l->l_syncobj->sobj_lendpri)(l, pri);
KASSERT(l->l_inheritedprio == pri);
}
@@ -418,7 +418,7 @@ lwp_eprio(lwp_t *l)
pri = l->l_priority;
if ((l->l_flag & LW_SYSTEM) == 0 && l->l_kpriority && pri < PRI_KERNEL)
pri = (pri >> 1) + l->l_kpribase;
- return MAX(l->l_inheritedprio, pri);
+ return MAX(l->l_auxprio, pri);
}
int lwp_create(lwp_t *, struct proc *, vaddr_t, int,
Index: src/sys/sys/sched.h
diff -u src/sys/sys/sched.h:1.75 src/sys/sys/sched.h:1.76
--- src/sys/sys/sched.h:1.75 Sun Nov 20 23:36:05 2011
+++ src/sys/sys/sched.h Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: sched.h,v 1.75 2011/11/21 04:36:05 christos Exp $ */
+/* $NetBSD: sched.h,v 1.76 2016/07/03 14:24:59 christos Exp $ */
/*-
* Copyright (c) 1999, 2000, 2001, 2002, 2007, 2008 The NetBSD Foundation, Inc.
@@ -124,6 +124,7 @@ int _sched_getaffinity(pid_t, lwpid_t, s
int _sched_setaffinity(pid_t, lwpid_t, size_t, const cpuset_t *);
int _sched_getparam(pid_t, lwpid_t, int *, struct sched_param *);
int _sched_setparam(pid_t, lwpid_t, int, const struct sched_param *);
+int _sched_protect(int);
__END_DECLS
/*
Index: src/sys/sys/unistd.h
diff -u src/sys/sys/unistd.h:1.58 src/sys/sys/unistd.h:1.59
--- src/sys/sys/unistd.h:1.58 Fri Jun 10 19:29:20 2016
+++ src/sys/sys/unistd.h Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: unistd.h,v 1.58 2016/06/10 23:29:20 christos Exp $ */
+/* $NetBSD: unistd.h,v 1.59 2016/07/03 14:24:59 christos Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -146,6 +146,8 @@
/* pthread_attr for stack address */
#define _POSIX_THREAD_ATTR_STACKADDR 200112L
/* _r functions */
+#define _POSIX_THREAD_PRIO_PROTECT 200112L
+ /* PTHREAD_PRIO_PROTECT */
#define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
/* timeouts */
#undef _POSIX_TIMEOUTS
Index: src/tests/lib/libpthread/t_cond.c
diff -u src/tests/lib/libpthread/t_cond.c:1.6 src/tests/lib/libpthread/t_cond.c:1.7
--- src/tests/lib/libpthread/t_cond.c:1.6 Wed Sep 3 12:23:24 2014
+++ src/tests/lib/libpthread/t_cond.c Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: t_cond.c,v 1.6 2014/09/03 16:23:24 gson Exp $ */
+/* $NetBSD: t_cond.c,v 1.7 2016/07/03 14:24:59 christos Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -29,7 +29,7 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_cond.c,v 1.6 2014/09/03 16:23:24 gson Exp $");
+__RCSID("$NetBSD: t_cond.c,v 1.7 2016/07/03 14:24:59 christos Exp $");
#include <sys/time.h>
@@ -547,6 +547,26 @@ ATF_TC_BODY(destroy_after_cancel, tc)
PTHREAD_REQUIRE(pthread_mutex_destroy(&mutex));
}
+ATF_TC(condattr);
+ATF_TC_HEAD(condattr, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks Condattr");
+}
+ATF_TC_BODY(condattr, tc)
+{
+ pthread_condattr_t condattr;
+ clockid_t clockid;
+
+ PTHREAD_REQUIRE(pthread_condattr_init(&condattr));
+ PTHREAD_REQUIRE(pthread_condattr_setclock(&condattr, CLOCK_REALTIME));
+ PTHREAD_REQUIRE(pthread_condattr_getclock(&condattr, &clockid));
+ ATF_REQUIRE_EQ(clockid, CLOCK_REALTIME);
+
+ PTHREAD_REQUIRE(pthread_condattr_setclock(&condattr, CLOCK_MONOTONIC));
+ PTHREAD_REQUIRE(pthread_condattr_getclock(&condattr, &clockid));
+ ATF_REQUIRE_EQ(clockid, CLOCK_MONOTONIC);
+}
+
ATF_TP_ADD_TCS(tp)
{
@@ -558,6 +578,7 @@ ATF_TP_ADD_TCS(tp)
ATF_TP_ADD_TC(tp, broadcast);
ATF_TP_ADD_TC(tp, bogus_timedwaits);
ATF_TP_ADD_TC(tp, destroy_after_cancel);
+ ATF_TP_ADD_TC(tp, condattr);
return atf_no_error();
}
Index: src/tests/lib/libpthread/t_mutex.c
diff -u src/tests/lib/libpthread/t_mutex.c:1.7 src/tests/lib/libpthread/t_mutex.c:1.8
--- src/tests/lib/libpthread/t_mutex.c:1.7 Mon Nov 3 19:20:19 2014
+++ src/tests/lib/libpthread/t_mutex.c Sun Jul 3 10:24:59 2016
@@ -1,4 +1,4 @@
-/* $NetBSD: t_mutex.c,v 1.7 2014/11/04 00:20:19 justin Exp $ */
+/* $NetBSD: t_mutex.c,v 1.8 2016/07/03 14:24:59 christos Exp $ */
/*
* Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -29,12 +29,15 @@
#include <sys/cdefs.h>
__COPYRIGHT("@(#) Copyright (c) 2008\
The NetBSD Foundation, inc. All rights reserved.");
-__RCSID("$NetBSD: t_mutex.c,v 1.7 2014/11/04 00:20:19 justin Exp $");
+__RCSID("$NetBSD: t_mutex.c,v 1.8 2016/07/03 14:24:59 christos Exp $");
#include <pthread.h>
#include <stdio.h>
#include <string.h>
+#include <errno.h>
#include <unistd.h>
+#include <sys/sched.h>
+#include <sys/param.h>
#include <atf-c.h>
@@ -304,12 +307,255 @@ ATF_TC_BODY(mutex4, tc)
PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex));
}
+static pthread_mutexattr_t attr5;
+static pthread_mutex_t mutex5;
+static int min_fifo_prio, max_fifo_prio;
+
+static void *
+child_func(void* arg)
+{
+ int res;
+
+ printf("child is waiting\n");
+ res = _sched_protect(-2);
+ ATF_REQUIRE_EQ(res, -1);
+ ATF_REQUIRE_EQ(errno, ENOENT);
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex5));
+ printf("child is owning resource\n");
+ res = _sched_protect(-2);
+ ATF_REQUIRE_EQ(res, max_fifo_prio);
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex5));
+ printf("child is done\n");
+
+ return 0;
+}
+
+ATF_TC(mutex5);
+ATF_TC_HEAD(mutex5, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexes for priority setting");
+}
+
+ATF_TC_BODY(mutex5, tc)
+{
+ int res;
+ struct sched_param param;
+ pthread_t child;
+
+ min_fifo_prio = sched_get_priority_min(SCHED_FIFO);
+ max_fifo_prio = sched_get_priority_max(SCHED_FIFO);
+ printf("min prio for FIFO = %d\n", min_fifo_prio);
+ param.sched_priority = min_fifo_prio;
+ /* = 0 OTHER, 1 FIFO, 2 RR, -1 NONE */
+ res = sched_setscheduler(getpid(), SCHED_FIFO, ¶m);
+ printf("previous policy used = %d\n", res);
+
+ res = sched_getscheduler(getpid());
+ ATF_REQUIRE_EQ(res, 1);
+
+ PTHREAD_REQUIRE(pthread_mutexattr_init(&attr5));
+ PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&attr5,
+ PTHREAD_PRIO_PROTECT));
+ PTHREAD_REQUIRE(pthread_mutexattr_setprioceiling(&attr5,
+ max_fifo_prio));
+
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex5, &attr5));
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex5));
+ printf("enter critical section for main\n");
+ PTHREAD_REQUIRE(pthread_create(&child, NULL, child_func, NULL));
+ printf("main starts to sleep\n");
+ sleep(10);
+ printf("main completes\n");
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex5));
+ PTHREAD_REQUIRE(pthread_join(child, NULL));
+}
+
+static pthread_mutex_t mutex6;
+static int start = 0;
+static uintmax_t high_cnt = 0, low_cnt = 0, MAX_LOOP = 100000000;
+
+static void *
+high_prio(void* arg)
+{
+ struct sched_param param;
+ int policy;
+ param.sched_priority = min_fifo_prio + 10;
+ pthread_t childid = pthread_self();
+
+ PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, ¶m));
+ PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, ¶m));
+ printf("high protect = %d, prio = %d\n",
+ _sched_protect(-2), param.sched_priority);
+ ATF_REQUIRE_EQ(policy, 1);
+ printf("high prio = %d\n", param.sched_priority);
+ sleep(1);
+ int i;
+ long tmp = 0;
+ for (i = 0; i<20; i++) {
+ while (high_cnt < MAX_LOOP) {
+ tmp += (123456789 % 1234) * (987654321 % 54321);
+ high_cnt += 1;
+ }
+ high_cnt = 0;
+ sleep(1);
+ }
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex6));
+ if (start == 0) start = 2;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6));
+
+ return 0;
+}
+
+static void *
+low_prio(void* arg)
+{
+ struct sched_param param;
+ int policy;
+ param.sched_priority = min_fifo_prio;
+ pthread_t childid = pthread_self();
+ int res = _sched_protect(max_fifo_prio);
+ ATF_REQUIRE_EQ(res, 0);
+ PTHREAD_REQUIRE(pthread_setschedparam(childid, 1, ¶m));
+ PTHREAD_REQUIRE(pthread_getschedparam(childid, &policy, ¶m));
+ printf("low protect = %d, prio = %d\n", _sched_protect(-2),
+ param.sched_priority);
+ ATF_REQUIRE_EQ(policy, 1);
+ printf("low prio = %d\n", param.sched_priority);
+ sleep(1);
+ for (int i = 0; i < 20; i++) {
+ while (low_cnt < MAX_LOOP) {
+ long tmp;
+ tmp += (123456789 % 1234) * (987654321 % 54321);
+ low_cnt += 1;
+ }
+ low_cnt = 0;
+ sleep(1);
+ }
+ PTHREAD_REQUIRE(pthread_mutex_lock(&mutex6));
+ if (start == 0)
+ start = 1;
+ PTHREAD_REQUIRE(pthread_mutex_unlock(&mutex6));
+
+ return 0;
+}
+
+ATF_TC(mutex6);
+ATF_TC_HEAD(mutex6, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Checks scheduling for priority ceiling");
+}
+
+/*
+ * 1. main thread sets itself to be a realtime task and launched two tasks,
+ * one has higher priority and the other has lower priority.
+ * 2. each child thread(low and high priority thread) sets its scheduler and
+ * priority.
+ * 3. each child thread did several rounds of computation, after each round it
+ * sleep 1 second.
+ * 4. the child thread with low priority will call _sched_protect to increase
+ * its protect priority.
+ * 5. We verify the thread with low priority runs first.
+ *
+ * Why does it work? From the main thread, we launched the high
+ * priority thread first. This gives this thread the benefit of
+ * starting first. The low priority thread did not call _sched_protect(2).
+ * The high priority thread should finish the task first. After each
+ * round of computation, we call sleep, to put the task into the
+ * sleep queue, and wake up again after the timer expires. This
+ * gives the scheduler the chance to decide which task to run. So,
+ * the thread with real high priority will always block the thread
+ * with real low priority.
+ *
+ */
+ATF_TC_BODY(mutex6, tc)
+{
+ int res;
+ pthread_t high, low;
+ min_fifo_prio = sched_get_priority_min(SCHED_FIFO);
+ max_fifo_prio = sched_get_priority_max(SCHED_FIFO);
+ PTHREAD_REQUIRE(pthread_mutex_init(&mutex, NULL));
+ printf("min_fifo_prio = %d, max_fifo_info = %d\n", min_fifo_prio,
+ max_fifo_prio);
+ struct sched_param param;
+ param.sched_priority = min_fifo_prio;
+ res = sched_setscheduler(getpid(), SCHED_FIFO, ¶m);
+ printf("previous policy used = %d\n", res);
+
+ res = sched_getscheduler(getpid());
+ ATF_REQUIRE_EQ(res, 1);
+ PTHREAD_REQUIRE(pthread_create(&high, NULL, high_prio, NULL));
+ PTHREAD_REQUIRE(pthread_create(&low, NULL, low_prio, NULL));
+ sleep(5);
+ PTHREAD_REQUIRE(pthread_join(low, NULL));
+ PTHREAD_REQUIRE(pthread_join(high, NULL));
+
+ ATF_REQUIRE_EQ(start, 1);
+}
+
+ATF_TC(mutexattr1);
+ATF_TC_HEAD(mutexattr1, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexattr");
+}
+
+ATF_TC_BODY(mutexattr1, tc)
+{
+ pthread_mutexattr_t mattr;
+ int protocol, target;
+
+ PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
+
+ target = PTHREAD_PRIO_NONE;
+ PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target));
+ PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol));
+ ATF_REQUIRE_EQ(protocol, target);
+
+ /*
+ target = PTHREAD_PRIO_INHERIT;
+ PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target));
+ PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol));
+ ATF_REQUIRE_EQ(protocol, target);
+ */
+
+ target = PTHREAD_PRIO_PROTECT;
+ PTHREAD_REQUIRE(pthread_mutexattr_setprotocol(&mattr, target));
+ PTHREAD_REQUIRE(pthread_mutexattr_getprotocol(&mattr, &protocol));
+ ATF_REQUIRE_EQ(protocol, target);
+}
+
+ATF_TC(mutexattr2);
+ATF_TC_HEAD(mutexattr2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Checks mutexattr");
+}
+
+ATF_TC_BODY(mutexattr2, tc)
+{
+ pthread_mutexattr_t mattr;
+
+ PTHREAD_REQUIRE(pthread_mutexattr_init(&mattr));
+ int max_prio = sched_get_priority_max(SCHED_FIFO);
+ int min_prio = sched_get_priority_min(SCHED_FIFO);
+ for (int i = min_prio; i <= max_prio; i++) {
+ int prioceiling;
+ PTHREAD_REQUIRE(pthread_mutexattr_setprioceiling(&mattr, i));
+ PTHREAD_REQUIRE(pthread_mutexattr_getprioceiling(&mattr,
+ &prioceiling));
+ ATF_REQUIRE_EQ(i, prioceiling);
+ }
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, mutex1);
ATF_TP_ADD_TC(tp, mutex2);
ATF_TP_ADD_TC(tp, mutex3);
ATF_TP_ADD_TC(tp, mutex4);
-
+ ATF_TP_ADD_TC(tp, mutex5);
+ ATF_TP_ADD_TC(tp, mutex6);
+ ATF_TP_ADD_TC(tp, mutexattr1);
+ ATF_TP_ADD_TC(tp, mutexattr2);
+
return atf_no_error();
}