12#ifndef ZEPHYR_INCLUDE_SPINLOCK_H_
13#define ZEPHYR_INCLUDE_SPINLOCK_H_
34struct z_spinlock_key {
50#ifdef CONFIG_TICKET_SPINLOCKS
69#ifdef CONFIG_SPIN_VALIDATE
74#ifdef CONFIG_SPIN_LOCK_TIME_LIMIT
81#if defined(CONFIG_NONZERO_SPINLOCK_SIZE) && !defined(CONFIG_SMP) && !defined(CONFIG_SPIN_VALIDATE)
103#ifdef CONFIG_SPIN_VALIDATE
105bool z_spin_unlock_valid(
struct k_spinlock *l);
106void z_spin_lock_set_owner(
struct k_spinlock *l);
107void z_spin_lock_transfer_owner(
struct k_spinlock *l);
108void z_assert_can_swap(
unsigned int key,
struct k_spinlock *swap_lock);
109void z_spin_validate_reset(
bool lock_held);
110extern const uint8_t z_spinlock_abort_sentinel;
114#if defined(CONFIG_64BIT)
115BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 8,
"Too many CPUs for mask");
117BUILD_ASSERT(CONFIG_MP_MAX_NUM_CPUS <= 4,
"Too many CPUs for mask");
120# ifdef CONFIG_KERNEL_COHERENCE
121bool z_spin_lock_mem_coherent(
struct k_spinlock *l);
139static ALWAYS_INLINE
void z_spinlock_validate_pre(
struct k_spinlock *l)
142#ifdef CONFIG_SPIN_VALIDATE
143 __ASSERT(z_spin_lock_valid(l),
"Invalid spinlock %p", l);
144#ifdef CONFIG_KERNEL_COHERENCE
145 __ASSERT_NO_MSG(z_spin_lock_mem_coherent(l));
150static ALWAYS_INLINE
void z_spinlock_validate_post(
struct k_spinlock *l)
153#ifdef CONFIG_SPIN_VALIDATE
154 z_spin_lock_set_owner(l);
155#if defined(CONFIG_SPIN_LOCK_TIME_LIMIT) && (CONFIG_SPIN_LOCK_TIME_LIMIT != 0)
203 z_spinlock_validate_pre(l);
205#ifdef CONFIG_TICKET_SPINLOCKS
223 z_spinlock_validate_post(l);
246 z_spinlock_validate_pre(l);
248#ifdef CONFIG_TICKET_SPINLOCKS
269 if (!
atomic_cas(&l->tail, ticket_val, ticket_val + 1)) {
278 z_spinlock_validate_post(l);
316#ifdef CONFIG_SPIN_VALIDATE
317 __ASSERT(z_spin_unlock_valid(l),
"Not my spinlock %p", l);
319#if defined(CONFIG_SPIN_LOCK_TIME_LIMIT) && (CONFIG_SPIN_LOCK_TIME_LIMIT != 0)
322 __ASSERT(delta < CONFIG_SPIN_LOCK_TIME_LIMIT,
323 "Spin lock %p held %u cycles, longer than limit of %u cycles",
324 l, delta, CONFIG_SPIN_LOCK_TIME_LIMIT);
329#ifdef CONFIG_TICKET_SPINLOCKS
350#if defined(CONFIG_TEST) || defined(CONFIG_ASSERT)
359static ALWAYS_INLINE
bool z_spin_is_locked(
struct k_spinlock *l)
362#ifdef CONFIG_TICKET_SPINLOCKS
365 return !
atomic_cas(&l->tail, ticket_val, ticket_val);
378static ALWAYS_INLINE
void k_spin_release(
struct k_spinlock *l)
381#ifdef CONFIG_SPIN_VALIDATE
382 __ASSERT(z_spin_unlock_valid(l),
"Not my spinlock %p", l);
385#ifdef CONFIG_TICKET_SPINLOCKS
393#if defined(CONFIG_SPIN_VALIDATE) && defined(__GNUC__)
396 __ASSERT(k->key,
"K_SPINLOCK exited with goto, break or return, "
397 "use K_SPINLOCK_BREAK instead.");
399#define K_SPINLOCK_ONEXIT __attribute__((__cleanup__(z_spin_onexit)))
401#define K_SPINLOCK_ONEXIT
414#define K_SPINLOCK_BREAK continue
457#define K_SPINLOCK(lck) \
458 for (k_spinlock_key_t __i K_SPINLOCK_ONEXIT = {}, __key = k_spin_lock(lck); !__i.key; \
459 k_spin_unlock((lck), __key), __i.key = 1)
void arch_spin_relax(void)
Perform architecture specific processing within spin loops.
Header file for the Atomic operations API.
static unsigned int arch_irq_lock(void)
Lock interrupts on the current CPU.
static void arch_irq_unlock(unsigned int key)
Unlock interrupts on the current CPU.
static bool arch_cpu_irqs_are_enabled(void)
Probe the current CPU overall interrupt controller lock state without modifying it.
long atomic_t
Atomic integer variable.
Definition atomic_types.h:31
atomic_t atomic_val_t
Value type for atomic integer variables.
Definition atomic_types.h:38
atomic_val_t atomic_get(const atomic_t *target)
Atomic get.
atomic_val_t atomic_clear(atomic_t *target)
Atomic clear.
atomic_val_t atomic_inc(atomic_t *target)
Atomic increment.
bool atomic_cas(atomic_t *target, atomic_val_t old_value, atomic_val_t new_value)
Atomic compare-and-set.
uint32_t sys_clock_cycle_get_32(void)
Hardware cycle counter.
static ALWAYS_INLINE int k_spin_trylock(struct k_spinlock *l, k_spinlock_key_t *k)
Attempt to lock a spinlock.
Definition spinlock.h:242
static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l, k_spinlock_key_t key)
Unlock a spin lock.
Definition spinlock.h:312
static ALWAYS_INLINE k_spinlock_key_t k_spin_lock(struct k_spinlock *l)
Lock a spinlock.
Definition spinlock.h:192
struct z_spinlock_key k_spinlock_key_t
Spinlock key type.
Definition spinlock.h:137
#define EBUSY
Mount device busy.
Definition errno.h:54
__UINT32_TYPE__ uint32_t
Definition stdint.h:90
__UINT8_TYPE__ uint8_t
Definition stdint.h:88
__UINTPTR_TYPE__ uintptr_t
Definition stdint.h:105
Kernel Spin Lock.
Definition spinlock.h:45