原子位操作

来源:互联网 发布:淘宝发布助手一直提示 编辑:程序博客网 时间:2024/06/04 23:35

include/asm-generic/bitops

针对SMP与非SMP:

#include <asm/types.h>#include <linux/irqflags.h>#ifdef CONFIG_SMP#include <asm/spinlock.h>#include <asm/cache.h>          /* we use L1_CACHE_BYTES *//* Use an array of spinlocks for our atomic_ts. * Hash function to index into a different SPINLOCK. * Since "a" is usually an address, use one spinlock per cacheline. */#  define ATOMIC_HASH_SIZE 4#  define ATOMIC_HASH(a) (&(__atomic_hash[ (((unsigned long) a)/L1_CACHE_BYTES) & (ATOMIC_HASH_SIZE-1) ]))extern arch_spinlock_t __atomic_hash[ATOMIC_HASH_SIZE] __lock_aligned;/* Can't use raw_spin_lock_irq because of #include problems, so * this is the substitute */#define _atomic_spin_lock_irqsave(l,f) do {     \        arch_spinlock_t *s = ATOMIC_HASH(l);    \        local_irq_save(f);                      \        arch_spin_lock(s);                      \} while(0)#define _atomic_spin_unlock_irqrestore(l,f) do {        \        arch_spinlock_t *s = ATOMIC_HASH(l);            \        arch_spin_unlock(s);                            \        local_irq_restore(f);                           \} while(0)#else#  define _atomic_spin_lock_irqsave(l,f) do { local_irq_save(f); } while (0)#  define _atomic_spin_unlock_irqrestore(l,f) do { local_irq_restore(f); } while (0)#endif

置位:

static inline void set_bit(int nr, volatile unsigned long *addr){        unsigned long mask = BIT_MASK(nr);        unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);        unsigned long flags;        _atomic_spin_lock_irqsave(p, flags);        *p  |= mask;        _atomic_spin_unlock_irqrestore(p, flags);}等。。。
0 0
原创粉丝点击