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