1 '\" te
   2 .\"  Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved
   3 .\" Copyright (c) 2013, Joyent, Inc. All rights reserved.
   4 .\" The contents of this file are subject to the terms of the Common Development and Distribution License (the "License").  You may not use this file except in compliance with the License.
   5 .\" You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE or http://www.opensolaris.org/os/licensing.  See the License for the specific language governing permissions and limitations under the License.
   6 .\" When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE.  If applicable, add the following below this CDDL HEADER, with the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner]
   7 .TH RWLOCK 9F "Sep 19, 2013"
   8 .SH NAME
   9 rwlock, rw_init, rw_destroy, rw_enter, rw_exit, rw_tryenter, rw_downgrade,
  10 rw_tryupgrade, rw_read_locked \- readers/writer lock functions
  11 .SH SYNOPSIS
  12 .LP
  13 .nf
  14 #include <sys/ksynch.h>
  15 
  16 
  17 
  18 \fBvoid\fR \fBrw_init\fR(\fBkrwlock_t *\fR\fIrwlp\fR, \fBchar *\fR\fIname\fR, \fBkrw_type_t\fR \fItype\fR, \fBvoid *\fR\fIarg\fR);
  19 .fi
  20 
  21 .LP
  22 .nf
  23 \fBvoid\fR \fBrw_destroy\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
  24 .fi
  25 
  26 .LP
  27 .nf
  28 \fBvoid\fR \fBrw_enter\fR(\fBkrwlock_t *\fR\fIrwlp\fR, \fBkrw_t\fR \fIenter_type\fR);
  29 .fi
  30 
  31 .LP
  32 .nf
  33 \fBvoid\fR \fBrw_exit\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
  34 .fi
  35 
  36 .LP
  37 .nf
  38 \fBint\fR \fBrw_tryenter\fR(\fBkrwlock_t *\fR\fIrwlp\fR, \fBkrw_t\fR \fIenter_type\fR);
  39 .fi
  40 
  41 .LP
  42 .nf
  43 \fBvoid\fR \fBrw_downgrade\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
  44 .fi
  45 
  46 .LP
  47 .nf
  48 \fBint\fR \fBrw_tryupgrade\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
  49 .fi
  50 
  51 .LP
  52 .nf
  53 \fBint\fR \fBrw_read_locked\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
  54 .fi
  55 
  56 .SH INTERFACE LEVEL
  57 .sp
  58 .LP
  59 Solaris DDI specific (Solaris DDI).
  60 .SH PARAMETERS
  61 .sp
  62 .ne 2
  63 .na
  64 \fB\fIrwlp\fR\fR
  65 .ad
  66 .RS 14n
  67 Pointer to a \fBkrwlock_t\fR readers/writer lock.
  68 .RE
  69 
  70 .sp
  71 .ne 2
  72 .na
  73 \fB\fIname\fR\fR
  74 .ad
  75 .RS 14n
  76 Descriptive string. This is obsolete and should be \fBNULL\fR. (Non-null
  77 strings are legal, but they're a waste of kernel memory.)
  78 .RE
  79 
  80 .sp
  81 .ne 2
  82 .na
  83 \fB\fItype\fR\fR
  84 .ad
  85 .RS 14n
  86 Type of readers/writer lock.
  87 .RE
  88 
  89 .sp
  90 .ne 2
  91 .na
  92 \fB\fIarg\fR\fR
  93 .ad
  94 .RS 14n
  95 Type-specific argument for initialization function.
  96 .RE
  97 
  98 .sp
  99 .ne 2
 100 .na
 101 \fB\fIenter_type\fR\fR
 102 .ad
 103 .RS 14n
 104 One of the values \fBRW_WRITER\fR, \fBRW_READER\fR or
 105 \fBRW_READER_STARVEWRITER\fR, indicating whether the
 106 lock is to be acquired exclusively (\fBRW_WRITER\fR), non-exclusively
 107 (\fBRW_READER\fR) or non-exclusively without regard to any threads
 108 that may be blocked on exclusive access (\fBRW_READER_STARVEWRITER\fR).
 109 .RE
 110 
 111 .SH DESCRIPTION
 112 .sp
 113 .LP
 114 A multiple-readers, single-writer lock is represented by the \fBkrwlock_t\fR
 115 data type. This type of lock will allow many threads to have simultaneous
 116 read-only access to an object. Only one thread may have write access at any one
 117 time. An object that is searched more frequently than it is changed is a good
 118 candidate for a readers/writer lock.
 119 .sp
 120 .LP
 121 Readers/writer locks are slightly more expensive than mutex locks, and the
 122 advantage of multiple read access may not occur if the lock will only be held
 123 for a short time.
 124 .sp
 125 .LP
 126 The \fBrw_init()\fR function initializes a readers/writer lock. It is an error
 127 to initialize a lock more than once. The \fItype\fR argument should be set to
 128 \fBRW_DRIVER\fR. If the lock is used by the interrupt handler, the
 129 type-specific argument, \fIarg\fR, should be the interrupt priority returned
 130 from \fBddi_intr_get_pri\fR(9F) or \fBddi_intr_get_softint_pri\fR(9F). Note
 131 that arg should be the value of the interrupt priority cast by calling the
 132 \fBDDI_INTR_PRI\fR macro. If the lock is not used by any interrupt handler, the
 133 argument should be \fINULL.\fR
 134 .sp
 135 .LP
 136 The \fBrw_destroy()\fR function releases any resources that might have been
 137 allocated by \fBrw_init()\fR. It should be called before freeing the memory
 138 containing the lock. The lock must not be held by any thread when it is
 139 destroyed.
 140 .sp
 141 .LP
 142 The \fBrw_enter()\fR function acquires the lock, and blocks if necessary. If
 143 \fIenter_type\fR is \fBRW_WRITER\fR, the caller blocks if any thread holds 
 144 the lock. If \fIenter_type\fR is \fBRW_READER\fR, the caller blocks if there
 145 is a writer or a thread attempting to enter for writing. If \fIenter_type\fR
 146 is \fBRW_READER_STARVEWRITER\fR, the caller blocks only if there is a writer;
 147 if the lock is held for reading and a thread is blocked attempting to enter
 148 for writing, the caller will acquire the lock as a reader instead of
 149 blocking on the pending writer.
 150 
 151 .sp
 152 .LP
 153 NOTE: It is a programming error for any thread to acquire an rwlock as
 154 \fBRW_READER\fR that it already holds. Doing so can deadlock the system: if
 155 thread R acquires the lock as \fBRW_READER\fR, then thread W tries to acquire
 156 the lock as a writer, W will set write-wanted and block. When R tries to get
 157 its second read hold on the lock, it will honor the write-wanted bit and block
 158 waiting for W; but W cannot run until R drops the lock. Thus threads R and W
 159 deadlock.  To opt out of this behavior -- that is, to safely allow a lock to
 160 be grabbed recursively as a reader -- the lock should be acquired as
 161 \fBRW_READER_STARVEWRITER\fR, which will allow R to get its second read hold
 162 without regard for the write-wanted bit set by W.  Note that the
 163 \fBRW_READER_STARVEWRITER\fR behavior will starve writers in the presence of
 164 infinite readers; it should be used with care, and only where the default
 165 \fBRW_READER\fR behavior is unacceptable.
 166 .sp
 167 .LP
 168 The \fBrw_exit()\fR function releases the lock and may wake up one or more
 169 threads waiting on the lock.
 170 .sp
 171 .LP
 172 The \fBrw_tryenter()\fR function attempts to enter the lock, like
 173 \fBrw_enter()\fR, but never blocks. It returns a non-zero value if the lock was
 174 successfully entered, and zero otherwise.
 175 .sp
 176 .LP
 177 A thread that holds the lock exclusively (entered with \fBRW_WRITER\fR), may
 178 call \fBrw_downgrade()\fR to convert to holding the lock non-exclusively (as if
 179 entered with \fBRW_READER\fR). One or more waiting readers may be unblocked.
 180 .sp
 181 .LP
 182 The \fBrw_tryupgrade()\fR function can be called by a thread that holds the
 183 lock for reading to attempt to convert to holding it for writing. This upgrade
 184 can only succeed if no other thread is holding the lock and no other thread is
 185 blocked waiting to acquire the lock for writing.
 186 .sp
 187 .LP
 188 The \fBrw_read_locked()\fR function returns non-zero if the calling thread
 189 holds the lock for read, and zero if the caller holds the lock for write. The
 190 caller must hold the lock. The system may panic if \fBrw_read_locked()\fR is
 191 called for a lock that isn't held by the caller.
 192 .SH RETURN VALUES
 193 .sp
 194 .ne 2
 195 .na
 196 \fB\fB0\fR\fR
 197 .ad
 198 .RS 12n
 199 \fBrw_tryenter()\fR could not obtain the lock without blocking.
 200 .RE
 201 
 202 .sp
 203 .ne 2
 204 .na
 205 \fB\fB0\fR\fR
 206 .ad
 207 .RS 12n
 208 \fBrw_tryupgrade()\fR was unable to perform the upgrade because of other
 209 threads holding or waiting to hold the lock.
 210 .RE
 211 
 212 .sp
 213 .ne 2
 214 .na
 215 \fB\fB0\fR\fR
 216 .ad
 217 .RS 12n
 218 \fBrw_read_locked()\fR returns \fB0\fR if the lock is held by the caller for
 219 write.
 220 .RE
 221 
 222 .sp
 223 .ne 2
 224 .na
 225 \fB\fBnon-zero\fR\fR
 226 .ad
 227 .RS 12n
 228 from \fBrw_read_locked()\fR if the lock is held by the caller for read.
 229 .RE
 230 
 231 .sp
 232 .ne 2
 233 .na
 234 \fB\fBnon-zero\fR\fR
 235 .ad
 236 .RS 12n
 237 successful return from \fBrw_tryenter()\fR or \fBrw_tryupgrade()\fR.
 238 .RE
 239 
 240 .SH CONTEXT
 241 .sp
 242 .LP
 243 These functions can be called from user, interrupt, or kernel context, except
 244 for \fBrw_init()\fR and \fBrw_destroy()\fR, which can be called from user
 245 context only.
 246 .SH SEE ALSO
 247 .sp
 248 .LP
 249 \fBcondvar\fR(9F), \fBddi_intr_alloc\fR(9F), \fBddi_intr_add_handler\fR(9F),
 250 \fBddi_intr_get_pri\fR(9F), \fBddi_intr_get_softint_pri\fR(9F),
 251 \fBmutex\fR(9F), \fBsemaphore\fR(9F)
 252 .sp
 253 .LP
 254 \fIWriting Device Drivers\fR
 255 .SH NOTES
 256 .sp
 257 .LP
 258 Compiling with \fB_LOCKTEST\fR or \fB_MPSTATS\fR defined no longer has any
 259 effect. To gather lock statistics, see \fBlockstat\fR(1M).