📄 spinlock.h
字号:
local_irq_disable(); \
preempt_disable(); \
_raw_spin_lock(lock); \
__acquire(lock); \
} while (0)
#define _spin_lock_bh(lock) \
do { \
local_bh_disable(); \
preempt_disable(); \
_raw_spin_lock(lock); \
__acquire(lock); \
} while (0)
#define _read_lock_irqsave(lock, flags) \
do { \
local_irq_save(flags); \
preempt_disable(); \
_raw_read_lock(lock); \
__acquire(lock); \
} while (0)
#define _read_lock_irq(lock) \
do { \
local_irq_disable(); \
preempt_disable(); \
_raw_read_lock(lock); \
__acquire(lock); \
} while (0)
#define _read_lock_bh(lock) \
do { \
local_bh_disable(); \
preempt_disable(); \
_raw_read_lock(lock); \
__acquire(lock); \
} while (0)
#define _write_lock_irqsave(lock, flags) \
do { \
local_irq_save(flags); \
preempt_disable(); \
_raw_write_lock(lock); \
__acquire(lock); \
} while (0)
#define _write_lock_irq(lock) \
do { \
local_irq_disable(); \
preempt_disable(); \
_raw_write_lock(lock); \
__acquire(lock); \
} while (0)
#define _write_lock_bh(lock) \
do { \
local_bh_disable(); \
preempt_disable(); \
_raw_write_lock(lock); \
__acquire(lock); \
} while (0)
#define _spin_unlock_irqrestore(lock, flags) \
do { \
_raw_spin_unlock(lock); \
local_irq_restore(flags); \
preempt_enable(); \
__release(lock); \
} while (0)
#define _spin_unlock_irq(lock) \
do { \
_raw_spin_unlock(lock); \
local_irq_enable(); \
preempt_enable(); \
__release(lock); \
} while (0)
#define _spin_unlock_bh(lock) \
do { \
_raw_spin_unlock(lock); \
preempt_enable_no_resched(); \
local_bh_enable(); \
__release(lock); \
} while (0)
#define _write_unlock_bh(lock) \
do { \
_raw_write_unlock(lock); \
preempt_enable_no_resched(); \
local_bh_enable(); \
__release(lock); \
} while (0)
#define _read_unlock_irqrestore(lock, flags) \
do { \
_raw_read_unlock(lock); \
local_irq_restore(flags); \
preempt_enable(); \
__release(lock); \
} while (0)
#define _write_unlock_irqrestore(lock, flags) \
do { \
_raw_write_unlock(lock); \
local_irq_restore(flags); \
preempt_enable(); \
__release(lock); \
} while (0)
#define _read_unlock_irq(lock) \
do { \
_raw_read_unlock(lock); \
local_irq_enable(); \
preempt_enable(); \
__release(lock); \
} while (0)
#define _read_unlock_bh(lock) \
do { \
_raw_read_unlock(lock); \
preempt_enable_no_resched(); \
local_bh_enable(); \
__release(lock); \
} while (0)
#define _write_unlock_irq(lock) \
do { \
_raw_write_unlock(lock); \
local_irq_enable(); \
preempt_enable(); \
__release(lock); \
} while (0)
#endif /* !SMP */
/*
* Define the various spin_lock and rw_lock methods. Note we define these
* regardless of whether CONFIG_SMP or CONFIG_PREEMPT are set. The various
* methods are defined as nops in the case they are not required.
*/
#define spin_trylock(lock) __cond_lock(_spin_trylock(lock))
#define read_trylock(lock) __cond_lock(_read_trylock(lock))
#define write_trylock(lock) __cond_lock(_write_trylock(lock))
#define spin_lock(lock) _spin_lock(lock)
#define write_lock(lock) _write_lock(lock)
#define read_lock(lock) _read_lock(lock)
#ifdef CONFIG_SMP
#define spin_lock_irqsave(lock, flags) flags = _spin_lock_irqsave(lock)
#define read_lock_irqsave(lock, flags) flags = _read_lock_irqsave(lock)
#define write_lock_irqsave(lock, flags) flags = _write_lock_irqsave(lock)
#else
#define spin_lock_irqsave(lock, flags) _spin_lock_irqsave(lock, flags)
#define read_lock_irqsave(lock, flags) _read_lock_irqsave(lock, flags)
#define write_lock_irqsave(lock, flags) _write_lock_irqsave(lock, flags)
#endif
#define spin_lock_irq(lock) _spin_lock_irq(lock)
#define spin_lock_bh(lock) _spin_lock_bh(lock)
#define read_lock_irq(lock) _read_lock_irq(lock)
#define read_lock_bh(lock) _read_lock_bh(lock)
#define write_lock_irq(lock) _write_lock_irq(lock)
#define write_lock_bh(lock) _write_lock_bh(lock)
#define spin_unlock(lock) _spin_unlock(lock)
#define write_unlock(lock) _write_unlock(lock)
#define read_unlock(lock) _read_unlock(lock)
#define spin_unlock_irqrestore(lock, flags) _spin_unlock_irqrestore(lock, flags)
#define spin_unlock_irq(lock) _spin_unlock_irq(lock)
#define spin_unlock_bh(lock) _spin_unlock_bh(lock)
#define read_unlock_irqrestore(lock, flags) _read_unlock_irqrestore(lock, flags)
#define read_unlock_irq(lock) _read_unlock_irq(lock)
#define read_unlock_bh(lock) _read_unlock_bh(lock)
#define write_unlock_irqrestore(lock, flags) _write_unlock_irqrestore(lock, flags)
#define write_unlock_irq(lock) _write_unlock_irq(lock)
#define write_unlock_bh(lock) _write_unlock_bh(lock)
#define spin_trylock_bh(lock) __cond_lock(_spin_trylock_bh(lock))
#define spin_trylock_irq(lock) \
({ \
local_irq_disable(); \
_spin_trylock(lock) ? \
1 : ({local_irq_enable(); 0; }); \
})
#define spin_trylock_irqsave(lock, flags) \
({ \
local_irq_save(flags); \
_spin_trylock(lock) ? \
1 : ({local_irq_restore(flags); 0;}); \
})
#ifdef CONFIG_LOCKMETER
extern void _metered_spin_lock (spinlock_t *lock);
extern void _metered_spin_unlock (spinlock_t *lock);
extern int _metered_spin_trylock(spinlock_t *lock);
extern void _metered_read_lock (rwlock_t *lock);
extern void _metered_read_unlock (rwlock_t *lock);
extern void _metered_write_lock (rwlock_t *lock);
extern void _metered_write_unlock (rwlock_t *lock);
extern int _metered_read_trylock (rwlock_t *lock);
extern int _metered_write_trylock(rwlock_t *lock);
#endif
/* "lock on reference count zero" */
#ifndef ATOMIC_DEC_AND_LOCK
#include <asm/atomic.h>
extern int _atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
#endif
#define atomic_dec_and_lock(atomic,lock) __cond_lock(_atomic_dec_and_lock(atomic,lock))
/*
* bit-based spin_lock()
*
* Don't use this unless you really need to: spin_lock() and spin_unlock()
* are significantly faster.
*/
static inline void bit_spin_lock(int bitnum, unsigned long *addr)
{
/*
* Assuming the lock is uncontended, this never enters
* the body of the outer loop. If it is contended, then
* within the inner loop a non-atomic test is used to
* busywait with less bus contention for a good time to
* attempt to acquire the lock bit.
*/
preempt_disable();
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
while (test_and_set_bit(bitnum, addr)) {
while (test_bit(bitnum, addr)) {
preempt_enable();
cpu_relax();
preempt_disable();
}
}
#endif
__acquire(bitlock);
}
/*
* Return true if it was acquired
*/
static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
{
preempt_disable();
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
if (test_and_set_bit(bitnum, addr)) {
preempt_enable();
return 0;
}
#endif
__acquire(bitlock);
return 1;
}
/*
* bit-based spin_unlock()
*/
static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
{
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
BUG_ON(!test_bit(bitnum, addr));
smp_mb__before_clear_bit();
clear_bit(bitnum, addr);
#endif
preempt_enable();
__release(bitlock);
}
/*
* Return true if the lock is held.
*/
static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
{
#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
return test_bit(bitnum, addr);
#elif defined CONFIG_PREEMPT
return preempt_count();
#else
return 1;
#endif
}
#define DEFINE_SPINLOCK(x) spinlock_t x = SPIN_LOCK_UNLOCKED
#define DEFINE_RWLOCK(x) rwlock_t x = RW_LOCK_UNLOCKED
/**
* spin_can_lock - would spin_trylock() succeed?
* @lock: the spinlock in question.
*/
#define spin_can_lock(lock) (!spin_is_locked(lock))
#endif /* __LINUX_SPINLOCK_H */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -