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.\" 315b77ed3bSTomohiro Kusumi.Dd February 14, 2019 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 , 398d1b35d0SSascha Wildner.\".Nm mtx_lock_sh_link , 40493c9781SSascha Wildner.Nm mtx_lock_sh_quick , 41493c9781SSascha Wildner.Nm mtx_lock_ex , 428d1b35d0SSascha 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 , 618d1b35d0SSascha 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 676700dd34SSascha Wildner.Fn mtx_init "mtx_t *mtx" "const char *ident" 68493c9781SSascha Wildner.Ft void 698d1b35d0SSascha Wildner.Fn mtx_uninit "mtx_t *mtx" 70493c9781SSascha Wildner.Ft int 71db335ff8SSascha Wildner.Fn mtx_lock_sh "mtx_t *mtx" "int flags" "int to" 728d1b35d0SSascha Wildner.\".Ft int 73db335ff8SSascha Wildner.\".Fn mtx_lock_sh_link "mtx_t *mtx" "mtx_link_t *link" "int flags" "int to" 74493c9781SSascha Wildner.Ft int 75db335ff8SSascha Wildner.Fn mtx_lock_sh_quick "mtx_t *mtx" 76dcece5c7SNuno Antunes.Ft int 77db335ff8SSascha Wildner.Fn mtx_lock_ex "mtx_t *mtx" "int flags" "int to" 788d1b35d0SSascha Wildner.\".Ft int 79db335ff8SSascha Wildner.\".Fn mtx_lock_ex_link "mtx_t *mtx" "mtx_link_t *link" "int flags" "int to" 808d1b35d0SSascha Wildner.Ft int 81db335ff8SSascha Wildner.Fn mtx_lock_ex_quick "mtx_t *mtx" 82493c9781SSascha Wildner.Ft void 838d1b35d0SSascha Wildner.Fn mtx_lock "mtx_t *mtx" 84493c9781SSascha Wildner.Ft void 858d1b35d0SSascha Wildner.Fn mtx_spinlock "mtx_t *mtx" 868d1b35d0SSascha Wildner.Ft int 878d1b35d0SSascha Wildner.Fn mtx_lock_ex_try "mtx_t *mtx" 888d1b35d0SSascha Wildner.Ft int 898d1b35d0SSascha Wildner.Fn mtx_lock_sh_try "mtx_t *mtx" 908d1b35d0SSascha Wildner.Ft int 918d1b35d0SSascha Wildner.Fn mtx_spinlock_try "mtx_t *mtx" 92493c9781SSascha Wildner.Ft void 938d1b35d0SSascha Wildner.Fn mtx_downgrade "mtx_t *mtx" 948d1b35d0SSascha Wildner.Ft int 958d1b35d0SSascha Wildner.Fn mtx_upgrade_try "mtx_t *mtx" 96493c9781SSascha Wildner.Ft void 978d1b35d0SSascha Wildner.Fn mtx_unlock "mtx_t *mtx" 98dcece5c7SNuno Antunes.Ft void 998d1b35d0SSascha Wildner.Fn mtx_unlock_ex "mtx_t *mtx" 100493c9781SSascha Wildner.Ft void 1018d1b35d0SSascha Wildner.Fn mtx_unlock_sh "mtx_t *mtx" 1028d1b35d0SSascha Wildner.Ft void 1038d1b35d0SSascha Wildner.Fn mtx_spinunlock "mtx_t *mtx" 104493c9781SSascha Wildner.Ft int 1058d1b35d0SSascha Wildner.Fn mtx_islocked "mtx_t *mtx" 1068d1b35d0SSascha Wildner.Ft int 1078d1b35d0SSascha Wildner.Fn mtx_islocked_ex "mtx_t *mtx" 1088d1b35d0SSascha Wildner.Ft int 1098d1b35d0SSascha Wildner.Fn mtx_notlocked "mtx_t *mtx" 1108d1b35d0SSascha Wildner.Ft int 1118d1b35d0SSascha Wildner.Fn mtx_notlocked_ex "mtx_t *mtx" 1128d1b35d0SSascha Wildner.Ft int 1138d1b35d0SSascha Wildner.Fn mtx_owned "mtx_t *mtx" 1148d1b35d0SSascha Wildner.Ft int 1158d1b35d0SSascha Wildner.Fn mtx_notowned "mtx_t *mtx" 1168d1b35d0SSascha Wildner.Ft int 1178d1b35d0SSascha 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. 145db335ff8SSascha WildnerThe 146db335ff8SSascha Wildner.Fa ident 147db335ff8SSascha Wildnerparameter is as in 148db335ff8SSascha Wildner.Xr tsleep 9 , 149db335ff8SSascha Wildnerit is a string describing the reason for a thread to be blocked. 150493c9781SSascha Wildner.Pp 151493c9781SSascha WildnerThe 152493c9781SSascha Wildner.Fn mtx_uninit 153493c9781SSascha Wildnerfunction deinitializes a mutex. 154493c9781SSascha Wildner.Pp 155493c9781SSascha WildnerThe 156493c9781SSascha Wildner.Fn mtx_lock_sh 157493c9781SSascha Wildnerfunction attempts to lock a mutex in shared mode and blocks the current 158493c9781SSascha Wildnerthread until it is able to do so. 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. 1718d1b35d0SSascha WildnerThe 1728d1b35d0SSascha Wildner.Fn mtx_lock_sh 1738d1b35d0SSascha Wildnerand 1748d1b35d0SSascha Wildner.Fn mtx_lock_sh_quick 1758d1b35d0SSascha Wildnerfunctions return 0 on success, or the 1768d1b35d0SSascha Wildner.Fn tsleep 1778d1b35d0SSascha Wildnerreturn code on failure. 1788d1b35d0SSascha WildnerAn error can only be returned if 179db335ff8SSascha Wildner.Dv PCATCH 180db335ff8SSascha Wildneris specified in the flags. 181493c9781SSascha Wildner.Pp 182493c9781SSascha WildnerThe 183493c9781SSascha Wildner.Fn mtx_lock_ex 184493c9781SSascha Wildnerfunction attempts to lock a mutex exclusively and blocks the current thread 185493c9781SSascha Wildneruntil it is able to do so. 186493c9781SSascha WildnerThe 187dcece5c7SNuno Antunes.Fa flags 188db335ff8SSascha Wildnerparameter is as in 189493c9781SSascha Wildner.Xr tsleep 9 . 190493c9781SSascha WildnerThe 191493c9781SSascha Wildner.Fa to 192493c9781SSascha Wildnerparameter is a timeout on the sleep. 193dcece5c7SNuno AntunesThe 194dcece5c7SNuno Antunes.Fn mtx_lock_ex_quick 1952315115fSSascha Wildnerfunction is a version of 196dcece5c7SNuno Antunes.Fn mtx_lock_ex 197dcece5c7SNuno Antuneswithout flags or a timeout. 198dcece5c7SNuno AntunesThe 199dcece5c7SNuno Antunes.Fn mtx_lock 200dcece5c7SNuno Antunesfunction is a yet shorter form for exclusively locking a mutex, blocking the 201dcece5c7SNuno Antunescurrent thread until acquired. 2028d1b35d0SSascha WildnerIt is equivalent to 2035b77ed3bSTomohiro Kusumi.Fn mtx_lock_ex "mtx" "0" "0" . 2048d1b35d0SSascha WildnerThe 2058d1b35d0SSascha Wildner.Fn mtx_lock_ex 2068d1b35d0SSascha Wildnerand 2078d1b35d0SSascha Wildner.Fn mtx_lock_ex_quick 2088d1b35d0SSascha Wildnerfunctions return 0 on success, or the 2098d1b35d0SSascha Wildner.Fn tsleep 2108d1b35d0SSascha Wildnerreturn code on failure. 2118d1b35d0SSascha WildnerAn error can only be returned if 212*081e4509SSascha Wildner.Dv PCATCH 213*081e4509SSascha Wildneris 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