xref: /netbsd-src/share/man/man9/mutex.9 (revision 0df165c04d0a9ca1adde9ed2b890344c937954a6)
1.\"	$NetBSD: mutex.9,v 1.9 2007/04/09 13:37:57 ad Exp $
2.\"
3.\" Copyright (c) 2007 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.\" 3. All advertising materials mentioning features or use of this software
18.\"    must display the following acknowledgement:
19.\"        This product includes software developed by the NetBSD
20.\"        Foundation, Inc. and its contributors.
21.\" 4. Neither the name of The NetBSD Foundation nor the names of its
22.\"    contributors may be used to endorse or promote products derived
23.\"    from this software without specific prior written permission.
24.\"
25.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
26.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
27.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
29.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
30.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
31.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
32.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
33.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
34.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
35.\" POSSIBILITY OF SUCH DAMAGE.
36.\"
37.Dd April 9, 2007
38.Dt MUTEX 9
39.Os
40.Sh NAME
41.Nm mutex ,
42.Nm mutex_init ,
43.Nm mutex_destroy ,
44.Nm mutex_enter ,
45.Nm mutex_exit ,
46.Nm mutex_tryenter ,
47.Nm mutex_owned
48.Nd mutual exclusion primitives
49.Sh SYNOPSIS
50.In sys/mutex.h
51.Ft void
52.Fn mutex_init "kmutex_t *mtx" "kmutex_type_t type" "int ipl"
53.Ft void
54.Fn mutex_destroy "kmutex_t *mtx"
55.Ft void
56.Fn mutex_enter "kmutex_t *mtx"
57.Ft void
58.Fn mutex_exit "kmutex_t *mtx"
59.Ft int
60.Fn mutex_tryenter "kmutex_t *mtx"
61.Ft int
62.Fn mutex_owned "kmutex_t *mtx"
63.Pp
64.Cd "options DIAGNOSTIC"
65.Cd "options LOCKDEBUG"
66.Sh DESCRIPTION
67Mutexes are used in the kernel to implement mutual exclusion among LWPs
68(lightweight processes) and interrupt handlers.
69.Pp
70The
71.Vt kmutex_t
72type provides storage for the mutex object.
73This should be treated as an opaque object and not examined directly by
74consumers.
75.Pp
76Mutexes replace the
77.Xr spl 9
78system traditionally used to provide synchronization between interrupt
79handlers and LWPs, and in combination with reader / writer locks replace
80the
81.Xr lockmgr 9
82facility.
83.Sh OPTIONS
84.Bl -tag -width abcd
85.It Cd "options DIAGNOSTIC"
86.Pp
87Kernels compiled with the
88.Dv DIAGNOSTIC
89option perform basic sanity checks on mutex operations.
90.It Cd "options LOCKDEBUG"
91.Pp
92Kernels compiled with the
93.Dv LOCKDEBUG
94option perform potentially CPU intensive sanity checks
95on mutex operations.
96.El
97.Sh FUNCTIONS
98.Bl -tag -width abcd
99.It Fn mutex_init "mtx" "type" "ipl"
100.Pp
101Dynamically initialize a mutex for use.
102No other operations can be performed on a mutex until it has been initialized.
103.Fn mutex_init
104may block in order to allocate memory.
105.Pp
106The
107.Fa type
108argument specifies the kind of mutex to be initialized, controlling the
109behaviour of the mutex.
110Once initialized, all types of mutex are manipulated using the same interface.
111Valid types are as follows:
112.Bl -tag -width cdoscdosrunru
113.It Dv MUTEX_DEFAULT
114Requests an adaptive mutex.
115Adaptive mutexes provide mutual exclusion between LWPs.
116.Pp
117When initializing an adaptive mutex,
118.Dv IPL_NONE
119must be specified as the
120.Fa ipl
121argument.
122Adaptive mutexes should not be acquired from an interrupt handler.
123.Pp
124An LWP may either sleep or busy-wait when attempting to acquire
125an adaptive mutex that is already held.
126.It Dv MUTEX_SPIN
127Requests a spin mutex.
128Spin mutexes provide mutual exclusion between LWPs, and between LWPs
129and interrupt handlers.
130.Pp
131When initializing a spin mutex, the
132.Fa ipl
133argument is used to pass an system interrupt priority level (SPL)
134that will block all interrupt handlers that may try to acquire the mutex.
135.Pp
136LWPs that own spin mutexes may not sleep, and therefore must not
137try to acquire adaptive mutexes or other sleep locks.
138.Pp
139A processor will always busy-wait when attempting to acquire
140a spin mutex that is already held.
141.El
142.Pp
143In general, device drivers should not directly request spin or adaptive
144mutexes.
145For device drivers a third type of mutex is provided:
146.Bl -tag -width cdoscdosrunru
147.It Dv MUTEX_DRIVER
148Requests a device driver mutex.
149.Pp
150The
151.Fa ipl
152argument is used to determine whether a spin or adaptive mutex is
153returned, depending on how interrupt handling is implemented by
154the machine architecture.
155.Pp
156If
157.Dv IPL_NONE
158is specified,
159.Fn mutex_init
160is guaranteed to return an adaptive mutex that can be used to
161provide mutual exclusion for device driver code that does not
162run from an interrupt handler.
163Other levels return mutexes that can be used to synchronize
164with interrupt handlers.
165For example, to request a mutex for synchronizing with network
166interrupt handlers, specify
167.Dv IPL_NET .
168Beyond this, device drivers should not make assumptions about
169the type of mutex returned.
170.El
171.It Fn mutex_destroy "mtx"
172.Pp
173Release resources used by a mutex.
174The mutex may not be used after it has been destroyed.
175.Fn mutex_destroy
176may block in order to free memory.
177.It Fn mutex_enter "mtx"
178.Pp
179Acquire a mutex.
180If the mutex is already held, the caller will block and not return until the
181mutex is acquired.
182.Pp
183Mutexes and other types of locks must always be acquired in a
184consistent order with respect to each other.
185Otherwise, the potential for system deadlock exists.
186.Pp
187Adaptive mutexes and other types of lock that can sleep may
188not be acquired once a spin mutex is held by the caller.
189Note that device driver mutexes at a level other than
190.Dv IPL_NONE
191can be spin mutexes.
192.It Fn mutex_exit "mtx"
193.Pp
194Release a mutex.
195The mutex must have been previously acquired by the caller.
196Mutexes may be released out of order as needed.
197.It Fn mutex_tryenter "mtx"
198.Pp
199Try to acquire a mutex, but do not block if the mutex is already held.
200Returns non-zero if the mutex was acquired, or zero if the mutex was
201already held.
202.Pp
203.Fn mutex_tryenter
204can be used as an optimization when acquiring locks in the the wrong order.
205For example, in a setting where the convention is that
206.Dv first_lock
207must be acquired before
208.Dv second_lock ,
209the following can be used to optimistically lock in reverse order:
210.Bd -literal
211	/* We hold second_lock, but not first_lock. */
212	KASSERT(mutex_owned(\*[Am]second_lock));
213
214	if (!mutex_tryenter(\*[Am]first_lock)) {
215		/* Failed to get it - lock in the correct order. */
216		mutex_exit(\*[Am]second_lock);
217		mutex_enter(\*[Am]first_lock);
218		mutex_enter(\*[Am]second_lock);
219
220		/*
221		 * We may need to recheck any conditions the code
222		 * path depends on, as we released second_lock
223		 * briefly.
224		 */
225	}
226.Ed
227.It Fn mutex_owned "mtx"
228.Pp
229For adaptive mutexes, return non-zero if the current LWP holds the mutex.
230For spin mutexes, return non-zero if the mutex is held, potentially by the
231current processor.
232Otherwise, return zero.
233.Pp
234.Fn mutex_owned
235is provided for making diagnostic checks to verify that a lock is held.
236For example:
237.Bd -literal
238	KASSERT(mutex_owned(\*[Am]driver_lock));
239.Ed
240.Pp
241It should not be used to make locking decisions at run time, or to
242verify that a lock is unheld.
243.El
244.Sh CODE REFERENCES
245This section describes places within the
246.Nx
247source tree where code implementing mutexes can be found.
248All pathnames are relative to
249.Pa /usr/src .
250.Pp
251The core of the mutex implementation is in
252.Pa sys/kern/kern_mutex.c .
253.Pp
254The header file
255.Pa sys/sys/mutex.h
256describes the public interface, and interfaces that machine-dependent
257code must provide to support mutexes.
258.Sh SEE ALSO
259.Xr condvar 9 ,
260.Xr mb 9 ,
261.Xr rwlock 9
262.Pp
263.Rs
264.%A Jim Mauro
265.%A Richard McDougall
266.%T Solaris Internals: Core Kernel Architecture ,
267.%I Prentice Hall
268.%D 2001
269.%O ISBN 0-13-022496-0
270.Re
271.Sh HISTORY
272The mutex primitives first appeared in
273.Nx 5.0 .
274