10#include <kernel/types.h>
12#ifdef CONFIG_SPINLOCK_DEBUG
13#include <kernel/logger.h>
17#include <utils/compiler.h>
18#include <utils/macro.h>
23#define SPINLOCK_DEBUG_STALL_TIMEOUT MS(30)
38#define __SPINLOCK_INIT \
42#define SPINLOCK_INIT ((spinlock_t)__SPINLOCK_INIT)
45#define __INIT_SPINLOCK(_lock) _lock = __SPINLOCK_INIT
46#define INIT_SPINLOCK(_lock) _lock = SPINLOCK_INIT
49#define DECLARE_SPINLOCK(_lock) spinlock_t _lock = SPINLOCK_INIT
51#ifdef CONFIG_SPINLOCK_DEBUG
59 while (__atomic_test_and_set(&lock->locked, __ATOMIC_ACQUIRE)) {
60 if (
timer_get_ms() - start > SPINLOCK_DEBUG_STALL_TIMEOUT) {
61 WARN(
"stall detected on spinlock (owner: %ps)",
80 WAIT_FOR(!__atomic_test_and_set(&lock->locked, __ATOMIC_ACQUIRE));
87#define spinlock_acquire(lock) __spinlock_acquire(lock, __THIS_IP)
92 __atomic_clear(&lock->locked, __ATOMIC_RELEASE);
100static inline scope_lock_t scope_lock_constructor(
spinlock_t *lock)
102 return (scope_lock_t){
108static inline void scope_lock_destructor(scope_lock_t *guard)
129#define locked_scope(_lock) \
130 for (scope_lock_t guard CLEANUP(scope_lock_destructor) = \
131 scope_lock_constructor(_lock); \
132 !guard.done; guard.done = true)
static ALWAYS_INLINE spinlock_t * __spinlock_acquire(spinlock_t *lock, vaddr_t owner)
Try to acquire a spinlock, or wait until it is free.
Definition: spinlock.h:76
static ALWAYS_INLINE void spinlock_release(spinlock_t *lock)
Release a spinlock for others to take it.
Definition: spinlock.h:90
static time_t timer_get_ms(void)
Definition: timer.h:77
#define WAIT_FOR(_cond)
Loop infinitely while the condition _cond is not met.
Definition: macro.h:15
#define UNUSED(_x)
Avoid compiler warning when not using a symbol.
Definition: macro.h:35
Spinlock.
Definition: spinlock.h:29