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.\" 31*8d1b35d0SSascha Wildner.Dd March 19, 2015 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 , 39*8d1b35d0SSascha Wildner.\".Nm mtx_lock_sh_link , 40493c9781SSascha Wildner.Nm mtx_lock_sh_quick , 41493c9781SSascha Wildner.Nm mtx_lock_ex , 42*8d1b35d0SSascha Wildner.\".Nm mtx_lock_ex_link , 43493c9781SSascha Wildner.Nm mtx_lock_ex_quick , 44dcece5c7SNuno Antunes.Nm mtx_lock , 45dcece5c7SNuno Antunes.Nm mtx_spinlock , 46493c9781SSascha Wildner.Nm mtx_lock_ex_try , 47493c9781SSascha Wildner.Nm mtx_lock_sh_try , 48dcece5c7SNuno Antunes.Nm mtx_spinlock_try , 49493c9781SSascha Wildner.Nm mtx_downgrade , 50493c9781SSascha Wildner.Nm mtx_upgrade_try , 51493c9781SSascha Wildner.Nm mtx_unlock , 52493c9781SSascha Wildner.Nm mtx_unlock_ex , 53493c9781SSascha Wildner.Nm mtx_unlock_sh , 54dcece5c7SNuno Antunes.Nm mtx_spinunlock , 55493c9781SSascha Wildner.Nm mtx_islocked , 56493c9781SSascha Wildner.Nm mtx_islocked_ex , 57493c9781SSascha Wildner.Nm mtx_notlocked , 58493c9781SSascha Wildner.Nm mtx_notlocked_ex , 5951ee83e2SSascha Wildner.Nm mtx_owned , 6051ee83e2SSascha Wildner.Nm mtx_notowned , 61*8d1b35d0SSascha Wildner.Nm mtx_lockrefs 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 67*8d1b35d0SSascha Wildner.Fn mtx_init "mtx_t *mtx" 68493c9781SSascha Wildner.Ft void 69*8d1b35d0SSascha Wildner.Fn mtx_uninit "mtx_t *mtx" 70493c9781SSascha Wildner.Ft int 71*8d1b35d0SSascha Wildner.Fn mtx_lock_sh "mtx_t *mtx" "const char *ident" "int flags" "int to" 72*8d1b35d0SSascha Wildner.\".Ft int 73*8d1b35d0SSascha Wildner.\".Fn mtx_lock_sh_link "mtx_t *mtx" "mtx_link_t *link" "const char *ident" "int flags" "int to" 74493c9781SSascha Wildner.Ft int 75*8d1b35d0SSascha Wildner.Fn mtx_lock_sh_quick "mtx_t *mtx" "const char *ident" 76dcece5c7SNuno Antunes.Ft int 77*8d1b35d0SSascha Wildner.Fn mtx_lock_ex "mtx_t *mtx" "const char *ident" "int flags" "int to" 78*8d1b35d0SSascha Wildner.\".Ft int 79*8d1b35d0SSascha Wildner.\".Fn mtx_lock_ex_link "mtx_t *mtx" "mtx_link_t *link" "const char *ident" "int flags" "int to" 80*8d1b35d0SSascha Wildner.Ft int 81*8d1b35d0SSascha Wildner.Fn mtx_lock_ex_quick "mtx_t *mtx" "const char *ident" 82493c9781SSascha Wildner.Ft void 83*8d1b35d0SSascha Wildner.Fn mtx_lock "mtx_t *mtx" 84493c9781SSascha Wildner.Ft void 85*8d1b35d0SSascha Wildner.Fn mtx_spinlock "mtx_t *mtx" 86*8d1b35d0SSascha Wildner.Ft int 87*8d1b35d0SSascha Wildner.Fn mtx_lock_ex_try "mtx_t *mtx" 88*8d1b35d0SSascha Wildner.Ft int 89*8d1b35d0SSascha Wildner.Fn mtx_lock_sh_try "mtx_t *mtx" 90*8d1b35d0SSascha Wildner.Ft int 91*8d1b35d0SSascha Wildner.Fn mtx_spinlock_try "mtx_t *mtx" 92493c9781SSascha Wildner.Ft void 93*8d1b35d0SSascha Wildner.Fn mtx_downgrade "mtx_t *mtx" 94*8d1b35d0SSascha Wildner.Ft int 95*8d1b35d0SSascha Wildner.Fn mtx_upgrade_try "mtx_t *mtx" 96493c9781SSascha Wildner.Ft void 97*8d1b35d0SSascha Wildner.Fn mtx_unlock "mtx_t *mtx" 98dcece5c7SNuno Antunes.Ft void 99*8d1b35d0SSascha Wildner.Fn mtx_unlock_ex "mtx_t *mtx" 100493c9781SSascha Wildner.Ft void 101*8d1b35d0SSascha Wildner.Fn mtx_unlock_sh "mtx_t *mtx" 102*8d1b35d0SSascha Wildner.Ft void 103*8d1b35d0SSascha Wildner.Fn mtx_spinunlock "mtx_t *mtx" 104493c9781SSascha Wildner.Ft int 105*8d1b35d0SSascha Wildner.Fn mtx_islocked "mtx_t *mtx" 106*8d1b35d0SSascha Wildner.Ft int 107*8d1b35d0SSascha Wildner.Fn mtx_islocked_ex "mtx_t *mtx" 108*8d1b35d0SSascha Wildner.Ft int 109*8d1b35d0SSascha Wildner.Fn mtx_notlocked "mtx_t *mtx" 110*8d1b35d0SSascha Wildner.Ft int 111*8d1b35d0SSascha Wildner.Fn mtx_notlocked_ex "mtx_t *mtx" 112*8d1b35d0SSascha Wildner.Ft int 113*8d1b35d0SSascha Wildner.Fn mtx_owned "mtx_t *mtx" 114*8d1b35d0SSascha Wildner.Ft int 115*8d1b35d0SSascha Wildner.Fn mtx_notowned "mtx_t *mtx" 116*8d1b35d0SSascha Wildner.Ft int 117*8d1b35d0SSascha Wildner.Fn mtx_lockrefs "mtx_t *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. 171*8d1b35d0SSascha WildnerThe 172*8d1b35d0SSascha Wildner.Fn mtx_lock_sh 173*8d1b35d0SSascha Wildnerand 174*8d1b35d0SSascha Wildner.Fn mtx_lock_sh_quick 175*8d1b35d0SSascha Wildnerfunctions return 0 on success, or the 176*8d1b35d0SSascha Wildner.Fn tsleep 177*8d1b35d0SSascha Wildnerreturn code on failure. 178*8d1b35d0SSascha WildnerAn error can only be returned if 179*8d1b35d0SSascha Wildner.Dv PCATCH is specified in the flags. 180493c9781SSascha Wildner.Pp 181493c9781SSascha WildnerThe 182493c9781SSascha Wildner.Fn mtx_lock_ex 183493c9781SSascha Wildnerfunction attempts to lock a mutex exclusively and blocks the current thread 184493c9781SSascha Wildneruntil it is able to do so. 185493c9781SSascha WildnerThe 186493c9781SSascha Wildner.Fa ident 187dcece5c7SNuno Antunesand 188dcece5c7SNuno Antunes.Fa flags 189dcece5c7SNuno Antunesparameters are as in 190493c9781SSascha Wildner.Xr tsleep 9 . 191493c9781SSascha WildnerThe 192493c9781SSascha Wildner.Fa to 193493c9781SSascha Wildnerparameter is a timeout on the sleep. 194dcece5c7SNuno AntunesThe 195dcece5c7SNuno Antunes.Fn mtx_lock_ex_quick 1962315115fSSascha Wildnerfunction is a version of 197dcece5c7SNuno Antunes.Fn mtx_lock_ex 198dcece5c7SNuno Antuneswithout flags or a timeout. 199dcece5c7SNuno AntunesThe 200dcece5c7SNuno Antunes.Fn mtx_lock 201dcece5c7SNuno Antunesfunction is a yet shorter form for exclusively locking a mutex, blocking the 202dcece5c7SNuno Antunescurrent thread until acquired. 203*8d1b35d0SSascha WildnerIt is equivalent to 204*8d1b35d0SSascha Wildner.Fn mtx_lock_ex "mtx" \&"mtxex\&" "0" "0" . 205*8d1b35d0SSascha WildnerThe 206*8d1b35d0SSascha Wildner.Fn mtx_lock_ex 207*8d1b35d0SSascha Wildnerand 208*8d1b35d0SSascha Wildner.Fn mtx_lock_ex_quick 209*8d1b35d0SSascha Wildnerfunctions return 0 on success, or the 210*8d1b35d0SSascha Wildner.Fn tsleep 211*8d1b35d0SSascha Wildnerreturn code on failure. 212*8d1b35d0SSascha WildnerAn error can only be returned if 213*8d1b35d0SSascha Wildner.Dv PCATCH is specified in the flags. 214493c9781SSascha Wildner.Pp 215493c9781SSascha WildnerThe 216dcece5c7SNuno Antunes.Fn mtx_spinlock 217493c9781SSascha Wildnerfunction attempts to lock the mutex in exclusive mode and spins until it is 218493c9781SSascha Wildnerable to do so. 219493c9781SSascha Wildner.Pp 220493c9781SSascha WildnerThe 221493c9781SSascha Wildner.Fn mtx_lock_ex_try 222493c9781SSascha Wildnerand 223493c9781SSascha Wildner.Fn mtx_lock_sh_try 224493c9781SSascha Wildnerfunctions attempt to lock the mutex in exclusive or shared mode, respectively. 225493c9781SSascha WildnerIf they are not able to, they return 226493c9781SSascha Wildner.Er EAGAIN . 227dcece5c7SNuno AntunesThe 228dcece5c7SNuno Antunes.Fn mtx_spinlock_try 229dcece5c7SNuno Antunesfunction does the same but for spin mutexes. 230493c9781SSascha Wildner.Pp 231493c9781SSascha WildnerThe 232493c9781SSascha Wildner.Fn mtx_downgrade 233493c9781SSascha Wildnerfunction converts an exclusively held lock to a shared lock. 234493c9781SSascha WildnerThe lock must be held by the calling thread. 235493c9781SSascha WildnerIf the lock is already shared, this call is a no-op. 236493c9781SSascha Wildner.Pp 237493c9781SSascha WildnerThe 238493c9781SSascha Wildner.Fn mtx_upgrade_try 239dd7fb6d2SSascha Wildnerfunction attempts to convert a shared lock to an exclusive one. 240493c9781SSascha WildnerThe mutex must be held by the caller in the shared state. 241493c9781SSascha WildnerIf the upgrade is successful, this function returns 0; otherwise, it returns 242493c9781SSascha Wildner.Er EDEADLK . 243493c9781SSascha Wildner.Pp 244493c9781SSascha WildnerThe 245493c9781SSascha Wildner.Fn mtx_unlock 246493c9781SSascha Wildnerfunction releases a held mutex; 247493c9781SSascha Wildnerit works on both exclusive and shared mutexes. 248493c9781SSascha WildnerThe 249493c9781SSascha Wildner.Fn mtx_unlock_ex 250493c9781SSascha Wildnerand 251493c9781SSascha Wildner.Fn mtx_unlock_sh 252493c9781SSascha Wildnerfunctions are optimized unlock paths, used when it is known that a lock is held 253493c9781SSascha Wildnerexclusively or in shared state. 254493c9781SSascha Wildner.Pp 255493c9781SSascha WildnerThe 256dcece5c7SNuno Antunes.Fn mtx_spinunlock 257dcece5c7SNuno Antunesfunction releases a held spin mutex. 258dcece5c7SNuno Antunes.Pp 259dcece5c7SNuno AntunesThe 260493c9781SSascha Wildner.Fn mtx_islocked 261493c9781SSascha Wildnerfunction returns non-zero if the mutex is locked in either shared of 262493c9781SSascha Wildnerexclusive state by any thread. 263493c9781SSascha Wildner.Fn mtx_islocked_ex 264493c9781SSascha Wildnerreturns non-zero if the mutex is locked exclusively by any thread. 265493c9781SSascha WildnerThe 266493c9781SSascha Wildner.Fn mtx_notlocked 267493c9781SSascha Wildnerfunction returns non-zero if the mutex is not locked. 268493c9781SSascha WildnerThe 269493c9781SSascha Wildner.Fn mtx_owned 270493c9781SSascha Wildnerfunction returns non-zero if the mutex is exclusively locked by the calling 271493c9781SSascha Wildnerthread. 272493c9781SSascha WildnerThe 273493c9781SSascha Wildner.Fn mtx_notowned 274493c9781SSascha Wildnerfunction returns non-zero if the mutex is not exclusively locked by the 275493c9781SSascha Wildnercalling thread. 276493c9781SSascha WildnerThe 277493c9781SSascha Wildner.Fn mtx_lockrefs 278493c9781SSascha Wildnerfunction returns the number of shared or exclusive locks on the mutex. 279493c9781SSascha Wildner.Sh FILES 280b8e54b97SSascha WildnerThe uncontended path of the 281b8e54b97SSascha Wildner.Nm 282b8e54b97SSascha Wildnerimplementation is in 283493c9781SSascha Wildner.Pa /sys/sys/mutex2.h . 284493c9781SSascha WildnerThe data structures are in 285493c9781SSascha Wildner.Pa /sys/sys/mutex.h . 286493c9781SSascha WildnerThe core of the spinlock implementation is in 287493c9781SSascha Wildner.Pa /sys/kern/kern_mutex.c . 288493c9781SSascha Wildner.Sh SEE ALSO 289493c9781SSascha Wildner.Xr crit_enter 9 , 290c04308e8SMarkus Pfeiffer.Xr locking 9 , 291493c9781SSascha Wildner.Xr lockmgr 9 , 292493c9781SSascha Wildner.Xr serializer 9 , 293dcece5c7SNuno Antunes.Xr sleep 9 , 294493c9781SSascha Wildner.Xr spinlock 9 295493c9781SSascha Wildner.Sh HISTORY 296493c9781SSascha WildnerMutexes first appeared in 297493c9781SSascha Wildner.Dx 2.3 . 298493c9781SSascha Wildner.Sh AUTHORS 299493c9781SSascha Wildner.An -nosplit 300493c9781SSascha WildnerThe 301b8e54b97SSascha Wildner.Nm 302493c9781SSascha Wildnerimplementation was written by 303493c9781SSascha Wildner.An Matthew Dillon . 304