DragonFly On-Line Manual Pages
SPINLOCK(9) DragonFly Kernel Developer's Manual SPINLOCK(9)
spin_init, spin_lock, spin_lock_quick, spin_trylock, spin_uninit,
spin_unlock, spin_unlock_quick -- core spinlocks
spin_init(struct spinlock *mtx, const char *descr);
spin_uninit(struct spinlock *mtx);
spin_lock(struct spinlock *mtx);
spin_lock_quick(globaldata_t gd, struct spinlock *mtx);
spin_trylock(struct spinlock *mtx);
spin_unlock(struct spinlock *mtx);
spin_unlock_quick(globaldata_t gd, struct spinlock *mtx);
The spinlock structure and call API are defined in the <sys/spinlock.h>
and <sys/spinlock2.h> header files, respectively.
The spin_init() function initializes a new spinlock structure for use.
An initializer macro, SPINLOCK_INITIALIZER, is provided as well, taking
the same arguments as spin_init(). The structure is cleaned up with
spin_uninit() when it is no longer needed.
The spin_lock() function obtains an exclusive read-write spinlock. A
thread may hold any number of exclusive spinlocks but should always be
mindful of ordering deadlocks. The spin_trylock() function will return
TRUE if the spinlock was successfully obtained and FALSE if it wasn't.
If you have the current CPU's globaldata pointer in hand you can call
spin_lock_quick(), but most code will just call the normal version. A
spinlock used only for exclusive access has about the same overhead as a
mutex based on a locked bus cycle.
A previously obtained exclusive spinlock is released by calling either
spin_unlock() or spin_unlock_quick().
A thread may not hold any spinlock across a blocking condition or thread
switch. LWKT tokens should be used for situations where you want an
exclusive run-time lock that will survive a blocking condition or thread
switch. Tokens will be automatically unlocked when a thread switches
away and relocked when the thread is switched back in. If you want a
lock that survives a blocking condition or thread switch without being
released, use lockmgr(9) locks or LWKT reader/writer locks.
DragonFly's core spinlocks should only be used around small contained
sections of code. For example, to manage a reference count or to
implement higher level locking mechanisms. Both the token code and the
lockmgr(9) code use exclusive spinlocks internally. Core spinlocks
should not be used around large chunks of code.
Holding one or more spinlocks will disable thread preemption by another
thread (e.g. preemption by an interrupt thread), and will prevent FAST
interrupts or IPIs from running. This means that a FAST interrupt, IPI
and any threaded interrupt (which is basically all interrupts except the
clock interrupt) will still be scheduled for later execution, but will
not be able to preempt the current thread.
A thread may hold any number of exclusive read-write spinlocks.
Spinlocks spin. A thread will not block, switch away, or lose its
critical section while obtaining or releasing a spinlock. Spinlocks do
not use IPIs or other mechanisms. They are considered to be a very low
If a spinlock can not be obtained after one second a warning will be
printed on the console. If a system panic occurs, spinlocks will succeed
after one second in order to allow the panic operation to proceed.
If you have a complex structure such as a vnode(9) which contains a token
or lockmgr(9) lock, it is legal to directly access the internal spinlock
embedded in those structures for other purposes as long as the spinlock
is not held when you issue the token or lockmgr(9) operation.
The uncontended path of the spinlock implementation is in
/sys/sys/spinlock2.h. The core of the spinlock implementation is in
crit_enter(9), locking(9), lockmgr(9), serializer(9)
A spinlock implementation first appeared in DragonFly 1.3.
The original spinlock implementation was written by Jeffrey M. Hsu and
was later extended by Matthew Dillon. This manual page was written by
Matthew Dillon and Sascha Wildner.
DragonFly 5.5 May 29, 2017 DragonFly 5.5