1.\" $NetBSD: rwlock.9,v 1.14 2009/11/22 18:40:26 mbalmer Exp $ 2.\" 3.\" Copyright (c) 2006, 2007, 2009 The NetBSD Foundation, Inc. 4.\" All rights reserved. 5.\" 6.\" This code is derived from software contributed to The NetBSD Foundation 7.\" by Andrew Doran. 8.\" 9.\" Redistribution and use in source and binary forms, with or without 10.\" modification, are permitted provided that the following conditions 11.\" are met: 12.\" 1. Redistributions of source code must retain the above copyright 13.\" notice, this list of conditions and the following disclaimer. 14.\" 2. Redistributions in binary form must reproduce the above copyright 15.\" notice, this list of conditions and the following disclaimer in the 16.\" documentation and/or other materials provided with the distribution. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28.\" POSSIBILITY OF SUCH DAMAGE. 29.\" 30.Dd November 22, 2009 31.Dt RWLOCK 9 32.Os 33.Sh NAME 34.Nm rw , 35.Nm rw_init , 36.Nm rw_destroy , 37.Nm rw_enter , 38.Nm rw_exit , 39.Nm rw_tryenter , 40.Nm rw_tryupgrade , 41.Nm rw_downgrade , 42.Nm rw_read_held , 43.Nm rw_write_held , 44.Nm rw_lock_held 45.Nd reader / writer lock primitives 46.Sh SYNOPSIS 47.In sys/rwlock.h 48.Ft void 49.Fn rw_init "krwlock_t *rw" 50.Ft void 51.Fn rw_destroy "krwlock_t *rw" 52.Ft void 53.Fn rw_enter "krwlock_t *rw" "const krw_t op" 54.Ft void 55.Fn rw_exit "krwlock_t *rw" 56.Ft int 57.Fn rw_tryenter "krwlock_t *rw" "const krw_t op" 58.Ft int 59.Fn rw_tryupgrade "krwlock_t *rw" 60.Ft void 61.Fn rw_downgrade "krwlock_t *rw" 62.Ft int 63.Fn rw_read_held "krwlock_t *rw" 64.Ft int 65.Fn rw_write_held "krwlock_t *rw" 66.Ft int 67.Fn rw_lock_held "krwlock_t *rw" 68.Pp 69.Cd "options DIAGNOSTIC" 70.Cd "options LOCKDEBUG" 71.Sh DESCRIPTION 72Reader / writer locks (RW locks) are used in the kernel to synchronize access 73to an object among LWPs (lightweight processes) and soft interrupt handlers. 74.Pp 75In addition to the capabilities provided by mutexes, RW locks distinguish 76between read (shared) and write (exclusive) access. 77.Pp 78RW locks are in one of three distinct states at any given time: 79.Bl -tag -width cdosrunrundo 80.It Dv Unlocked 81The lock is not held. 82.It Dv Read locked 83The lock holders intend to read the protected object. 84Multiple callers may hold a RW lock with 85.Dq read intent 86simultaneously. 87.It Dv Write locked 88The lock holder intends to update the protected object. 89Only one caller may hold a RW lock with 90.Dq write intent . 91.El 92.Pp 93The 94.Vt krwlock_t 95type provides storage for the RW lock object. 96This should be treated as an opaque object and not examined directly by 97consumers. 98.Pp 99Note that these interfaces must not be used from a hardware 100interrupt handler. 101.Sh OPTIONS AND MACROS 102.Bl -tag -width abcd 103.It Cd "options DIANOSTIC" 104.Pp 105Kernels compiled with the 106.Dv DIAGNOSTIC 107option perform basic sanity checks on RW lock operations. 108.It Cd "options LOCKDEBUG" 109.Pp 110Kernels compiled with the 111.Dv LOCKDEBUG 112option perform potentially CPU intensive sanity checks 113on RW lock operations. 114.El 115.Sh FUNCTIONS 116.Bl -tag -width abcd 117.It Fn rw_init "rw" 118.Pp 119Initialize a lock for use. 120No other operations can be performed on the lock until it has been 121initialized. 122.It Fn rw_destroy "rw" 123.Pp 124Release resources used by a lock. 125The lock may not be used after it has been destroyed. 126.It Fn rw_enter "rw" "op" 127.Pp 128If 129.Dv RW_READER 130is specified as the argument to 131.Fa op , 132acquire a read lock. 133If the lock is write held, the caller will block and not return until the 134hold is acquired. 135Callers must not recursively acquire read locks. 136.Pp 137If 138.Dv RW_WRITER 139is specified, acquire a write lock. 140If the lock is already held, the caller will block and not return until the 141hold is acquired. 142.Pp 143RW locks and other types of locks must always be acquired in a 144consistent order with respect to each other. 145Otherwise, the potential for system deadlock exists. 146.It Fn rw_exit "rw" 147.Pp 148Release a lock. 149The lock must have been previously acquired by the caller. 150.It Fn rw_tryenter "rw" "op" 151.Pp 152Try to acquire a lock, but do not block if the lock is already held. 153If the lock is acquired successfully, return non-zero. 154Otherwise, return zero. 155.Pp 156Valid arguments to 157.Fa op 158are 159.Dv RW_READER 160or 161.Dv RW_WRITER . 162.It Fn rw_tryupgrade "rw" 163.Pp 164Try to upgrade a lock from one read hold to a write hold. 165If the lock is upgraded successfully, returns non-zero. 166Otherwise, returns zero. 167.It Fn rw_downgrade "rw" 168.Pp 169Downgrade a lock from a write hold to a read hold. 170.It Fn rw_write_held "rw" 171.It Fn rw_read_held "rw" 172.It Fn rw_lock_held "rw" 173.Pp 174Test the lock's condition and return non-zero if the lock is held 175(potentially by the current LWP) and matches the specified condition. 176Otherwise, return zero. 177.Pp 178These functions must never be used to make locking decisions at run time: 179they are provided only for diagnostic purposes. 180.El 181.Sh PERFORMANCE CONSIDERATIONS 182RW locks are subject to high cache contention on multiprocessor systems, 183and scale poorly when the write:read ratio is not strongly in favour of 184readers. 185Ideally, RW locks should only be used in settings when the following three 186conditions are met: 187.Bl -bullet 188.It 189The data object(s) protected by the RW lock are read much more frequently 190than written. 191.It 192The read-side hold time for the RW lock is long (in the order of thousands 193of processor clock cycles). 194.It 195Strong synchronization semantics are required: there is no scope for 196lockless, lazy or optimistic synchronization. 197.El 198.Pp 199Generally speaking, it is better to organise code paths and/or 200data flows such that fewer and weaker synchronization points are required 201to ensure correct operation. 202.Sh CODE REFERENCES 203This section describes places within the 204.Nx 205source tree where code implementing RW locks can be found. 206All pathnames are relative to 207.Pa /usr/src . 208.Pp 209The core of the RW lock implementation is in 210.Pa sys/kern/kern_rwlock.c . 211.Pp 212The header file 213.Pa sys/sys/rwlock.h 214describes the public interface, and interfaces that machine-dependent 215code must provide to support RW locks. 216.Sh SEE ALSO 217.Xr lockstat 8 , 218.Xr condvar 9 , 219.Xr mb 9 , 220.Xr mutex 9 221.Rs 222.%A Jim Mauro 223.%A Richard McDougall 224.%T Solaris Internals: Core Kernel Architecture 225.%I Prentice Hall 226.%D 2001 227.%O ISBN 0-13-022496-0 228.Re 229.Sh HISTORY 230The RW lock primitives first appeared in 231.Nx 5.0 . 232