linux/tools/testing/radix-tree/linux/bitops/non-atomic.h
<<
>>
Prefs
   1#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
   2#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
   3
   4#include <asm/types.h>
   5
   6#define BITOP_MASK(nr)          (1UL << ((nr) % BITS_PER_LONG))
   7#define BITOP_WORD(nr)          ((nr) / BITS_PER_LONG)
   8
   9/**
  10 * __set_bit - Set a bit in memory
  11 * @nr: the bit to set
  12 * @addr: the address to start counting from
  13 *
  14 * Unlike set_bit(), this function is non-atomic and may be reordered.
  15 * If it's called on the same region of memory simultaneously, the effect
  16 * may be that only one operation succeeds.
  17 */
  18static inline void __set_bit(int nr, volatile unsigned long *addr)
  19{
  20        unsigned long mask = BITOP_MASK(nr);
  21        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
  22
  23        *p  |= mask;
  24}
  25
  26static inline void __clear_bit(int nr, volatile unsigned long *addr)
  27{
  28        unsigned long mask = BITOP_MASK(nr);
  29        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
  30
  31        *p &= ~mask;
  32}
  33
  34/**
  35 * __change_bit - Toggle a bit in memory
  36 * @nr: the bit to change
  37 * @addr: the address to start counting from
  38 *
  39 * Unlike change_bit(), this function is non-atomic and may be reordered.
  40 * If it's called on the same region of memory simultaneously, the effect
  41 * may be that only one operation succeeds.
  42 */
  43static inline void __change_bit(int nr, volatile unsigned long *addr)
  44{
  45        unsigned long mask = BITOP_MASK(nr);
  46        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
  47
  48        *p ^= mask;
  49}
  50
  51/**
  52 * __test_and_set_bit - Set a bit and return its old value
  53 * @nr: Bit to set
  54 * @addr: Address to count from
  55 *
  56 * This operation is non-atomic and can be reordered.
  57 * If two examples of this operation race, one can appear to succeed
  58 * but actually fail.  You must protect multiple accesses with a lock.
  59 */
  60static inline int __test_and_set_bit(int nr, volatile unsigned long *addr)
  61{
  62        unsigned long mask = BITOP_MASK(nr);
  63        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
  64        unsigned long old = *p;
  65
  66        *p = old | mask;
  67        return (old & mask) != 0;
  68}
  69
  70/**
  71 * __test_and_clear_bit - Clear a bit and return its old value
  72 * @nr: Bit to clear
  73 * @addr: Address to count from
  74 *
  75 * This operation is non-atomic and can be reordered.
  76 * If two examples of this operation race, one can appear to succeed
  77 * but actually fail.  You must protect multiple accesses with a lock.
  78 */
  79static inline int __test_and_clear_bit(int nr, volatile unsigned long *addr)
  80{
  81        unsigned long mask = BITOP_MASK(nr);
  82        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
  83        unsigned long old = *p;
  84
  85        *p = old & ~mask;
  86        return (old & mask) != 0;
  87}
  88
  89/* WARNING: non atomic and it can be reordered! */
  90static inline int __test_and_change_bit(int nr,
  91                                            volatile unsigned long *addr)
  92{
  93        unsigned long mask = BITOP_MASK(nr);
  94        unsigned long *p = ((unsigned long *)addr) + BITOP_WORD(nr);
  95        unsigned long old = *p;
  96
  97        *p = old ^ mask;
  98        return (old & mask) != 0;
  99}
 100
 101/**
 102 * test_bit - Determine whether a bit is set
 103 * @nr: bit number to test
 104 * @addr: Address to start counting from
 105 */
 106static inline int test_bit(int nr, const volatile unsigned long *addr)
 107{
 108        return 1UL & (addr[BITOP_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
 109}
 110
 111#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
 112