linux(kernel)位操作

#define BIT(nr) (1UL << (nr))

#define BIT_MASK(nr) (1UL << ((nr) % BITS_PER_LONG))

#define BIT_WORD(nr) ((nr) / BITS_PER_LONG)

 

#define BITS_PER_LONG 32

 

test_bit:测试相应地址的nr位是否为1.

static inline int test_bit(int nr, const volatile unsigned long *addr)

{

        return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));

}

 

clear_bit:设置相应设置地址的nr位为0.

/* TODO: Not atomic as it should be:

 * we don't use this for anything important. */

static inline void clear_bit(int nr, volatile unsigned long *addr)

{

unsigned long mask = BIT_MASK(nr);

unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);

 

*p &= ~mask;

}

 

set_bit:设置相应设置地址的nr位为1

/**

 * set_bit - Atomically set a bit in memory

 * @nr: the bit to set

 * @addr: the address to start counting from

 *

 * This function is atomic and may not be reordered.  See __set_bit()

 * if you do not require the atomic guarantees.

 *

 * Note: there are no guarantees that this function will not be reordered

 * on non x86 architectures, so if you are writing portable code,

 * make sure not to rely on its reordering guarantees.

 *

 * Note that @nr may be almost arbitrarily large; this function is not

 * restricted to acting on a single-word quantity.

 */

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);

}

 

test_and_set_bit:设置相应设置地址的nr位为1,并返回原来这一位的值

/**

 * test_and_set_bit - Set a bit and return its old value

 * @nr: Bit to set

 * @addr: Address to count from

 *

 * This operation is atomic and cannot be reordered.

 * It may be reordered on other architectures than x86.

 * It also implies a memory barrier.

 */

static inline int test_and_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 old;

unsigned long flags;

 

_atomic_spin_lock_irqsave(p, flags);

old = *p;

*p = old | mask;

_atomic_spin_unlock_irqrestore(p, flags);

 

return (old & mask) != 0;

}

 

test_and_clear_bit:设置相应设置地址的nr位为0,并返回原来这一位的值

/**

 * test_and_clear_bit - Clear a bit and return its old value

 * @nr: Bit to clear

 * @addr: Address to count from

 *

 * This operation is atomic and cannot be reordered.

 * It can be reorderdered on other architectures other than x86.

 * It also implies a memory barrier.

 */

static inline int test_and_clear_bit(int nr, volatile unsigned long *addr)

{

unsigned long mask = BIT_MASK(nr);

unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);

unsigned long old;

unsigned long flags;

 

_atomic_spin_lock_irqsave(p, flags);

old = *p;

*p = old & ~mask;

_atomic_spin_unlock_irqrestore(p, flags);

 

return (old & mask) != 0;

}

test_and_change_bit:改变相应设置地址的nr位的值,并返回原来这一位的值

 

/**

 * test_and_change_bit - Change a bit and return its old value

 * @nr: Bit to change

 * @addr: Address to count from

 *

 * This operation is atomic and cannot be reordered.

 * It also implies a memory barrier.

 */

static inline int test_and_change_bit(int nr, volatile unsigned long *addr)

{

unsigned long mask = BIT_MASK(nr);

unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr);

unsigned long old;

unsigned long flags;

 

_atomic_spin_lock_irqsave(p, flags);

old = *p;

*p = old ^ mask;

_atomic_spin_unlock_irqrestore(p, flags);

 

return (old & mask) != 0;

}

(摘自 http://wmzjzwlzs.blog.163.com/blog/static/205014196201532294338242

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值