1493c9781SSascha Wildner.\" 2493c9781SSascha Wildner.\" Copyright (c) 2010 The DragonFly Project. All rights reserved. 3493c9781SSascha Wildner.\" 4493c9781SSascha Wildner.\" Redistribution and use in source and binary forms, with or without 5493c9781SSascha Wildner.\" modification, are permitted provided that the following conditions 6493c9781SSascha Wildner.\" are met: 7493c9781SSascha Wildner.\" 8493c9781SSascha Wildner.\" 1. Redistributions of source code must retain the above copyright 9493c9781SSascha Wildner.\" notice, this list of conditions and the following disclaimer. 10493c9781SSascha Wildner.\" 2. Redistributions in binary form must reproduce the above copyright 11493c9781SSascha Wildner.\" notice, this list of conditions and the following disclaimer in 12493c9781SSascha Wildner.\" the documentation and/or other materials provided with the 13493c9781SSascha Wildner.\" distribution. 14493c9781SSascha Wildner.\" 3. Neither the name of The DragonFly Project nor the names of its 15493c9781SSascha Wildner.\" contributors may be used to endorse or promote products derived 16493c9781SSascha Wildner.\" from this software without specific, prior written permission. 17493c9781SSascha Wildner.\" 18493c9781SSascha Wildner.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19493c9781SSascha Wildner.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20493c9781SSascha Wildner.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21493c9781SSascha Wildner.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22493c9781SSascha Wildner.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23493c9781SSascha Wildner.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24493c9781SSascha Wildner.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25493c9781SSascha Wildner.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26493c9781SSascha Wildner.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27493c9781SSascha Wildner.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28493c9781SSascha Wildner.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29493c9781SSascha Wildner.\" SUCH DAMAGE. 30493c9781SSascha Wildner.\" 31dcece5c7SNuno Antunes.Dd August 24, 2012 32493c9781SSascha Wildner.Dt MUTEX 9 33fb5b3747SSascha Wildner.Os 34493c9781SSascha Wildner.Sh NAME 35b8e54b97SSascha Wildner.Nm mutex , 36493c9781SSascha Wildner.Nm mtx_init , 37493c9781SSascha Wildner.Nm mtx_uninit , 38493c9781SSascha Wildner.Nm mtx_lock_sh , 39493c9781SSascha Wildner.Nm mtx_lock_sh_quick , 40493c9781SSascha Wildner.Nm mtx_lock_ex , 41493c9781SSascha Wildner.Nm mtx_lock_ex_quick , 42dcece5c7SNuno Antunes.Nm mtx_lock , 43dcece5c7SNuno Antunes.Nm mtx_spinlock , 44493c9781SSascha Wildner.Nm mtx_lock_ex_try , 45493c9781SSascha Wildner.Nm mtx_lock_sh_try , 46dcece5c7SNuno Antunes.Nm mtx_spinlock_try , 47493c9781SSascha Wildner.Nm mtx_downgrade , 48493c9781SSascha Wildner.Nm mtx_upgrade_try , 49493c9781SSascha Wildner.Nm mtx_unlock , 50493c9781SSascha Wildner.Nm mtx_unlock_ex , 51493c9781SSascha Wildner.Nm mtx_unlock_sh , 52dcece5c7SNuno Antunes.Nm mtx_spinunlock , 53493c9781SSascha Wildner.Nm mtx_islocked , 54493c9781SSascha Wildner.Nm mtx_islocked_ex , 55493c9781SSascha Wildner.Nm mtx_notlocked , 56493c9781SSascha Wildner.Nm mtx_notlocked_ex , 5751ee83e2SSascha Wildner.Nm mtx_owned , 5851ee83e2SSascha Wildner.Nm mtx_notowned , 59493c9781SSascha Wildner.Nm mtx_lockrefs , 60493c9781SSascha Wildner.Nm mtx_hold , 61493c9781SSascha Wildner.Nm mtx_drop 62493c9781SSascha Wildner.Nd general blocking/spinnable mutex functions 63493c9781SSascha Wildner.Sh SYNOPSIS 64e7c86b60SSascha Wildner.In sys/globaldata.h 65493c9781SSascha Wildner.In sys/mutex2.h 66493c9781SSascha Wildner.Ft void 67493c9781SSascha Wildner.Fn mtx_init "struct mtx *mtx" 68493c9781SSascha Wildner.Ft void 69493c9781SSascha Wildner.Fn mtx_uninit "struct mtx *mtx" 70493c9781SSascha Wildner.Ft void 71493c9781SSascha Wildner.Fn mtx_lock_sh "struct mtx *mtx" "const char *ident" "int flags" "int to" 72493c9781SSascha Wildner.Ft void 73493c9781SSascha Wildner.Fn mtx_lock_sh_quick "struct mtx *mtx" "const char *ident" 74493c9781SSascha Wildner.Ft void 75493c9781SSascha Wildner.Fn mtx_lock_ex "struct mtx *mtx" "const char *ident" "int flags" "int to" 76493c9781SSascha Wildner.Ft void 77493c9781SSascha Wildner.Fn mtx_lock_ex_quick "struct mtx *mtx" "const char *ident" 78493c9781SSascha Wildner.Ft void 79dcece5c7SNuno Antunes.Fn mtx_lock "struct mtx *mtx" 80493c9781SSascha Wildner.Ft void 81dcece5c7SNuno Antunes.Fn mtx_spinlock "struct mtx *mtx" 82493c9781SSascha Wildner.Ft int 83493c9781SSascha Wildner.Fn mtx_lock_ex_try "struct mtx *mtx" 84493c9781SSascha Wildner.Ft int 85493c9781SSascha Wildner.Fn mtx_lock_sh_try "struct mtx *mtx" 86dcece5c7SNuno Antunes.Ft int 87dcece5c7SNuno Antunes.Fn mtx_spinlock_try "struct mtx *mtx" 88493c9781SSascha Wildner.Ft void 89493c9781SSascha Wildner.Fn mtx_downgrade "struct mtx *mtx" 90493c9781SSascha Wildner.Ft int 91493c9781SSascha Wildner.Fn mtx_upgrade_try "struct mtx *mtx" 92493c9781SSascha Wildner.Ft void 93493c9781SSascha Wildner.Fn mtx_unlock "struct mtx *mtx" 94493c9781SSascha Wildner.Ft void 95493c9781SSascha Wildner.Fn mtx_unlock_ex "struct mtx *mtx" 96493c9781SSascha Wildner.Ft void 97493c9781SSascha Wildner.Fn mtx_unlock_sh "struct mtx *mtx" 98dcece5c7SNuno Antunes.Ft void 99dcece5c7SNuno Antunes.Fn mtx_spinunlock "struct mtx *mtx" 100493c9781SSascha Wildner.Ft int 101493c9781SSascha Wildner.Fn mtx_islocked "struct mtx *mtx" 102493c9781SSascha Wildner.Ft int 103493c9781SSascha Wildner.Fn mtx_islocked_ex "struct mtx *mtx" 104493c9781SSascha Wildner.Ft int 105493c9781SSascha Wildner.Fn mtx_notlocked "struct mtx *mtx" 106493c9781SSascha Wildner.Ft int 107493c9781SSascha Wildner.Fn mtx_notlocked_ex "struct mtx *mtx" 108493c9781SSascha Wildner.Ft int 10951ee83e2SSascha Wildner.Fn mtx_owned "struct mtx *mtx" 110493c9781SSascha Wildner.Ft int 11151ee83e2SSascha Wildner.Fn mtx_notowned "struct mtx *mtx" 112493c9781SSascha Wildner.Ft int 113493c9781SSascha Wildner.Fn mtx_lockrefs "struct mtx *mtx" 114493c9781SSascha Wildner.Ft void 115493c9781SSascha Wildner.Fn mtx_hold "struct mtx *mtx" 116493c9781SSascha Wildner.Ft int 117493c9781SSascha Wildner.Fn mtx_drop "struct mtx *mtx" 118493c9781SSascha Wildner.Sh DESCRIPTION 119493c9781SSascha WildnerMutexes are used to implement mutual exclusion between threads. 120493c9781SSascha WildnerMutexes can be locked in shared or exclusive mode; they can also block 121493c9781SSascha Wildneror spin the current thread when there is contention. 122493c9781SSascha Wildner.Pp 123493c9781SSascha WildnerMutexes also have an associated reference count, independent of the lock. 124493c9781SSascha Wildner.Pp 125493c9781SSascha WildnerSystem-wide mutex contention statistics can be found in the 126493c9781SSascha Wildner.Va kern.mtx_contention_count , 127493c9781SSascha Wildner.Va kern.mtx_collision_count , 128493c9781SSascha Wildnerand 129493c9781SSascha Wildner.Va kern.mtx_wakeup_count 130493c9781SSascha Wildnervariables. 131493c9781SSascha Wildner.Va kern.mtx_contention_count 132493c9781SSascha Wildneris incremented each time an attempt to acquire a mutex fails due to contention. 133493c9781SSascha Wildner.Va kern.mtx_wakeup_count 134493c9781SSascha Wildneris incremented each time an exclusive lock is converted to either a shared or 135493c9781SSascha Wildnerunlocked state an waiters for the shared state are woken. 136493c9781SSascha Wildner.Pp 137493c9781SSascha WildnerThe mutex functions are similar to the 138493c9781SSascha Wildner.Xr lockmgr 9 139493c9781SSascha Wildnerfunctions. 140493c9781SSascha Wildner.Sh FUNCTIONS 141493c9781SSascha WildnerThe 142493c9781SSascha Wildner.Fn mtx_init 143493c9781SSascha Wildnerfunction initializes a mutex to the unlocked state. 144493c9781SSascha WildnerIt is an error to use a mutex without initializing it. 145493c9781SSascha Wildner.Pp 146493c9781SSascha WildnerThe 147493c9781SSascha Wildner.Fn mtx_uninit 148493c9781SSascha Wildnerfunction deinitializes a mutex. 149493c9781SSascha Wildner.Pp 150493c9781SSascha WildnerThe 151493c9781SSascha Wildner.Fn mtx_lock_sh 152493c9781SSascha Wildnerfunction attempts to lock a mutex in shared mode and blocks the current 153493c9781SSascha Wildnerthread until it is able to do so. 154493c9781SSascha WildnerThe 155493c9781SSascha Wildner.Fa ident 156493c9781SSascha Wildnerparameter is as in 157493c9781SSascha Wildner.Xr tsleep 9 , 158493c9781SSascha Wildnerit is a string describing the reason for a thread to be blocked. 159493c9781SSascha WildnerThe 160493c9781SSascha Wildner.Fa flags 161493c9781SSascha Wildnerparameter is passed to 162493c9781SSascha Wildner.Xr tsleep 9 163dcece5c7SNuno Antunesif the thread must block; the 164dcece5c7SNuno Antunes.Fa to 165dcece5c7SNuno Antunesparameter is a timeout for the sleep. 166dcece5c7SNuno AntunesThe 167493c9781SSascha Wildner.Fn mtx_lock_sh_quick 168dcece5c7SNuno Antunesfunction is a version of 169dcece5c7SNuno Antunes.Fn mtx_lock_sh 170dcece5c7SNuno Antuneswithout flags or a timeout. 171493c9781SSascha Wildner.Pp 172493c9781SSascha WildnerThe 173493c9781SSascha Wildner.Fn mtx_lock_ex 174493c9781SSascha Wildnerfunction attempts to lock a mutex exclusively and blocks the current thread 175493c9781SSascha Wildneruntil it is able to do so. 176493c9781SSascha WildnerThe 177493c9781SSascha Wildner.Fa ident 178dcece5c7SNuno Antunesand 179dcece5c7SNuno Antunes.Fa flags 180dcece5c7SNuno Antunesparameters are as in 181493c9781SSascha Wildner.Xr tsleep 9 . 182493c9781SSascha WildnerThe 183493c9781SSascha Wildner.Fa to 184493c9781SSascha Wildnerparameter is a timeout on the sleep. 185dcece5c7SNuno AntunesThe 186dcece5c7SNuno Antunes.Fn mtx_lock_ex_quick 1872315115fSSascha Wildnerfunction is a version of 188dcece5c7SNuno Antunes.Fn mtx_lock_ex 189dcece5c7SNuno Antuneswithout flags or a timeout. 190dcece5c7SNuno AntunesThe 191dcece5c7SNuno Antunes.Fn mtx_lock 192dcece5c7SNuno Antunesfunction is a yet shorter form for exclusively locking a mutex, blocking the 193dcece5c7SNuno Antunescurrent thread until acquired. 194dcece5c7SNuno AntunesIt is equivalent to mtx_lock_ex(mtx, "mtxex", 0, 0). 195493c9781SSascha Wildner.Pp 196493c9781SSascha WildnerThe 197dcece5c7SNuno Antunes.Fn mtx_spinlock 198493c9781SSascha Wildnerfunction attempts to lock the mutex in exclusive mode and spins until it is 199493c9781SSascha Wildnerable to do so. 200493c9781SSascha Wildner.Pp 201493c9781SSascha WildnerThe 202493c9781SSascha Wildner.Fn mtx_lock_ex_try 203493c9781SSascha Wildnerand 204493c9781SSascha Wildner.Fn mtx_lock_sh_try 205493c9781SSascha Wildnerfunctions attempt to lock the mutex in exclusive or shared mode, respectively. 206493c9781SSascha WildnerIf they are not able to, they return 207493c9781SSascha Wildner.Er EAGAIN . 208dcece5c7SNuno AntunesThe 209dcece5c7SNuno Antunes.Fn mtx_spinlock_try 210dcece5c7SNuno Antunesfunction does the same but for spin mutexes. 211493c9781SSascha Wildner.Pp 212493c9781SSascha WildnerThe 213493c9781SSascha Wildner.Fn mtx_downgrade 214493c9781SSascha Wildnerfunction converts an exclusively held lock to a shared lock. 215493c9781SSascha WildnerThe lock must be held by the calling thread. 216493c9781SSascha WildnerIf the lock is already shared, this call is a no-op. 217493c9781SSascha Wildner.Pp 218493c9781SSascha WildnerThe 219493c9781SSascha Wildner.Fn mtx_upgrade_try 220dd7fb6d2SSascha Wildnerfunction attempts to convert a shared lock to an exclusive one. 221493c9781SSascha WildnerThe mutex must be held by the caller in the shared state. 222493c9781SSascha WildnerIf the upgrade is successful, this function returns 0; otherwise, it returns 223493c9781SSascha Wildner.Er EDEADLK . 224493c9781SSascha Wildner.Pp 225493c9781SSascha WildnerThe 226493c9781SSascha Wildner.Fn mtx_unlock 227493c9781SSascha Wildnerfunction releases a held mutex; 228493c9781SSascha Wildnerit works on both exclusive and shared mutexes. 229493c9781SSascha WildnerThe 230493c9781SSascha Wildner.Fn mtx_unlock_ex 231493c9781SSascha Wildnerand 232493c9781SSascha Wildner.Fn mtx_unlock_sh 233493c9781SSascha Wildnerfunctions are optimized unlock paths, used when it is known that a lock is held 234493c9781SSascha Wildnerexclusively or in shared state. 235493c9781SSascha Wildner.Pp 236493c9781SSascha WildnerThe 237dcece5c7SNuno Antunes.Fn mtx_spinunlock 238dcece5c7SNuno Antunesfunction releases a held spin mutex. 239dcece5c7SNuno Antunes.Pp 240dcece5c7SNuno AntunesThe 241493c9781SSascha Wildner.Fn mtx_islocked 242493c9781SSascha Wildnerfunction returns non-zero if the mutex is locked in either shared of 243493c9781SSascha Wildnerexclusive state by any thread. 244493c9781SSascha Wildner.Fn mtx_islocked_ex 245493c9781SSascha Wildnerreturns non-zero if the mutex is locked exclusively by any thread. 246493c9781SSascha WildnerThe 247493c9781SSascha Wildner.Fn mtx_notlocked 248493c9781SSascha Wildnerfunction returns non-zero if the mutex is not locked. 249493c9781SSascha WildnerThe 250493c9781SSascha Wildner.Fn mtx_owned 251493c9781SSascha Wildnerfunction returns non-zero if the mutex is exclusively locked by the calling 252493c9781SSascha Wildnerthread. 253493c9781SSascha WildnerThe 254493c9781SSascha Wildner.Fn mtx_notowned 255493c9781SSascha Wildnerfunction returns non-zero if the mutex is not exclusively locked by the 256493c9781SSascha Wildnercalling thread. 257493c9781SSascha WildnerThe 258493c9781SSascha Wildner.Fn mtx_lockrefs 259493c9781SSascha Wildnerfunction returns the number of shared or exclusive locks on the mutex. 260493c9781SSascha Wildner.Pp 261493c9781SSascha WildnerThe 262493c9781SSascha Wildner.Fn mtx_hold 263493c9781SSascha Wildnerfunction increments the reference count associated with each mutex. 264493c9781SSascha WildnerThe reference count is independent of the lock field. 265493c9781SSascha WildnerThe 266493c9781SSascha Wildner.Fn mtx_drop 267493c9781SSascha Wildnerfunction decrements the reference count associated with each mutex 268493c9781SSascha Wildnerand returns the old value of the count. 269493c9781SSascha WildnerA return value of 270493c9781SSascha Wildner.Sq 1 271493c9781SSascha Wildnermeans that the current count is 272493c9781SSascha Wildner.Sq 0 . 273493c9781SSascha Wildner.Sh FILES 274b8e54b97SSascha WildnerThe uncontended path of the 275b8e54b97SSascha Wildner.Nm 276b8e54b97SSascha Wildnerimplementation is in 277493c9781SSascha Wildner.Pa /sys/sys/mutex2.h . 278493c9781SSascha WildnerThe data structures are in 279493c9781SSascha Wildner.Pa /sys/sys/mutex.h . 280493c9781SSascha WildnerThe core of the spinlock implementation is in 281493c9781SSascha Wildner.Pa /sys/kern/kern_mutex.c . 282493c9781SSascha Wildner.Sh SEE ALSO 283493c9781SSascha Wildner.Xr crit_enter 9 , 284*c04308e8SMarkus Pfeiffer.Xr locking 9 , 285493c9781SSascha Wildner.Xr lockmgr 9 , 286493c9781SSascha Wildner.Xr serializer 9 , 287dcece5c7SNuno Antunes.Xr sleep 9 , 288493c9781SSascha Wildner.Xr spinlock 9 289493c9781SSascha Wildner.Sh HISTORY 290493c9781SSascha WildnerMutexes first appeared in 291493c9781SSascha Wildner.Dx 2.3 . 292493c9781SSascha Wildner.Sh AUTHORS 293493c9781SSascha Wildner.An -nosplit 294493c9781SSascha WildnerThe 295b8e54b97SSascha Wildner.Nm 296493c9781SSascha Wildnerimplementation was written by 297493c9781SSascha Wildner.An Matthew Dillon . 298