| __CPU_SIMPLE_LOCK(9) | Kernel Developer's Manual | __CPU_SIMPLE_LOCK(9) |
__cpu_simple_lock —
simple spin locks
#include
<sys/lock.h>
void
__cpu_simple_lock_init(__cpu_simple_lock_t
*lock);
#define __SIMPLELOCK_UNLOCKED ...
void
__cpu_simple_lock(__cpu_simple_lock_t
*lock);
int
__cpu_simple_lock_try(__cpu_simple_lock
*lock);
void
__cpu_simple_unlock(__cpu_simple_lock_t
*lock);
int
__SIMPLELOCK_LOCKED_P(__cpu_simple_lock
*lock);
/* obsolete and for ABI compat only -- do not use
*/
void
__cpu_simple_lock_set(__cpu_simple_Lock
*lock);
void
__cpu_simple_lock_clear(__cpu_simple_lock
*lock);
int
__SIMPLELOCK_UNLOCKED_P(__cpu_simple_lock
*lock);
The __cpu_simple_lock functions provide a
simple spin-lock facility for limited purposes that cannot be served by
mutex(9), such as inside the
implementation of mutex(9)
itself on platforms with limited atomic read/modify/write operations.
__cpu_simple_lock is very limited:
__cpu_simple_lock provides no debugging or
diagnostic support through the LOCKDEBUG
option.__cpu_simple_lock does not synchronize between
code on a CPU and interrupt handlers running on that CPU — you must
use it with spl(9) for any
locks that may be taken in interrupt context; failing to do so will likely
lead to hard-to-debug deadlock.__cpu_simple_lock does not block preemption, so a
thread holding a lock may be preempted, potentially requiring other
callers to spin for long durations until the scheduler runs the holder
again.__cpu_simple_lock does no exponential backoff to
reduce memory traffic during contention.Unless you know what you are doing, you should use mutex(9) instead.
The macro __SIMPLELOCK_UNLOCKED expands to
an initializer for the type __cpu_simple_lock_t:
__cpu_simple_lock_t lock =
__SIMPLELOCK_UNLOCKED;A
__cpu_simple_lock_t object can also be initialized
with
__cpu_simple_lock_init().
No actions are needed to destroy a __cpu_simple_lock_t object.
__cpu_simple_lock_init(lock)__cpu_simple_lock functions.
The caller is responsible for
ensuring
__cpu_simple_lock_init()
happens before any use of the other functions.
__cpu_simple_lock_init() implies no particular
memory ordering on its own.
__cpu_simple_lock(lock)Any memory operations preceding the
previous
__cpu_simple_unlock()
call that released the lock happen before any memory operations after
the next
__cpu_simple_lock()
call that acquires it.
__cpu_simple_lock_try(lock)Any memory operations preceding the
previous
__cpu_simple_unlock()
call that released the lock happen before any memory operations after
the next
successful
__cpu_simple_lock_try() call that acquires
it.
__cpu_simple_unlock(lock)Any memory operations preceding
__cpu_simple_unlock()
happen before the next call to
__cpu_simple_lock(),
or the next successful call to
__cpu_simple_lock_try(), that acquires
lock.
__SIMPLELOCK_LOCKED_P(lock)This is normally only used for
diagnostic assertions, or for loops around
__cpu_simple_lock_try()
that also have higher-level functions like blocking interrupts and
performing exponential backoff.
No memory ordering is implied.
The following functions abuse the
__cpu_simple_lock_t type to store a boolean. They are
used inside the pthread(3)
library, and were included in the library ABI, so they can't be removed
without breaking the
pthread(3) ABI. Do not use
these in new code (except
__SIMPLELOCK_LOCKED_P()).
__cpu_simple_lock_set(lock)__cpu_simple_lock_clear(lock)__SIMPLELOCK_LOCKED_P(lock)__SIMPLELOCK_UNLOCKED_P(lock)The __cpu_simple_lock functions are
implemented in sys/arch/$ARCH/include/lock.h.
A machine-independent implementation, using compiler support for atomic and memory barrier builtins, is available in sys/sys/common_lock.h.
__cpu_simple_lock appeared a long time
ago.
| October 25, 2024 | NetBSD 11.0 |