include/sync/qspinlock.h View source View on GitHub
struct qspinlock {
_Atomic uint32_t val;
};
enum qspinlock_level {
QSPINLOCK_LEVEL_NORMAL,
QSPINLOCK_LEVEL_IRQ,
QSPINLOCK_LEVEL_NMI,
QSPINLOCK_LEVEL_MAX,
};
void qspinlock_init_chk_internal(struct qspinlock *lock, const struct lock_chk_class *class, enum lock_chk_flags flags);
bool qspin_is_locked(const struct qspinlock *lock);
void qspinlock_policy_init_internal(struct qspinlock *lock, enum lock_chk_flags flags);
void qspinlock_map_init_internal(struct qspinlock *lock, const struct lock_chk_class *class, enum lock_chk_flags flags);
void qspinlock_shallow_init_internal(struct qspinlock *lock);
void qspinlock_set_chk_flags(struct qspinlock *lock, enum lock_chk_flags flags);
void qspinlock_reinit_chk(struct qspinlock *lock, const struct lock_chk_class *class, enum lock_chk_flags flags);
void qspinlock_note_use(struct qspinlock *lock, bool raw_operation);
bool qspinlock_order_checked(struct qspinlock *lock);
void qspinlock_classify(struct qspinlock *lock, enum lock_debug_irq_usage usage, const struct lock_chk_site *site);
bool qspinlock_deep_checked(struct qspinlock *lock);
struct lock_chk_acquire_request qspinlock_chk_acquire_request(struct qspinlock *lock, const struct lock_chk_site *site, enum lock_chk_wait_kind wait_kind, uint8_t subclass, bool raw_operation, bool irq_safe);
struct lock_chk_release_request qspinlock_chk_release_request(struct qspinlock *lock, const struct lock_chk_site *site);
void qspinlock_policy_init_internal(struct qspinlock *lock, enum lock_chk_flags flags);
void qspinlock_map_init_internal(struct qspinlock *lock, const struct lock_chk_class *class, enum lock_chk_flags flags);
void qspinlock_shallow_init_internal(struct qspinlock *lock);
void qspinlock_set_chk_flags(struct qspinlock *lock, enum lock_chk_flags flags);
void qspinlock_reinit_chk(struct qspinlock *lock, const struct lock_chk_class *class, enum lock_chk_flags flags);
void qspinlock_note_use(struct qspinlock *lock, bool raw_operation);
bool qspinlock_order_checked(struct qspinlock *lock);
void qspinlock_classify(struct qspinlock *lock, enum lock_debug_irq_usage usage, const struct lock_chk_site *site);
bool qspinlock_deep_checked(struct qspinlock *lock);
void qspinlock_init_chk_internal(struct qspinlock *lock, const struct lock_chk_class *class, enum lock_chk_flags flags);
bool qspin_trylock_physical(struct qspinlock *lock);
void qspin_lock_slowpath(struct qspinlock *lock, uint32_t val);
void qspin_lock_physical(struct qspinlock *lock);
void qspin_unlock_physical(struct qspinlock *lock);
bool qspin_is_locked(const struct qspinlock *lock);
bool qspin_trylock_raw_internal(struct qspinlock *lock, const struct lock_chk_site *site);
void qspin_lock_raw_internal(struct qspinlock *lock, const struct lock_chk_site *site);
void qspin_unlock_raw_internal(struct qspinlock *lock, const struct lock_chk_site *site);
void qspin_unlock_internal(struct qspinlock *lock, enum irql old_irql, const struct lock_chk_site *site);
enum irql qspin_lock_subclass_internal(struct qspinlock *lock, uint8_t subclass, const struct lock_chk_site *site);
enum irql qspin_lock_internal(struct qspinlock *lock, const struct lock_chk_site *site);
enum irql qspin_lock_irq_disable_internal(struct qspinlock *lock, const struct lock_chk_site *site);
bool qspin_trylock_internal(struct qspinlock *lock, enum irql *out, const struct lock_chk_site *site);
bool qspin_trylock_irq_disable_internal(struct qspinlock *lock, enum irql *out, const struct lock_chk_site *site);
void qspin_assert_held_internal(struct qspinlock *lock, const struct lock_chk_site *site);
void qspin_assert_not_held_internal(struct qspinlock *lock, const struct lock_chk_site *site);
#define Q_SPIN_LOCKED_OFFSET 0
#define Q_SPIN_LOCKED_BITS 8
#define Q_SPIN_LOCKED_MASK 0x000000FFU
#define Q_SPIN_LOCKED_VAL 0x00000001U
#define Q_SPIN_PENDING_OFFSET 8
#define Q_SPIN_PENDING_BITS 1
#define Q_SPIN_PENDING_MASK 0x00000100U
#define Q_SPIN_PENDING_VAL 0x00000100U
#define Q_SPIN_LOCKED_PENDING_MASK (Q_SPIN_LOCKED_MASK | Q_SPIN_PENDING_MASK)
#define Q_SPIN_TAIL_LVL_OFFSET 9
#define Q_SPIN_TAIL_LVL_BITS 2
#define Q_SPIN_TAIL_LVL_MASK 0x00000600U
#define Q_SPIN_TAIL_CPU_OFFSET 16
#define Q_SPIN_TAIL_CPU_BITS 16
#define Q_SPIN_TAIL_CPU_MASK 0xFFFF0000U
#define Q_SPIN_TAIL_MASK (Q_SPIN_TAIL_LVL_MASK | Q_SPIN_TAIL_CPU_MASK)
#define QSPINLOCK_INIT QSPINLOCK_INIT_CHK(NULL, LOCK_CHKD_FULL)
#define QSPINLOCK_DEFINE(id) struct qspinlock id = QSPINLOCK_INIT
#define QSPINLOCK_DEFINE_CHK(id, class_, flags_) \
struct qspinlock id = QSPINLOCK_INIT_CHK((class_), (flags_))
#define __QSPINLOCK_SHALLOW_VALUE_INIT \
, .irq_usage = ATOMIC_VAR_INIT(LOCK_DEBUG_IRQ_NONE)
#define __QSPINLOCK_LOCK_CHK_VALUE_INIT(class_, flags_) \
, .chk = LOCK_CHK_LOCK_VALUE_INIT((class_), (flags_))
#define QSPINLOCK_INIT_CHK(class_, flags_) \
((struct qspinlock) { \
.val = ATOMIC_VAR_INIT(0) __QSPINLOCK_LOCK_CHK_VALUE_INIT( \
(class_), (flags_)) __QSPINLOCK_SHALLOW_VALUE_INIT})
#define qspinlock_init_chk(lock_, class_, flags_) \
qspinlock_init_chk_internal((lock_), (class_), (flags_))
#define qspinlock_init_auto_internal(lock_, flags_) \
do { \
static const struct lock_chk_class __auto_class = { \
.name = #lock_, \
.file = __RELFILE__, \
.line = __LINE__, \
}; \
qspinlock_init_chk_internal((lock_), &__auto_class, (flags_)); \
} while (0)
#define __QSPINLOCK_SHALLOW_VALUE_INIT
#define __QSPINLOCK_LOCK_CHK_VALUE_INIT(class_, flags_)
#define QSPINLOCK_INIT_CHK(class_, flags_) \
((struct qspinlock) {.val = ATOMIC_VAR_INIT(0)})
#define qspinlock_init_chk(lock_, class_, flags_) \
qspinlock_init_chk_internal((lock_), NULL, LOCK_UNCHKD)
#define qspinlock_init_auto_internal(lock_, flags_) \
qspinlock_init_chk_internal((lock_), NULL, LOCK_UNCHKD)
#define qspinlock_init_1(lock_) \
qspinlock_init_auto_internal((lock_), LOCK_CHKD_FULL)
#define qspinlock_init_2(lock_, flags_) \
qspinlock_init_auto_internal((lock_), (flags_))
#define qspinlock_init(...) \
_DISPATCH(qspinlock_init, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
#define qspin_init(...) qspinlock_init(__VA_ARGS__)
#define qspin_init_chk(...) qspinlock_init_chk(__VA_ARGS__)
#define QSPINLOCK_ASSERT_LOCKED(l) \
kassert(qspin_is_locked(l), "qspinlock not locked")
#define qspin_lock(lock_) qspin_lock_internal((lock_), LOCK_CHK_SITE_HERE())
#define qspin_lock_subclass(lock_, subclass_) \
qspin_lock_subclass_internal((lock_), (subclass_), LOCK_CHK_SITE_HERE())
#define qspin_lock_irq_disable(lock_) \
qspin_lock_irq_disable_internal((lock_), LOCK_CHK_SITE_HERE())
#define qspin_unlock(lock_, old_) \
qspin_unlock_internal((lock_), (old_), LOCK_CHK_SITE_HERE())
#define qspin_unlock_irq_restore(lock_, old_) \
qspin_unlock_internal((lock_), (old_), LOCK_CHK_SITE_HERE())
#define qspin_trylock(lock_, out_) \
qspin_trylock_internal((lock_), (out_), LOCK_CHK_SITE_HERE())
#define qspin_trylock_irq_disable(lock_, out_) \
qspin_trylock_irq_disable_internal((lock_), (out_), LOCK_CHK_SITE_HERE())
#define qspin_lock_raw(lock_) \
qspin_lock_raw_internal((lock_), LOCK_CHK_SITE_HERE())
#define qspin_trylock_raw(lock_) \
qspin_trylock_raw_internal((lock_), LOCK_CHK_SITE_HERE())
#define qspin_unlock_raw(lock_) \
qspin_unlock_raw_internal((lock_), LOCK_CHK_SITE_HERE())
#define QSPINLOCK_ASSERT_HELD(l) \
qspin_assert_held_internal((l), LOCK_CHK_SITE_HERE())
#define QSPINLOCK_ASSERT_NOT_HELD(l) \
qspin_assert_not_held_internal((l), LOCK_CHK_SITE_HERE())