bitops.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _ASM_IA64_BITOPS_H
  2. #define _ASM_IA64_BITOPS_H
  3. /*
  4.  * Copyright (C) 1998-2001 Hewlett-Packard Co
  5.  * Copyright (C) 1998-2001 David Mosberger-Tang <davidm@hpl.hp.com>
  6.  */
  7. #include <asm/system.h>
  8. /**
  9.  * set_bit - Atomically set a bit in memory
  10.  * @nr: the bit to set
  11.  * @addr: the address to start counting from
  12.  *
  13.  * This function is atomic and may not be reordered.  See __set_bit()
  14.  * if you do not require the atomic guarantees.
  15.  * Note that @nr may be almost arbitrarily large; this function is not
  16.  * restricted to acting on a single-word quantity.
  17.  *
  18.  * The address must be (at least) "long" aligned.
  19.  * Note that there are driver (e.g., eepro100) which use these operations to operate on
  20.  * hw-defined data-structures, so we can't easily change these operations to force a
  21.  * bigger alignment.
  22.  *
  23.  * bit 0 is the LSB of addr; bit 32 is the LSB of (addr+1).
  24.  */
  25. static __inline__ void
  26. set_bit (int nr, volatile void *addr)
  27. {
  28. __u32 bit, old, new;
  29. volatile __u32 *m;
  30. CMPXCHG_BUGCHECK_DECL
  31. m = (volatile __u32 *) addr + (nr >> 5);
  32. bit = 1 << (nr & 31);
  33. do {
  34. CMPXCHG_BUGCHECK(m);
  35. old = *m;
  36. new = old | bit;
  37. } while (cmpxchg_acq(m, old, new) != old);
  38. }
  39. /**
  40.  * __set_bit - Set a bit in memory
  41.  * @nr: the bit to set
  42.  * @addr: the address to start counting from
  43.  *
  44.  * Unlike set_bit(), this function is non-atomic and may be reordered.
  45.  * If it's called on the same region of memory simultaneously, the effect
  46.  * may be that only one operation succeeds.
  47.  */
  48. static __inline__ void
  49. __set_bit (int nr, volatile void *addr)
  50. {
  51. *((__u32 *) addr + (nr >> 5)) |= (1 << (nr & 31));
  52. }
  53. /*
  54.  * clear_bit() doesn't provide any barrier for the compiler.
  55.  */
  56. #define smp_mb__before_clear_bit() smp_mb()
  57. #define smp_mb__after_clear_bit() smp_mb()
  58. /**
  59.  * clear_bit - Clears a bit in memory
  60.  * @nr: Bit to clear
  61.  * @addr: Address to start counting from
  62.  *
  63.  * clear_bit() is atomic and may not be reordered.  However, it does
  64.  * not contain a memory barrier, so if it is used for locking purposes,
  65.  * you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
  66.  * in order to ensure changes are visible on other processors.
  67.  */
  68. static __inline__ void
  69. clear_bit (int nr, volatile void *addr)
  70. {
  71. __u32 mask, old, new;
  72. volatile __u32 *m;
  73. CMPXCHG_BUGCHECK_DECL
  74. m = (volatile __u32 *) addr + (nr >> 5);
  75. mask = ~(1 << (nr & 31));
  76. do {
  77. CMPXCHG_BUGCHECK(m);
  78. old = *m;
  79. new = old & mask;
  80. } while (cmpxchg_acq(m, old, new) != old);
  81. }
  82. /**
  83.  * change_bit - Toggle a bit in memory
  84.  * @nr: Bit to clear
  85.  * @addr: Address to start counting from
  86.  *
  87.  * change_bit() is atomic and may not be reordered.
  88.  * Note that @nr may be almost arbitrarily large; this function is not
  89.  * restricted to acting on a single-word quantity.
  90.  */
  91. static __inline__ void
  92. change_bit (int nr, volatile void *addr)
  93. {
  94. __u32 bit, old, new;
  95. volatile __u32 *m;
  96. CMPXCHG_BUGCHECK_DECL
  97. m = (volatile __u32 *) addr + (nr >> 5);
  98. bit = (1 << (nr & 31));
  99. do {
  100. CMPXCHG_BUGCHECK(m);
  101. old = *m;
  102. new = old ^ bit;
  103. } while (cmpxchg_acq(m, old, new) != old);
  104. }
  105. /**
  106.  * __change_bit - Toggle a bit in memory
  107.  * @nr: the bit to set
  108.  * @addr: the address to start counting from
  109.  *
  110.  * Unlike change_bit(), this function is non-atomic and may be reordered.
  111.  * If it's called on the same region of memory simultaneously, the effect
  112.  * may be that only one operation succeeds.
  113.  */
  114. static __inline__ void
  115. __change_bit (int nr, volatile void *addr)
  116. {
  117. *((__u32 *) addr + (nr >> 5)) ^= (1 << (nr & 31));
  118. }
  119. /**
  120.  * test_and_set_bit - Set a bit and return its old value
  121.  * @nr: Bit to set
  122.  * @addr: Address to count from
  123.  *
  124.  * This operation is atomic and cannot be reordered.  
  125.  * It also implies a memory barrier.
  126.  */
  127. static __inline__ int
  128. test_and_set_bit (int nr, volatile void *addr)
  129. {
  130. __u32 bit, old, new;
  131. volatile __u32 *m;
  132. CMPXCHG_BUGCHECK_DECL
  133. m = (volatile __u32 *) addr + (nr >> 5);
  134. bit = 1 << (nr & 31);
  135. do {
  136. CMPXCHG_BUGCHECK(m);
  137. old = *m;
  138. new = old | bit;
  139. } while (cmpxchg_acq(m, old, new) != old);
  140. return (old & bit) != 0;
  141. }
  142. /**
  143.  * __test_and_set_bit - Set a bit and return its old value
  144.  * @nr: Bit to set
  145.  * @addr: Address to count from
  146.  *
  147.  * This operation is non-atomic and can be reordered.  
  148.  * If two examples of this operation race, one can appear to succeed
  149.  * but actually fail.  You must protect multiple accesses with a lock.
  150.  */
  151. static __inline__ int
  152. __test_and_set_bit (int nr, volatile void *addr)
  153. {
  154. __u32 *p = (__u32 *) addr + (nr >> 5);
  155. __u32 m = 1 << (nr & 31);
  156. int oldbitset = (*p & m) != 0;
  157. *p |= m;
  158. return oldbitset;
  159. }
  160. /**
  161.  * test_and_clear_bit - Clear a bit and return its old value
  162.  * @nr: Bit to set
  163.  * @addr: Address to count from
  164.  *
  165.  * This operation is atomic and cannot be reordered.  
  166.  * It also implies a memory barrier.
  167.  */
  168. static __inline__ int
  169. test_and_clear_bit (int nr, volatile void *addr)
  170. {
  171. __u32 mask, old, new;
  172. volatile __u32 *m;
  173. CMPXCHG_BUGCHECK_DECL
  174. m = (volatile __u32 *) addr + (nr >> 5);
  175. mask = ~(1 << (nr & 31));
  176. do {
  177. CMPXCHG_BUGCHECK(m);
  178. old = *m;
  179. new = old & mask;
  180. } while (cmpxchg_acq(m, old, new) != old);
  181. return (old & ~mask) != 0;
  182. }
  183. /**
  184.  * __test_and_clear_bit - Clear a bit and return its old value
  185.  * @nr: Bit to set
  186.  * @addr: Address to count from
  187.  *
  188.  * This operation is non-atomic and can be reordered.  
  189.  * If two examples of this operation race, one can appear to succeed
  190.  * but actually fail.  You must protect multiple accesses with a lock.
  191.  */
  192. static __inline__ int
  193. __test_and_clear_bit(int nr, volatile void * addr)
  194. {
  195. __u32 *p = (__u32 *) addr + (nr >> 5);
  196. __u32 m = 1 << (nr & 31);
  197. int oldbitset = *p & m;
  198. *p &= ~m;
  199. return oldbitset;
  200. }
  201. /**
  202.  * test_and_change_bit - Change a bit and return its new value
  203.  * @nr: Bit to set
  204.  * @addr: Address to count from
  205.  *
  206.  * This operation is atomic and cannot be reordered.  
  207.  * It also implies a memory barrier.
  208.  */
  209. static __inline__ int
  210. test_and_change_bit (int nr, volatile void *addr)
  211. {
  212. __u32 bit, old, new;
  213. volatile __u32 *m;
  214. CMPXCHG_BUGCHECK_DECL
  215. m = (volatile __u32 *) addr + (nr >> 5);
  216. bit = (1 << (nr & 31));
  217. do {
  218. CMPXCHG_BUGCHECK(m);
  219. old = *m;
  220. new = old ^ bit;
  221. } while (cmpxchg_acq(m, old, new) != old);
  222. return (old & bit) != 0;
  223. }
  224. /*
  225.  * WARNING: non atomic version.
  226.  */
  227. static __inline__ int
  228. __test_and_change_bit (int nr, void *addr)
  229. {
  230. __u32 old, bit = (1 << (nr & 31));
  231. __u32 *m = (__u32 *) addr + (nr >> 5);
  232. old = *m;
  233. *m = old ^ bit;
  234. return (old & bit) != 0;
  235. }
  236. static __inline__ int
  237. test_bit (int nr, volatile void *addr)
  238. {
  239. return 1 & (((const volatile __u32 *) addr)[nr >> 5] >> (nr & 31));
  240. }
  241. /**
  242.  * ffz - find the first zero bit in a memory region
  243.  * @x: The address to start the search at
  244.  *
  245.  * Returns the bit-number (0..63) of the first (least significant) zero bit, not
  246.  * the number of the byte containing a bit.  Undefined if no zero exists, so
  247.  * code should check against ~0UL first...
  248.  */
  249. static inline unsigned long
  250. ffz (unsigned long x)
  251. {
  252. unsigned long result;
  253. __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x & (~x - 1)));
  254. return result;
  255. }
  256. #ifdef __KERNEL__
  257. /*
  258.  * find_last_zero_bit - find the last zero bit in a 64 bit quantity
  259.  * @x: The value to search
  260.  */
  261. static inline unsigned long
  262. ia64_fls (unsigned long x)
  263. {
  264. double d = x;
  265. long exp;
  266. __asm__ ("getf.exp %0=%1" : "=r"(exp) : "f"(d));
  267. return exp - 0xffff;
  268. }
  269. /*
  270.  * ffs: find first bit set. This is defined the same way as the libc and compiler builtin
  271.  * ffs routines, therefore differs in spirit from the above ffz (man ffs): it operates on
  272.  * "int" values only and the result value is the bit number + 1.  ffs(0) is defined to
  273.  * return zero.
  274.  */
  275. #define ffs(x) __builtin_ffs(x)
  276. /*
  277.  * hweightN: returns the hamming weight (i.e. the number
  278.  * of bits set) of a N-bit word
  279.  */
  280. static __inline__ unsigned long
  281. hweight64 (unsigned long x)
  282. {
  283. unsigned long result;
  284. __asm__ ("popcnt %0=%1" : "=r" (result) : "r" (x));
  285. return result;
  286. }
  287. #define hweight32(x) hweight64 ((x) & 0xfffffffful)
  288. #define hweight16(x) hweight64 ((x) & 0xfffful)
  289. #define hweight8(x)  hweight64 ((x) & 0xfful)
  290. #endif /* __KERNEL__ */
  291. /*
  292.  * Find next zero bit in a bitmap reasonably efficiently..
  293.  */
  294. static inline int
  295. find_next_zero_bit (void *addr, unsigned long size, unsigned long offset)
  296. {
  297. unsigned long *p = ((unsigned long *) addr) + (offset >> 6);
  298. unsigned long result = offset & ~63UL;
  299. unsigned long tmp;
  300. if (offset >= size)
  301. return size;
  302. size -= result;
  303. offset &= 63UL;
  304. if (offset) {
  305. tmp = *(p++);
  306. tmp |= ~0UL >> (64-offset);
  307. if (size < 64)
  308. goto found_first;
  309. if (~tmp)
  310. goto found_middle;
  311. size -= 64;
  312. result += 64;
  313. }
  314. while (size & ~63UL) {
  315. if (~(tmp = *(p++)))
  316. goto found_middle;
  317. result += 64;
  318. size -= 64;
  319. }
  320. if (!size)
  321. return result;
  322. tmp = *p;
  323. found_first:
  324. tmp |= ~0UL << size;
  325. found_middle:
  326. return result + ffz(tmp);
  327. }
  328. /*
  329.  * The optimizer actually does good code for this case..
  330.  */
  331. #define find_first_zero_bit(addr, size) find_next_zero_bit((addr), (size), 0)
  332. #ifdef __KERNEL__
  333. #define ext2_set_bit                 test_and_set_bit
  334. #define ext2_clear_bit               test_and_clear_bit
  335. #define ext2_test_bit                test_bit
  336. #define ext2_find_first_zero_bit     find_first_zero_bit
  337. #define ext2_find_next_zero_bit      find_next_zero_bit
  338. /* Bitmap functions for the minix filesystem.  */
  339. #define minix_test_and_set_bit(nr,addr) test_and_set_bit(nr,addr)
  340. #define minix_set_bit(nr,addr) set_bit(nr,addr)
  341. #define minix_test_and_clear_bit(nr,addr) test_and_clear_bit(nr,addr)
  342. #define minix_test_bit(nr,addr) test_bit(nr,addr)
  343. #define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size)
  344. #endif /* __KERNEL__ */
  345. #endif /* _ASM_IA64_BITOPS_H */