Module Name: src Committed By: ad Date: Sat Feb 22 21:24:45 UTC 2020
Modified Files: src/distrib/sets/lists/comp: mi src/share/man/man9: rwlock.9 src/sys/kern: kern_rwlock.c src/sys/sys: rwlock.h Log Message: Add rw_lock_op(): return either RW_READER or RW_WRITER for a lock that is known to be held by the caller. Panic if the lock is not held. To generate a diff of this commit: cvs rdiff -u -r1.2310 -r1.2311 src/distrib/sets/lists/comp/mi cvs rdiff -u -r1.19 -r1.20 src/share/man/man9/rwlock.9 cvs rdiff -u -r1.64 -r1.65 src/sys/kern/kern_rwlock.c cvs rdiff -u -r1.15 -r1.16 src/sys/sys/rwlock.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/distrib/sets/lists/comp/mi diff -u src/distrib/sets/lists/comp/mi:1.2310 src/distrib/sets/lists/comp/mi:1.2311 --- src/distrib/sets/lists/comp/mi:1.2310 Fri Feb 7 18:48:58 2020 +++ src/distrib/sets/lists/comp/mi Sat Feb 22 21:24:44 2020 @@ -1,4 +1,4 @@ -# $NetBSD: mi,v 1.2310 2020/02/07 18:48:58 kamil Exp $ +# $NetBSD: mi,v 1.2311 2020/02/22 21:24:44 ad Exp $ # # Note: don't delete entries from here - mark them as "obsolete" instead. ./etc/mtree/set.comp comp-sys-root @@ -11792,6 +11792,7 @@ ./usr/share/man/cat9/rw_exit.0 comp-sys-catman .cat ./usr/share/man/cat9/rw_init.0 comp-sys-catman .cat ./usr/share/man/cat9/rw_lock_held.0 comp-sys-catman .cat +./usr/share/man/cat9/rw_lock_op.0 comp-sys-catman .cat ./usr/share/man/cat9/rw_read_held.0 comp-sys-catman .cat ./usr/share/man/cat9/rw_tryenter.0 comp-sys-catman .cat ./usr/share/man/cat9/rw_tryupgrade.0 comp-sys-catman .cat @@ -19710,6 +19711,7 @@ ./usr/share/man/html9/rw_exit.html comp-sys-htmlman html ./usr/share/man/html9/rw_init.html comp-sys-htmlman html ./usr/share/man/html9/rw_lock_held.html comp-sys-htmlman html +./usr/share/man/html9/rw_lock_op.html comp-sys-htmlman html ./usr/share/man/html9/rw_read_held.html comp-sys-htmlman html ./usr/share/man/html9/rw_tryenter.html comp-sys-htmlman html ./usr/share/man/html9/rw_tryupgrade.html comp-sys-htmlman html @@ -27811,6 +27813,7 @@ ./usr/share/man/man9/rw_exit.9 comp-sys-man .man ./usr/share/man/man9/rw_init.9 comp-sys-man .man ./usr/share/man/man9/rw_lock_held.9 comp-sys-man .man +./usr/share/man/man9/rw_lock_op.9 comp-sys-man .man ./usr/share/man/man9/rw_read_held.9 comp-sys-man .man ./usr/share/man/man9/rw_tryenter.9 comp-sys-man .man ./usr/share/man/man9/rw_tryupgrade.9 comp-sys-man .man Index: src/share/man/man9/rwlock.9 diff -u src/share/man/man9/rwlock.9:1.19 src/share/man/man9/rwlock.9:1.20 --- src/share/man/man9/rwlock.9:1.19 Mon Dec 10 20:12:36 2018 +++ src/share/man/man9/rwlock.9 Sat Feb 22 21:24:45 2020 @@ -1,6 +1,6 @@ -.\" $NetBSD: rwlock.9,v 1.19 2018/12/10 20:12:36 jdolecek Exp $ +.\" $NetBSD: rwlock.9,v 1.20 2020/02/22 21:24:45 ad Exp $ .\" -.\" Copyright (c) 2006, 2007, 2009 The NetBSD Foundation, Inc. +.\" Copyright (c) 2006, 2007, 2009, 2020 The NetBSD Foundation, Inc. .\" All rights reserved. .\" .\" This code is derived from software contributed to The NetBSD Foundation @@ -27,7 +27,7 @@ .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" POSSIBILITY OF SUCH DAMAGE. .\" -.Dd December 10, 2018 +.Dd February 22, 2020 .Dt RWLOCK 9 .Os .Sh NAME @@ -41,7 +41,8 @@ .Nm rw_downgrade , .Nm rw_read_held , .Nm rw_write_held , -.Nm rw_lock_held +.Nm rw_lock_held , +.Nm rw_lock_op .Nd reader / writer lock primitives .Sh SYNOPSIS .In sys/rwlock.h @@ -65,6 +66,8 @@ .Fn rw_write_held "krwlock_t *rw" .Ft int .Fn rw_lock_held "krwlock_t *rw" +.Ft krw_t +.Fn rw_lock_op "krwlock_t *rw" .Pp .Cd "options DIAGNOSTIC" .Cd "options LOCKDEBUG" @@ -130,8 +133,7 @@ If is specified as the argument to .Fa op , acquire a read lock. -If the lock is write held, the caller will block and not return until the -hold is acquired. +The caller may block and will not return until the hold is acquired. Callers must not recursively acquire read locks. .Pp If @@ -172,6 +174,7 @@ Downgrade a lock from a write hold to a Return non-zero if write lock is held by current lwp. Otherwise, return zero. .It Fn rw_read_held "rw" +.Pp Returns non-zero if read lock is held by any lwp. Otherwise, return zero. .It Fn rw_lock_held "rw" @@ -179,19 +182,28 @@ Otherwise, return zero. Returns non-zero if either read or write lock is held by any lwp. Otherwise, return zero. .Pp -Functions .Fn rw_write_held , .Fn rw_read_held , and .Fn rw_lock_held -must never be used to make locking decisions at run time: -they are provided only for diagnostic purposes. -They are also not atomic, hence they should only be used to assert -that lock is held. -The only exception is +should not generally be used to make locking decisions at run time: +they are provided for diagnostic purposes, for example making +assertions. +.Pp +Negative assertions (lock not held) should not be made due to atomicity +issues, excepting .Fn rw_write_held , -which can be also used safely to assert that write lock is NOT currently -held by current lwp. +which can safely be used to assert that a write lock is NOT held by +the current LWP. +.It Fn rw_lock_op "rw" +.Pp +For a lock that is known to be held by the calling LWP, return either +.Dv RW_READER +or +.Dv RW_WRITER +to denote the type of hold. +This is useful when dropping and later re-acquiring a lock, if the type +of hold is not already known. .El .Sh PERFORMANCE CONSIDERATIONS RW locks are subject to high cache contention on multiprocessor systems, Index: src/sys/kern/kern_rwlock.c diff -u src/sys/kern/kern_rwlock.c:1.64 src/sys/kern/kern_rwlock.c:1.65 --- src/sys/kern/kern_rwlock.c:1.64 Wed Jan 22 12:44:54 2020 +++ src/sys/kern/kern_rwlock.c Sat Feb 22 21:24:45 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_rwlock.c,v 1.64 2020/01/22 12:44:54 ad Exp $ */ +/* $NetBSD: kern_rwlock.c,v 1.65 2020/02/22 21:24:45 ad Exp $ */ /*- * Copyright (c) 2002, 2006, 2007, 2008, 2009, 2019, 2020 @@ -45,7 +45,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.64 2020/01/22 12:44:54 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_rwlock.c,v 1.65 2020/02/22 21:24:45 ad Exp $"); #include "opt_lockdebug.h" @@ -782,6 +782,21 @@ rw_lock_held(krwlock_t *rw) } /* + * rw_lock_op: + * + * For a rwlock that is known to be held by the caller, return + * RW_READER or RW_WRITER to describe the hold type. + */ +krw_t +rw_lock_op(krwlock_t *rw) +{ + + RW_ASSERT(rw, rw_lock_held(rw)); + + return (rw->rw_owner & RW_WRITE_LOCKED) != 0 ? RW_WRITER : RW_READER; +} + +/* * rw_owner: * * Return the current owner of an RW lock, but only if it is write Index: src/sys/sys/rwlock.h diff -u src/sys/sys/rwlock.h:1.15 src/sys/sys/rwlock.h:1.16 --- src/sys/sys/rwlock.h:1.15 Tue Jan 21 20:29:51 2020 +++ src/sys/sys/rwlock.h Sat Feb 22 21:24:45 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: rwlock.h,v 1.15 2020/01/21 20:29:51 ad Exp $ */ +/* $NetBSD: rwlock.h,v 1.16 2020/02/22 21:24:45 ad Exp $ */ /*- * Copyright (c) 2002, 2006, 2007, 2008, 2019, 2020 The NetBSD Foundation, Inc. @@ -103,6 +103,7 @@ void rw_downgrade(krwlock_t *); int rw_read_held(krwlock_t *); int rw_write_held(krwlock_t *); int rw_lock_held(krwlock_t *); +krw_t rw_lock_op(krwlock_t *); void rw_enter(krwlock_t *, const krw_t); void rw_exit(krwlock_t *);