123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- #ifndef ZEPHYR_INCLUDE_SPINLOCK_H_
- #define ZEPHYR_INCLUDE_SPINLOCK_H_
- #include <sys/atomic.h>
- #include <sys/__assert.h>
- #include <stdbool.h>
- #include <arch/cpu.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- struct z_spinlock_key {
- int key;
- };
- struct k_spinlock {
- #ifdef CONFIG_SMP
- atomic_t locked;
- #endif
- #ifdef CONFIG_SPIN_VALIDATE
-
- uintptr_t thread_cpu;
- #endif
- #if !defined(CONFIG_SMP) && !defined(CONFIG_SPIN_VALIDATE)
-
- char dummy;
- #endif
- };
- #ifdef CONFIG_SPIN_VALIDATE
- bool z_spin_lock_valid(struct k_spinlock *l);
- bool z_spin_unlock_valid(struct k_spinlock *l);
- void z_spin_lock_set_owner(struct k_spinlock *l);
- BUILD_ASSERT(CONFIG_MP_NUM_CPUS <= 4, "Too many CPUs for mask");
- # ifdef CONFIG_KERNEL_COHERENCE
- bool z_spin_lock_mem_coherent(struct k_spinlock *l);
- # endif
- #endif
- typedef struct z_spinlock_key k_spinlock_key_t;
- static ALWAYS_INLINE k_spinlock_key_t k_spin_lock(struct k_spinlock *l)
- {
- ARG_UNUSED(l);
- k_spinlock_key_t k;
-
- k.key = arch_irq_lock();
- #ifdef CONFIG_SPIN_VALIDATE
- __ASSERT(z_spin_lock_valid(l), "Recursive spinlock %p", l);
- # ifdef CONFIG_KERNEL_COHERENCE
- __ASSERT_NO_MSG(z_spin_lock_mem_coherent(l));
- # endif
- #endif
- #ifdef CONFIG_SMP
- while (!atomic_cas(&l->locked, 0, 1)) {
- }
- #endif
- #ifdef CONFIG_SPIN_VALIDATE
- z_spin_lock_set_owner(l);
- #endif
- return k;
- }
- static ALWAYS_INLINE void k_spin_unlock(struct k_spinlock *l,
- k_spinlock_key_t key)
- {
- ARG_UNUSED(l);
- #ifdef CONFIG_SPIN_VALIDATE
- __ASSERT(z_spin_unlock_valid(l), "Not my spinlock %p", l);
- #endif
- #ifdef CONFIG_SMP
-
- atomic_clear(&l->locked);
- #endif
- arch_irq_unlock(key.key);
- }
- static ALWAYS_INLINE void k_spin_release(struct k_spinlock *l)
- {
- ARG_UNUSED(l);
- #ifdef CONFIG_SPIN_VALIDATE
- __ASSERT(z_spin_unlock_valid(l), "Not my spinlock %p", l);
- #endif
- #ifdef CONFIG_SMP
- atomic_clear(&l->locked);
- #endif
- }
- #ifdef __cplusplus
- }
- #endif
- #endif
|