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

嵌入式Linux

开发平台:

Unix_Linux

  1. /*
  2.  * Atomic operations that C can't guarantee us.  Useful for
  3.  * resource counting etc..
  4.  *
  5.  * But use these as seldom as possible since they are much more slower
  6.  * than regular operations.
  7.  *
  8.  * This file is subject to the terms and conditions of the GNU General Public
  9.  * License.  See the file "COPYING" in the main directory of this archive
  10.  * for more details.
  11.  *
  12.  * Copyright (C) 1996, 1997, 1999, 2000 by Ralf Baechle
  13.  */
  14. #ifndef _ASM_ATOMIC_H
  15. #define _ASM_ATOMIC_H
  16. #include <asm/sgidefs.h>
  17. typedef struct { volatile int counter; } atomic_t;
  18. #ifdef __KERNEL__
  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. extern __inline__ void atomic_add(int i, volatile atomic_t * v)
  38. {
  39. unsigned long temp;
  40. __asm__ __volatile__(
  41. "1:tllt%0,%1ttt# atomic_addnt"
  42. "addut%0,%2nt"
  43. "sct%0,%1nt"
  44. "beqzt%0,1b"
  45. : "=&r" (temp), "=m" (v->counter)
  46. : "Ir" (i), "m" (v->counter));
  47. }
  48. /*
  49.  * atomic_sub - subtract the atomic variable
  50.  * @i: integer value to subtract
  51.  * @v: pointer of type atomic_t
  52.  *
  53.  * Atomically subtracts @i from @v.  Note that the guaranteed
  54.  * useful range of an atomic_t is only 24 bits.
  55.  */
  56. extern __inline__ void atomic_sub(int i, volatile atomic_t * v)
  57. {
  58. unsigned long temp;
  59. __asm__ __volatile__(
  60. "1:tllt%0,%1ttt# atomic_subnt"
  61. "subut%0,%2nt"
  62. "sct%0,%1nt"
  63. "beqzt%0,1b"
  64. : "=&r" (temp), "=m" (v->counter)
  65. : "Ir" (i), "m" (v->counter));
  66. }
  67. /*
  68.  * Same as above, but return the result value
  69.  */
  70. extern __inline__ int atomic_add_return(int i, atomic_t * v)
  71. {
  72. unsigned long temp, result;
  73. __asm__ __volatile__(
  74. ".settnoreorderttt# atomic_add_returnn"
  75. "1:tllt%1,%2nt"
  76. "addut%0,%1,%3nt"
  77. "sct%0,%2nt"
  78. "beqzt%0,1bnt"
  79. "addut%0,%1,%3nt"
  80. ".settreorder"
  81. : "=&r" (result), "=&r" (temp), "=m" (v->counter)
  82. : "Ir" (i), "m" (v->counter)
  83. : "memory");
  84. return result;
  85. }
  86. extern __inline__ int atomic_sub_return(int i, atomic_t * v)
  87. {
  88. unsigned long temp, result;
  89. __asm__ __volatile__(
  90. ".settnoreorderttt# atomic_sub_returnn"
  91. "1:tllt%1,%2nt"
  92. "subut%0,%1,%3nt"
  93. "sct%0,%2nt"
  94. "beqzt%0,1bnt"
  95. "subut%0,%1,%3nt"
  96. ".settreorder"
  97. : "=&r" (result), "=&r" (temp), "=m" (v->counter)
  98. : "Ir" (i), "m" (v->counter)
  99. : "memory");
  100. return result;
  101. }
  102. #define atomic_dec_return(v) atomic_sub_return(1,(v))
  103. #define atomic_inc_return(v) atomic_add_return(1,(v))
  104. /*
  105.  * atomic_sub_and_test - subtract value from variable and test result
  106.  * @i: integer value to subtract
  107.  * @v: pointer of type atomic_t
  108.  *
  109.  * Atomically subtracts @i from @v and returns
  110.  * true if the result is zero, or false for all
  111.  * other cases.  Note that the guaranteed
  112.  * useful range of an atomic_t is only 24 bits.
  113.  */
  114. #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
  115. /*
  116.  * atomic_inc_and_test - increment and test
  117.  * @v: pointer of type atomic_t
  118.  *
  119.  * Atomically increments @v by 1
  120.  * and returns true if the result is zero, or false for all
  121.  * other cases.  Note that the guaranteed
  122.  * useful range of an atomic_t is only 24 bits.
  123.  * atomic_inc_and_test is currently not implemented for mips64.
  124.  */
  125. /*
  126.  * atomic_dec_and_test - decrement by 1 and test
  127.  * @v: pointer of type atomic_t
  128.  *
  129.  * Atomically decrements @v by 1 and
  130.  * returns true if the result is 0, or false for all other
  131.  * cases.  Note that the guaranteed
  132.  * useful range of an atomic_t is only 24 bits.
  133.  */
  134. #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  135. /*
  136.  * atomic_inc - increment atomic variable
  137.  * @v: pointer of type atomic_t
  138.  *
  139.  * Atomically increments @v by 1.  Note that the guaranteed
  140.  * useful range of an atomic_t is only 24 bits.
  141.  */
  142. #define atomic_inc(v) atomic_add(1,(v))
  143. /*
  144.  * atomic_dec - decrement and test
  145.  * @v: pointer of type atomic_t
  146.  *
  147.  * Atomically decrements @v by 1.  Note that the guaranteed
  148.  * useful range of an atomic_t is only 24 bits.
  149.  */
  150. #define atomic_dec(v) atomic_sub(1,(v))
  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.  * atomic_add_negative is currently not implemented for mips64.
  162.  */
  163. /* Atomic operations are already serializing */
  164. #define smp_mb__before_atomic_dec() barrier()
  165. #define smp_mb__after_atomic_dec() barrier()
  166. #define smp_mb__before_atomic_inc() barrier()
  167. #define smp_mb__after_atomic_inc() barrier()
  168. #endif /* defined(__KERNEL__) */
  169. #endif /* _ASM_ATOMIC_H */