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

Linux/Unix编程

开发平台:

Unix_Linux

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