atomic.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:5k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef __ARCH_X86_64_ATOMIC__
  2. #define __ARCH_X86_64_ATOMIC__
  3. #include <linux/config.h>
  4. /* atomic_t should be 32 bit signed type */
  5. /*
  6.  * Atomic operations that C can't guarantee us.  Useful for
  7.  * resource counting etc..
  8.  */
  9. #ifdef CONFIG_SMP
  10. #define LOCK "lock ; "
  11. #else
  12. #define LOCK ""
  13. #endif
  14. /*
  15.  * Make sure gcc doesn't try to be clever and move things around
  16.  * on us. We need to use _exactly_ the address the user gave us,
  17.  * not some alias that contains the same information.
  18.  */
  19. typedef struct { volatile int counter; } atomic_t;
  20. #define ATOMIC_INIT(i) { (i) }
  21. /**
  22.  * atomic_read - read atomic variable
  23.  * @v: pointer of type atomic_t
  24.  * 
  25.  * Atomically reads the value of @v.  Note that the guaranteed
  26.  * useful range of an atomic_t is only 24 bits.
  27.  */ 
  28. #define atomic_read(v) ((v)->counter)
  29. /**
  30.  * atomic_set - set atomic variable
  31.  * @v: pointer of type atomic_t
  32.  * @i: required value
  33.  * 
  34.  * Atomically sets the value of @v to @i.  Note that the guaranteed
  35.  * useful range of an atomic_t is only 24 bits.
  36.  */ 
  37. #define atomic_set(v,i) (((v)->counter) = (i))
  38. /**
  39.  * atomic_add - add integer to atomic variable
  40.  * @i: integer value to add
  41.  * @v: pointer of type atomic_t
  42.  * 
  43.  * Atomically adds @i to @v.  Note that the guaranteed useful range
  44.  * of an atomic_t is only 24 bits.
  45.  */
  46. static __inline__ void atomic_add(int i, atomic_t *v)
  47. {
  48. __asm__ __volatile__(
  49. LOCK "addl %1,%0"
  50. :"=m" (v->counter)
  51. :"ir" (i), "m" (v->counter));
  52. }
  53. /**
  54.  * atomic_sub - subtract the atomic variable
  55.  * @i: integer value to subtract
  56.  * @v: pointer of type atomic_t
  57.  * 
  58.  * Atomically subtracts @i from @v.  Note that the guaranteed
  59.  * useful range of an atomic_t is only 24 bits.
  60.  */
  61. static __inline__ void atomic_sub(int i, atomic_t *v)
  62. {
  63. __asm__ __volatile__(
  64. LOCK "subl %1,%0"
  65. :"=m" (v->counter)
  66. :"ir" (i), "m" (v->counter));
  67. }
  68. /**
  69.  * atomic_sub_and_test - subtract value from variable and test result
  70.  * @i: integer value to subtract
  71.  * @v: pointer of type atomic_t
  72.  * 
  73.  * Atomically subtracts @i from @v and returns
  74.  * true if the result is zero, or false for all
  75.  * other cases.  Note that the guaranteed
  76.  * useful range of an atomic_t is only 24 bits.
  77.  */
  78. static __inline__ int atomic_sub_and_test(int i, atomic_t *v)
  79. {
  80. unsigned char c;
  81. __asm__ __volatile__(
  82. LOCK "subl %2,%0; sete %1"
  83. :"=m" (v->counter), "=qm" (c)
  84. :"ir" (i), "m" (v->counter) : "memory");
  85. return c;
  86. }
  87. /**
  88.  * atomic_inc - increment atomic variable
  89.  * @v: pointer of type atomic_t
  90.  * 
  91.  * Atomically increments @v by 1.  Note that the guaranteed
  92.  * useful range of an atomic_t is only 24 bits.
  93.  */ 
  94. static __inline__ void atomic_inc(atomic_t *v)
  95. {
  96. __asm__ __volatile__(
  97. LOCK "incl %0"
  98. :"=m" (v->counter)
  99. :"m" (v->counter));
  100. }
  101. /**
  102.  * atomic_dec - decrement atomic variable
  103.  * @v: pointer of type atomic_t
  104.  * 
  105.  * Atomically decrements @v by 1.  Note that the guaranteed
  106.  * useful range of an atomic_t is only 24 bits.
  107.  */ 
  108. static __inline__ void atomic_dec(atomic_t *v)
  109. {
  110. __asm__ __volatile__(
  111. LOCK "decl %0"
  112. :"=m" (v->counter)
  113. :"m" (v->counter));
  114. }
  115. /**
  116.  * atomic_dec_and_test - decrement and test
  117.  * @v: pointer of type atomic_t
  118.  * 
  119.  * Atomically decrements @v by 1 and
  120.  * returns true if the result is 0, or false for all other
  121.  * cases.  Note that the guaranteed
  122.  * useful range of an atomic_t is only 24 bits.
  123.  */ 
  124. static __inline__ int atomic_dec_and_test(atomic_t *v)
  125. {
  126. unsigned char c;
  127. __asm__ __volatile__(
  128. LOCK "decl %0; sete %1"
  129. :"=m" (v->counter), "=qm" (c)
  130. :"m" (v->counter) : "memory");
  131. return c != 0;
  132. }
  133. /**
  134.  * atomic_inc_and_test - increment and test 
  135.  * @v: pointer of type atomic_t
  136.  * 
  137.  * Atomically increments @v by 1
  138.  * and returns true if the result is zero, or false for all
  139.  * other cases.  Note that the guaranteed
  140.  * useful range of an atomic_t is only 24 bits.
  141.  */ 
  142. static __inline__ int atomic_inc_and_test(atomic_t *v)
  143. {
  144. unsigned char c;
  145. __asm__ __volatile__(
  146. LOCK "incl %0; sete %1"
  147. :"=m" (v->counter), "=qm" (c)
  148. :"m" (v->counter) : "memory");
  149. return c != 0;
  150. }
  151. /**
  152.  * atomic_add_negative - add and test if negative
  153.  * @v: pointer of type atomic_t
  154.  * @i: integer value to add
  155.  * 
  156.  * Atomically adds @i to @v and returns true
  157.  * if the result is negative, or false when
  158.  * result is greater than or equal to zero.  Note that the guaranteed
  159.  * useful range of an atomic_t is only 24 bits.
  160.  */ 
  161. static __inline__ int atomic_add_negative(int i, atomic_t *v)
  162. {
  163. unsigned char c;
  164. __asm__ __volatile__(
  165. LOCK "addl %2,%0; sets %1"
  166. :"=m" (v->counter), "=qm" (c)
  167. :"ir" (i), "m" (v->counter) : "memory");
  168. return c;
  169. }
  170. /* These are x86-specific, used by some header files */
  171. #define atomic_clear_mask(mask, addr) 
  172. __asm__ __volatile__(LOCK "andl %0,%1" 
  173. : : "r" (~(mask)),"m" (*addr) : "memory")
  174. #define atomic_set_mask(mask, addr) 
  175. __asm__ __volatile__(LOCK "orl %0,%1" 
  176. : : "r" ((unsigned)mask),"m" (*addr) : "memory")
  177. /* Atomic operations are already serializing on x86 */
  178. #define smp_mb__before_atomic_dec() barrier()
  179. #define smp_mb__after_atomic_dec() barrier()
  180. #define smp_mb__before_atomic_inc() barrier()
  181. #define smp_mb__after_atomic_inc() barrier()
  182. #endif