xref: /freebsd/share/man/man9/sx.9 (revision f0a75d274af375d15b97b830966b99a02b7db911)
1.\"
2.\" Copyright (C) 2001 Jason Evans <jasone@FreeBSD.org>.  All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice(s), this list of conditions and the following disclaimer as
9.\"    the first lines of this file unmodified other than the possible
10.\"    addition of one or more copyright notices.
11.\" 2. Redistributions in binary form must reproduce the above copyright
12.\"    notice(s), this list of conditions and the following disclaimer in the
13.\"    documentation and/or other materials provided with the distribution.
14.\"
15.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
16.\" EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17.\" WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18.\" DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY
19.\" DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20.\" (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21.\" SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22.\" CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
25.\" DAMAGE.
26.\"
27.\" $FreeBSD$
28.\"
29.Dd February 1, 2006
30.Dt SX 9
31.Os
32.Sh NAME
33.Nm sx ,
34.Nm sx_init ,
35.Nm sx_init_flags ,
36.Nm sx_destroy ,
37.Nm sx_slock ,
38.Nm sx_xlock ,
39.Nm sx_try_slock ,
40.Nm sx_try_xlock ,
41.Nm sx_sunlock ,
42.Nm sx_xunlock ,
43.Nm sx_unlock ,
44.Nm sx_try_upgrade ,
45.Nm sx_downgrade ,
46.Nm sx_sleep ,
47.Nm sx_xlocked ,
48.Nm sx_assert ,
49.Nm SX_SYSINIT
50.Nd kernel shared/exclusive lock
51.Sh SYNOPSIS
52.In sys/param.h
53.In sys/lock.h
54.In sys/sx.h
55.Ft void
56.Fn sx_init "struct sx *sx" "const char *description"
57.Ft void
58.Fn sx_init_flags "struct sx *sx" "const char *description" "int opts"
59.Ft void
60.Fn sx_destroy "struct sx *sx"
61.Ft void
62.Fn sx_slock "struct sx *sx"
63.Ft void
64.Fn sx_xlock "struct sx *sx"
65.Ft int
66.Fn sx_try_slock "struct sx *sx"
67.Ft int
68.Fn sx_try_xlock "struct sx *sx"
69.Ft void
70.Fn sx_sunlock "struct sx *sx"
71.Ft void
72.Fn sx_xunlock "struct sx *sx"
73.Ft void
74.Fn sx_unlock "struct sx *sx"
75.Ft int
76.Fn sx_try_upgrade "struct sx *sx"
77.Ft void
78.Fn sx_downgrade "struct sx *sx"
79.Ft int
80.Fn sx_sleep "void *chan" "struct sx *sx" "int priority" "const char *wmesg" "int timo"
81.Ft int
82.Fn sx_xlocked "struct sx *sx"
83.Pp
84.Cd "options INVARIANTS"
85.Cd "options INVARIANT_SUPPORT"
86.Ft void
87.Fn sx_assert "struct sx *sx" "int what"
88.In sys/kernel.h
89.Fn SX_SYSINIT "name" "struct sx *sx" "const char *description"
90.Sh DESCRIPTION
91Shared/exclusive locks are used to protect data that are read far more often
92than they are written.
93Shared/exclusive locks do not implement priority propagation like mutexes and
94reader/writer locks to prevent priority inversions, so
95shared/exclusive locks should be used prudently.
96.Pp
97Shared/exclusive locks are created with either
98.Fn sx_init
99or
100.Fn sx_init_flags
101where
102.Fa sx
103is a pointer to space for a
104.Vt struct sx ,
105and
106.Fa description
107is a pointer to a null-terminated character string that describes the
108shared/exclusive lock.
109The
110.Fa opts
111argument to
112.Fn sx_init_flags
113specifies a set of optional flags to alter the behavior of
114.Fa sx .
115It contains one or more of the following flags:
116.Bl -tag -width SX_ADAPTIVESPIN
117.It Dv SX_ADAPTIVESPIN
118If the kernel is compiled with
119.Cd "options ADAPTIVE_SX" ,
120then lock operations for
121.Fa sx
122will spin instead of sleeping while an exclusive lock holder is executing on
123another CPU.
124.It Dv SX_DUPOK
125Witness should not log messages about duplicate locks being acquired.
126.It Dv SX_NOWITNESS
127Instruct
128.Xr witness 4
129to ignore this lock.
130.It Dv SX_NOPROFILE
131Do not profile this lock.
132.It Dv SX_QUIET
133Do not log any operations for this lock via
134.Xr ktr 4 .
135.El
136.Pp
137Shared/exclusive locks are destroyed with
138.Fn sx_destroy .
139The lock
140.Fa sx
141must not be locked by any thread when it is destroyed.
142.Pp
143Threads acquire and release a shared lock by calling
144.Fn sx_slock
145or
146.Fn sx_try_slock
147and
148.Fn sx_sunlock
149or
150.Fn sx_unlock .
151Threads acquire and release an exclusive lock by calling
152.Fn sx_xlock
153or
154.Fn sx_try_xlock
155and
156.Fn sx_xunlock
157or
158.Fn sx_unlock .
159A thread can attempt to upgrade a currently held shared lock to an exclusive
160lock by calling
161.Fn sx_try_upgrade .
162A thread that has an exclusive lock can downgrade it to a shared lock by
163calling
164.Fn sx_downgrade .
165.Pp
166.Fn sx_try_slock
167and
168.Fn sx_try_xlock
169will return 0 if the shared/exclusive lock cannot be acquired immediately;
170otherwise the shared/exclusive lock will be acquired and a non-zero value will
171be returned.
172.Pp
173.Fn sx_try_upgrade
174will return 0 if the shared lock cannot be upgraded to an exclusive lock
175immediately; otherwise the exclusive lock will be acquired and a non-zero value
176will be returned.
177.Pp
178A thread can atomically release a shared/exclusive lock while waiting for an
179event by calling
180.Fn sx_sleep .
181For more details on the parameters to this function,
182see
183.Xr sleep 9 .
184.Pp
185When compiled with
186.Cd "options INVARIANTS"
187and
188.Cd "options INVARIANT_SUPPORT" ,
189the
190.Fn sx_assert
191function tests
192.Fa sx
193for the assertions specified in
194.Fa what ,
195and panics if they are not met.
196One of the following assertions must be specified:
197.Bl -tag -width ".Dv SX_UNLOCKED"
198.It Dv SX_LOCKED
199Assert that the current thread has either a shared or an exclusive lock on the
200.Vt sx
201lock pointed to by the first argument.
202.It Dv SX_SLOCKED
203Assert that the current thread has a shared lock on the
204.Vt sx
205lock pointed to by
206the first argument.
207.It Dv SX_XLOCKED
208Assert that the current thread has an exclusive lock on the
209.Vt sx
210lock pointed to
211by the first argument.
212.It Dv SX_UNLOCKED
213Assert that the current thread has no lock on the
214.Vt sx
215lock pointed to
216by the first argument.
217.El
218.Pp
219In addition, one of the following optional assertions may be included with
220either an
221.Dv SX_LOCKED ,
222.Dv SX_SLOCKED ,
223or
224.Dv SX_XLOCKED
225assertion:
226.Bl -tag -width ".Dv SX_NOTRECURSED"
227.It Dv SX_RECURSED
228Assert that the current thread has a recursed lock on
229.Fa sx .
230.It Dv SX_NOTRECURSED
231Assert that the current thread does not have a recursed lock on
232.Fa sx .
233.El
234.Pp
235.Fn sx_xlocked
236will return non-zero if the current thread holds the exclusive lock;
237otherwise, it will return zero.
238.Pp
239For ease of programming,
240.Fn sx_unlock
241is provided as a macro frontend to the respective functions,
242.Fn sx_sunlock
243and
244.Fn sx_xunlock .
245Algorithms that are aware of what state the lock is in should use either
246of the two specific functions for a minor performance benefit.
247.Pp
248The
249.Fn SX_SYSINIT
250macro is used to generate a call to the
251.Fn sx_sysinit
252routine at system startup in order to initialize a given
253.Fa sx
254lock.
255The parameters are the same as
256.Fn sx_init
257but with an additional argument,
258.Fa name ,
259that is used in generating unique variable names for the related
260structures associated with the lock and the sysinit routine.
261.Pp
262A thread may not hold both a shared lock and an exclusive lock on the same
263lock simultaneously;
264attempting to do so will result in deadlock.
265.Sh CONTEXT
266A thread may hold a shared or exclusive lock on an
267.Nm
268lock while sleeping.
269As a result, an
270.Nm
271lock may not be acquired while holding a mutex.
272Otherwise, if one thread slept while holding an
273.Nm
274lock while another thread blocked on the same
275.Nm
276lock after acquiring a mutex, then the second thread would effectively
277end up sleeping while holding a mutex, which is not allowed.
278.Sh SEE ALSO
279.Xr locking 9 ,
280.Xr lock 9 ,
281.Xr mutex 9 ,
282.Xr panic 9 ,
283.Xr rwlock 9 ,
284.Xr sema 9
285.Sh BUGS
286Currently there is no way to assert that a lock is not held.
287This is not possible in the
288.No non- Ns Dv WITNESS
289case for asserting that this thread
290does not hold a shared lock.
291In the
292.No non- Ns Dv WITNESS
293case, the
294.Dv SX_LOCKED
295and
296.Dv SX_SLOCKED
297assertions merely check that some thread holds a shared lock.
298They do not ensure that the current thread holds a shared lock.
299