linux/tools/testing/radix-tree/linux/bitops.h
<<
>>
Prefs
   1#ifndef _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
   2#define _ASM_GENERIC_BITOPS_NON_ATOMIC_H_
   3
   4#include <linux/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/**
 112 * __ffs - find first bit in word.
 113 * @word: The word to search
 114 *
 115 * Undefined if no bit exists, so code should check against 0 first.
 116 */
 117static inline unsigned long __ffs(unsigned long word)
 118{
 119        int num = 0;
 120
 121        if ((word & 0xffffffff) == 0) {
 122                num += 32;
 123                word >>= 32;
 124        }
 125        if ((word & 0xffff) == 0) {
 126                num += 16;
 127                word >>= 16;
 128        }
 129        if ((word & 0xff) == 0) {
 130                num += 8;
 131                word >>= 8;
 132        }
 133        if ((word & 0xf) == 0) {
 134                num += 4;
 135                word >>= 4;
 136        }
 137        if ((word & 0x3) == 0) {
 138                num += 2;
 139                word >>= 2;
 140        }
 141        if ((word & 0x1) == 0)
 142                num += 1;
 143        return num;
 144}
 145
 146unsigned long find_next_bit(const unsigned long *addr,
 147                            unsigned long size,
 148                            unsigned long offset);
 149
 150#endif /* _ASM_GENERIC_BITOPS_NON_ATOMIC_H_ */
 151