Linux 内核 bitops 非原子操作实现。
static inline void set_bit(int bit, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(bit);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(bit);
*p |= mask;
}
static inline void clear_bit(unsigned int bit, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(bit);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(bit);
*p &= ~mask;
}
static inline void change_bit(unsigned int bit, volatile unsigned long *addr)
{
unsigned long mask = BIT_MASK(bit);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(bit);
*p ^= mask;
}
static inline int
test_and_set_bit(unsigned int bit, volatile unsigned long *addr)
{
unsigned int res;
unsigned long mask = BIT_MASK(bit);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(bit);
res = *p;
*p = res | mask;
return (res & mask) != 0;
}
static inline int
test_and_clear_bit(unsigned int bit, volatile unsigned long *addr)
{
unsigned int res;
unsigned long mask = BIT_MASK(bit);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(bit);
res = *p;
*p = res & ~mask;
return (res & mask) != 0;
}
static inline int
test_and_change_bit(unsigned int bit, volatile unsigned long *addr)
{
unsigned int res;
unsigned long mask = BIT_MASK(bit);
unsigned long *p = ((unsigned long *)addr) + BIT_WORD(bit);
res = *p;
*p = res ^ mask;
return (res & mask) != 0;
}