summaryrefslogtreecommitdiff
path: root/usr/src/man/man9f/rwlock.9f
blob: 5186d4aa5448919ff8bbe4ac5f08472051db6b48 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
'\" te
.\"  Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved
.\" Copyright (c) 2013, Joyent, Inc. All rights reserved.
.\" 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.
.\" 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.
.\" 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]
.TH RWLOCK 9F "Sep 19, 2013"
.SH NAME
rwlock, rw_init, rw_destroy, rw_enter, rw_exit, rw_tryenter, rw_downgrade,
rw_tryupgrade, rw_read_locked \- readers/writer lock functions
.SH SYNOPSIS
.LP
.nf
#include <sys/ksynch.h>



\fBvoid\fR \fBrw_init\fR(\fBkrwlock_t *\fR\fIrwlp\fR, \fBchar *\fR\fIname\fR, \fBkrw_type_t\fR \fItype\fR, \fBvoid *\fR\fIarg\fR);
.fi

.LP
.nf
\fBvoid\fR \fBrw_destroy\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
.fi

.LP
.nf
\fBvoid\fR \fBrw_enter\fR(\fBkrwlock_t *\fR\fIrwlp\fR, \fBkrw_t\fR \fIenter_type\fR);
.fi

.LP
.nf
\fBvoid\fR \fBrw_exit\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
.fi

.LP
.nf
\fBint\fR \fBrw_tryenter\fR(\fBkrwlock_t *\fR\fIrwlp\fR, \fBkrw_t\fR \fIenter_type\fR);
.fi

.LP
.nf
\fBvoid\fR \fBrw_downgrade\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
.fi

.LP
.nf
\fBint\fR \fBrw_tryupgrade\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
.fi

.LP
.nf
\fBint\fR \fBrw_read_locked\fR(\fBkrwlock_t *\fR\fIrwlp\fR);
.fi

.SH INTERFACE LEVEL
.sp
.LP
Solaris DDI specific (Solaris DDI).
.SH PARAMETERS
.sp
.ne 2
.na
\fB\fIrwlp\fR\fR
.ad
.RS 14n
Pointer to a \fBkrwlock_t\fR readers/writer lock.
.RE

.sp
.ne 2
.na
\fB\fIname\fR\fR
.ad
.RS 14n
Descriptive string. This is obsolete and should be \fBNULL\fR. (Non-null
strings are legal, but they're a waste of kernel memory.)
.RE

.sp
.ne 2
.na
\fB\fItype\fR\fR
.ad
.RS 14n
Type of readers/writer lock.
.RE

.sp
.ne 2
.na
\fB\fIarg\fR\fR
.ad
.RS 14n
Type-specific argument for initialization function.
.RE

.sp
.ne 2
.na
\fB\fIenter_type\fR\fR
.ad
.RS 14n
One of the values \fBRW_WRITER\fR, \fBRW_READER\fR or
\fBRW_READER_STARVEWRITER\fR, indicating whether the
lock is to be acquired exclusively (\fBRW_WRITER\fR), non-exclusively
(\fBRW_READER\fR) or non-exclusively without regard to any threads
that may be blocked on exclusive access (\fBRW_READER_STARVEWRITER\fR).
.RE

.SH DESCRIPTION
.sp
.LP
A multiple-readers, single-writer lock is represented by the \fBkrwlock_t\fR
data type. This type of lock will allow many threads to have simultaneous
read-only access to an object. Only one thread may have write access at any one
time. An object that is searched more frequently than it is changed is a good
candidate for a readers/writer lock.
.sp
.LP
Readers/writer locks are slightly more expensive than mutex locks, and the
advantage of multiple read access may not occur if the lock will only be held
for a short time.
.sp
.LP
The \fBrw_init()\fR function initializes a readers/writer lock. It is an error
to initialize a lock more than once. The \fItype\fR argument should be set to
\fBRW_DRIVER\fR. If the lock is used by the interrupt handler, the
type-specific argument, \fIarg\fR, should be the interrupt priority returned
from \fBddi_intr_get_pri\fR(9F) or \fBddi_intr_get_softint_pri\fR(9F). Note
that arg should be the value of the interrupt priority cast by calling the
\fBDDI_INTR_PRI\fR macro. If the lock is not used by any interrupt handler, the
argument should be \fINULL.\fR
.sp
.LP
The \fBrw_destroy()\fR function releases any resources that might have been
allocated by \fBrw_init()\fR. It should be called before freeing the memory
containing the lock. The lock must not be held by any thread when it is
destroyed.
.sp
.LP
The \fBrw_enter()\fR function acquires the lock, and blocks if necessary. If
\fIenter_type\fR is \fBRW_WRITER\fR, the caller blocks if any thread holds
the lock. If \fIenter_type\fR is \fBRW_READER\fR, the caller blocks if there
is a writer or a thread attempting to enter for writing. If \fIenter_type\fR
is \fBRW_READER_STARVEWRITER\fR, the caller blocks only if there is a writer;
if the lock is held for reading and a thread is blocked attempting to enter
for writing, the caller will acquire the lock as a reader instead of
blocking on the pending writer.

.sp
.LP
NOTE: It is a programming error for any thread to acquire an rwlock as
\fBRW_READER\fR that it already holds. Doing so can deadlock the system: if
thread R acquires the lock as \fBRW_READER\fR, then thread W tries to acquire
the lock as a writer, W will set write-wanted and block. When R tries to get
its second read hold on the lock, it will honor the write-wanted bit and block
waiting for W; but W cannot run until R drops the lock. Thus threads R and W
deadlock.  To opt out of this behavior -- that is, to safely allow a lock to
be grabbed recursively as a reader -- the lock should be acquired as
\fBRW_READER_STARVEWRITER\fR, which will allow R to get its second read hold
without regard for the write-wanted bit set by W.  Note that the
\fBRW_READER_STARVEWRITER\fR behavior will starve writers in the presence of
infinite readers; it should be used with care, and only where the default
\fBRW_READER\fR behavior is unacceptable.
.sp
.LP
The \fBrw_exit()\fR function releases the lock and may wake up one or more
threads waiting on the lock.
.sp
.LP
The \fBrw_tryenter()\fR function attempts to enter the lock, like
\fBrw_enter()\fR, but never blocks. It returns a non-zero value if the lock was
successfully entered, and zero otherwise.
.sp
.LP
A thread that holds the lock exclusively (entered with \fBRW_WRITER\fR), may
call \fBrw_downgrade()\fR to convert to holding the lock non-exclusively (as if
entered with \fBRW_READER\fR). One or more waiting readers may be unblocked.
.sp
.LP
The \fBrw_tryupgrade()\fR function can be called by a thread that holds the
lock for reading to attempt to convert to holding it for writing. This upgrade
can only succeed if no other thread is holding the lock and no other thread is
blocked waiting to acquire the lock for writing.
.sp
.LP
The \fBrw_read_locked()\fR function returns non-zero if the calling thread
holds the lock for read, and zero if the caller holds the lock for write. The
caller must hold the lock. The system may panic if \fBrw_read_locked()\fR is
called for a lock that isn't held by the caller.
.SH RETURN VALUES
.sp
.ne 2
.na
\fB\fB0\fR\fR
.ad
.RS 12n
\fBrw_tryenter()\fR could not obtain the lock without blocking.
.RE

.sp
.ne 2
.na
\fB\fB0\fR\fR
.ad
.RS 12n
\fBrw_tryupgrade()\fR was unable to perform the upgrade because of other
threads holding or waiting to hold the lock.
.RE

.sp
.ne 2
.na
\fB\fB0\fR\fR
.ad
.RS 12n
\fBrw_read_locked()\fR returns \fB0\fR if the lock is held by the caller for
write.
.RE

.sp
.ne 2
.na
\fB\fBnon-zero\fR\fR
.ad
.RS 12n
from \fBrw_read_locked()\fR if the lock is held by the caller for read.
.RE

.sp
.ne 2
.na
\fB\fBnon-zero\fR\fR
.ad
.RS 12n
successful return from \fBrw_tryenter()\fR or \fBrw_tryupgrade()\fR.
.RE

.SH CONTEXT
.sp
.LP
These functions can be called from user, interrupt, or kernel context, except
for \fBrw_init()\fR and \fBrw_destroy()\fR, which can be called from user
context only.
.SH SEE ALSO
.sp
.LP
\fBcondvar\fR(9F), \fBddi_intr_alloc\fR(9F), \fBddi_intr_add_handler\fR(9F),
\fBddi_intr_get_pri\fR(9F), \fBddi_intr_get_softint_pri\fR(9F),
\fBmutex\fR(9F), \fBsemaphore\fR(9F)
.sp
.LP
\fIWriting Device Drivers\fR
.SH NOTES
.sp
.LP
Compiling with \fB_LOCKTEST\fR or \fB_MPSTATS\fR defined no longer has any
effect. To gather lock statistics, see \fBlockstat\fR(1M).