1.\" 2.\" Copyright (c) 2006 The DragonFly Project. All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 8.\" 1. Redistributions of source code must retain the above copyright 9.\" notice, this list of conditions and the following disclaimer. 10.\" 2. Redistributions in binary form must reproduce the above copyright 11.\" notice, this list of conditions and the following disclaimer in 12.\" the documentation and/or other materials provided with the 13.\" distribution. 14.\" 3. Neither the name of The DragonFly Project nor the names of its 15.\" contributors may be used to endorse or promote products derived 16.\" from this software without specific, prior written permission. 17.\" 18.\" THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20.\" LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21.\" FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22.\" COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23.\" INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 24.\" BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25.\" LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 26.\" AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 27.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 28.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29.\" SUCH DAMAGE. 30.\" 31.Dd August 30, 2010 32.Os 33.Dt SPINLOCK 9 34.Sh NAME 35.Nm spin_init , 36.Nm spin_lock , 37.Nm spin_lock_quick , 38.Nm spin_trylock , 39.Nm spin_uninit , 40.Nm spin_unlock , 41.Nm spin_unlock_quick 42.Nd core spinlocks 43.Sh SYNOPSIS 44.In sys/spinlock.h 45.In sys/spinlock2.h 46.Ft void 47.Fn spin_init "struct spinlock *mtx" 48.Ft void 49.Fn spin_uninit "struct spinlock *mtx" 50.Ft void 51.Fn spin_lock "struct spinlock *mtx" 52.Ft void 53.Fn spin_lock_quick "globaldata_t gd" "struct spinlock *mtx" 54.Ft boolean_t 55.Fn spin_trylock "struct spinlock *mtx" 56.Ft void 57.Fn spin_unlock "struct spinlock *mtx" 58.Ft void 59.Fn spin_unlock_quick "globaldata_t gd" "struct spinlock *mtx" 60.Sh DESCRIPTION 61The 62.Fa spinlock 63structure and call API are defined in the 64.In sys/spinlock.h 65and 66.In sys/spinlock2.h 67header files, respectively. 68.Pp 69The 70.Fn spin_init 71function initializes a new 72.Fa spinlock 73structure for use. 74The structure is cleaned up with 75.Fn spin_uninit 76when it is no longer needed. 77.Pp 78The 79.Fn spin_lock 80function obtains an exclusive 81.Em read-write 82spinlock. 83A thread may hold any number of exclusive spinlocks but should always 84be mindful of ordering deadlocks. 85The 86.Fn spin_trylock 87function will return 88.Dv TRUE 89if the spinlock was successfully obtained and 90.Dv FALSE 91if it wasn't. 92If you have the current CPU's 93.Fa globaldata 94pointer in hand you can call 95.Fn spin_lock_quick , 96but most code will just call the normal version. 97A spinlock used only for exclusive access has about the same overhead 98as a mutex based on a locked bus cycle. 99.Pp 100A previously obtained exclusive spinlock is released by calling either 101.Fn spin_unlock 102or 103.Fn spin_unlock_quick . 104.Sh IMPLEMENTATION NOTES 105A thread may not hold any spinlock across a blocking condition or 106thread switch. 107LWKT tokens should be used for situations where you want an exclusive 108run-time lock that will survive a blocking condition or thread switch. 109Tokens will be automatically unlocked when a thread switches away and 110relocked when the thread is switched back in. 111If you want a lock that survives a blocking condition or thread switch 112without being released, use 113.Xr lockmgr 9 114locks or LWKT reader/writer locks. 115.Pp 116.Dx Ap s 117core spinlocks should only be used around small contained sections of 118code. 119For example, to manage a reference count or to implement higher level 120locking mechanisms. 121Both the token code and the 122.Xr lockmgr 9 123code use exclusive spinlocks internally. 124Core spinlocks should not be used around large chunks of code. 125.Pp 126Holding one or more spinlocks will disable thread preemption by 127another thread (e.g. preemption by an interrupt thread), but will not 128disable FAST interrupts or IPIs. 129This means that a FAST interrupt can still operate during a spinlock, 130and any threaded interrupt (which is basically all interrupts except 131the clock interrupt) will still be scheduled for later execution, but 132will not be able to preempt the current thread. 133If you wish to disable FAST interrupts and IPIs you need to enter a 134critical section prior to obtaining the spinlock. 135.Pp 136Currently, FAST interrupts, including IPI messages, are not allowed to 137acquire any spinlocks. 138It is possible to work around this if 139.Va mycpu->gd_spinlocks_wr 140is 0. 141If one 142or the other is not zero, the FAST interrupt or IPI cannot acquire 143any spinlocks without risking a deadlock, even if the spinlocks in 144question are not related. 145.Pp 146A thread may hold any number of exclusive 147.Em read-write 148spinlocks. 149.Pp 150Spinlocks spin. 151A thread will not block, switch away, or lose its critical section 152while obtaining or releasing a spinlock. 153Spinlocks do not use IPIs or other mechanisms. 154They are considered to be a very low level mechanism. 155.Pp 156If a spinlock can not be obtained after one second a warning will be 157printed on the console. 158If a system panic occurs, spinlocks will succeed after one second in 159order to allow the panic operation to proceed. 160.Pp 161If you have a complex structure such as a 162.Xr vnode 9 163which contains a token or 164.Xr lockmgr 9 165lock, it is legal to directly access the internal spinlock embedded 166in those structures for other purposes as long as the spinlock is not 167held when you issue the token or 168.Xr lockmgr 9 169operation. 170.Sh FILES 171The uncontended path of the spinlock implementation is in 172.Pa /sys/sys/spinlock2.h . 173The core of the spinlock implementation is in 174.Pa /sys/kern/kern_spinlock.c . 175.Sh SEE ALSO 176.Xr crit_enter 9 , 177.Xr lockmgr 9 , 178.Xr serializer 9 179.Sh HISTORY 180A 181.Nm spinlock 182implementation first appeared in 183.Dx 1.3 . 184.Sh AUTHORS 185.An -nosplit 186The original 187.Nm spinlock 188implementation was written by 189.An Jeffrey M. Hsu 190and was later extended by 191.An Matthew Dillon . 192This manual page was written by 193.An Matthew Dillon 194and 195.An Sascha Wildner . 196