xref: /freebsd/share/man/man9/sx.9 (revision 7dfd9569a2f0637fb9a48157b1c1bfe5709faee3)
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_destroy ,
36.Nm sx_slock ,
37.Nm sx_xlock ,
38.Nm sx_try_slock ,
39.Nm sx_try_xlock ,
40.Nm sx_sunlock ,
41.Nm sx_xunlock ,
42.Nm sx_try_upgrade ,
43.Nm sx_downgrade ,
44.Nm sx_assert ,
45.Nm sx_unlock ,
46.Nm SX_SYSINIT
47.Nd kernel shared/exclusive lock
48.Sh SYNOPSIS
49.In sys/param.h
50.In sys/lock.h
51.In sys/sx.h
52.Ft void
53.Fn sx_init "struct sx *sx" "const char *description"
54.Ft void
55.Fn sx_destroy "struct sx *sx"
56.Ft void
57.Fn sx_slock "struct sx *sx"
58.Ft void
59.Fn sx_xlock "struct sx *sx"
60.Ft int
61.Fn sx_try_slock "struct sx *sx"
62.Ft int
63.Fn sx_try_xlock "struct sx *sx"
64.Ft void
65.Fn sx_sunlock "struct sx *sx"
66.Ft void
67.Fn sx_xunlock "struct sx *sx"
68.Ft int
69.Fn sx_try_upgrade "struct sx *sx"
70.Ft void
71.Fn sx_downgrade "struct sx *sx"
72.Ft void
73.Fn sx_assert "struct sx *sx" "int what"
74.\"
75.Ss Nm Ss utility macros
76.Fn sx_unlock "struct sx *sx"
77.Fn SX_SYSINIT "name" "struct sx *sx" "const char *description"
78.\"
79.Ss Kernel options
80.Cd "options INVARIANTS"
81.Cd "options INVARIANT_SUPPORT"
82.Sh DESCRIPTION
83Shared/exclusive locks are used to protect data that are read far more often
84than they are written.
85Mutexes are inherently more efficient than shared/exclusive locks, so
86shared/exclusive locks should be used prudently.
87.Pp
88Shared/exclusive locks are created with
89.Fn sx_init ,
90where
91.Fa sx
92is a pointer to space for a
93.Vt struct sx ,
94and
95.Fa description
96is a pointer to a null-terminated character string that describes the
97shared/exclusive lock.
98Shared/exclusive locks are destroyed with
99.Fn sx_destroy .
100Threads acquire and release a shared lock by calling
101.Fn sx_slock
102or
103.Fn sx_try_slock
104and
105.Fn sx_sunlock
106or
107.Fn sx_unlock .
108Threads acquire and release an exclusive lock by calling
109.Fn sx_xlock
110or
111.Fn sx_try_xlock
112and
113.Fn sx_xunlock
114or
115.Fn sx_unlock .
116A thread can attempt to upgrade a currently held shared lock to an exclusive
117lock by calling
118.Fn sx_try_upgrade .
119A thread that has an exclusive lock can downgrade it to a shared lock by
120calling
121.Fn sx_downgrade .
122.Pp
123.Fn sx_try_slock
124and
125.Fn sx_try_xlock
126will return 0 if the shared/exclusive lock cannot be acquired immediately;
127otherwise the shared/exclusive lock will be acquired and a non-zero value will
128be returned.
129.Pp
130.Fn sx_try_upgrade
131will return 0 if the shared lock cannot be upgraded to an exclusive lock
132immediately; otherwise the exclusive lock will be acquired and a non-zero value
133will be returned.
134.Pp
135When compiled with
136.Cd "options INVARIANTS"
137and
138.Cd "options INVARIANT_SUPPORT" ,
139the
140.Fn sx_assert
141function tests
142.Fa sx
143for the assertions specified in
144.Fa what ,
145and panics if they are not met.
146The following assertions are supported:
147.Bl -tag -width ".Dv SX_UNLOCKED"
148.It Dv SX_LOCKED
149Assert that the current thread has either a shared or an exclusive lock on the
150.Vt sx
151lock pointed to by the first argument.
152.It Dv SX_SLOCKED
153Assert that the current thread has a shared lock on the
154.Vt sx
155lock pointed to by
156the first argument.
157.It Dv SX_XLOCKED
158Assert that the current thread has an exclusive lock on the
159.Vt sx
160lock pointed to
161by the first argument.
162.It Dv SX_UNLOCKED
163Assert that the current thread has no lock on the
164.Vt sx
165lock pointed to
166by the first argument.
167.El
168.Pp
169For ease of programming,
170.Fn sx_unlock
171is provided as a macro frontend to the respective functions,
172.Fn sx_sunlock
173and
174.Fn sx_xunlock .
175Algorithms that are aware of what state the lock is in should use either
176of the two specific functions for a minor performance benefit.
177.Pp
178The
179.Fn SX_SYSINIT
180macro is used to generate a call to the
181.Fn sx_sysinit
182routine at system startup in order to initialize a given
183.Fa sx
184lock.
185The parameters are the same as
186.Fn sx_init
187but with an additional argument,
188.Fa name ,
189that is used in generating unique variable names for the related
190structures associated with the lock and the sysinit routine.
191.Pp
192A thread may not hold both a shared lock and an exclusive lock on the same
193lock simultaneously;
194attempting to do so will result in deadlock.
195.Sh CONTEXT
196A thread may hold a shared or exclusive lock on an
197.Nm
198lock while sleeping.
199As a result, an
200.Nm
201lock may not be acquired while holding a mutex.
202Otherwise, if one thread slept while holding an
203.Nm
204lock while another thread blocked on the same
205.Nm
206lock after acquiring a mutex, then the second thread would effectively
207end up sleeping while holding a mutex, which is not allowed.
208.Sh SEE ALSO
209.Xr mutex 9 ,
210.Xr panic 9 ,
211.Xr rwlock 9 ,
212.Xr sema 9
213.Sh BUGS
214Currently there is no way to assert that a lock is not held.
215This is not possible in the
216.No non- Ns Dv WITNESS
217case for asserting that this thread
218does not hold a shared lock.
219In the
220.No non- Ns Dv WITNESS
221case, the
222.Dv SX_LOCKED
223and
224.Dv SX_SLOCKED
225assertions merely check that some thread holds a shared lock.
226They do not ensure that the current thread holds a shared lock.
227