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

Linux/Unix编程

开发平台:

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. "syncnt"
  81. ".settreorder"
  82. : "=&r" (result), "=&r" (temp), "=m" (v->counter)
  83. : "Ir" (i), "m" (v->counter)
  84. : "memory");
  85. return result;
  86. }
  87. extern __inline__ int atomic_sub_return(int i, atomic_t * v)
  88. {
  89. unsigned long temp, result;
  90. __asm__ __volatile__(
  91. ".settnoreorderttt# atomic_sub_returnn"
  92. "1:tllt%1,%2nt"
  93. "subut%0,%1,%3nt"
  94. "sct%0,%2nt"
  95. "beqzt%0,1bnt"
  96. "subut%0,%1,%3nt"
  97. "syncnt"
  98. ".settreorder"
  99. : "=&r" (result), "=&r" (temp), "=m" (v->counter)
  100. : "Ir" (i), "m" (v->counter)
  101. : "memory");
  102. return result;
  103. }
  104. #define atomic_dec_return(v) atomic_sub_return(1,(v))
  105. #define atomic_inc_return(v) atomic_add_return(1,(v))
  106. /*
  107.  * atomic_sub_and_test - subtract value from variable and test result
  108.  * @i: integer value to subtract
  109.  * @v: pointer of type atomic_t
  110.  *
  111.  * Atomically subtracts @i from @v and returns
  112.  * true if the result is zero, or false for all
  113.  * other cases.  Note that the guaranteed
  114.  * useful range of an atomic_t is only 24 bits.
  115.  */
  116. #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
  117. /*
  118.  * atomic_inc_and_test - increment and test
  119.  * @v: pointer of type atomic_t
  120.  *
  121.  * Atomically increments @v by 1
  122.  * and returns true if the result is zero, or false for all
  123.  * other cases.  Note that the guaranteed
  124.  * useful range of an atomic_t is only 24 bits.
  125.  * atomic_inc_and_test is currently not implemented for mips64.
  126.  */
  127. /*
  128.  * atomic_dec_and_test - decrement by 1 and test
  129.  * @v: pointer of type atomic_t
  130.  *
  131.  * Atomically decrements @v by 1 and
  132.  * returns true if the result is 0, or false for all other
  133.  * cases.  Note that the guaranteed
  134.  * useful range of an atomic_t is only 24 bits.
  135.  */
  136. #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  137. /*
  138.  * atomic_inc - increment atomic variable
  139.  * @v: pointer of type atomic_t
  140.  *
  141.  * Atomically increments @v by 1.  Note that the guaranteed
  142.  * useful range of an atomic_t is only 24 bits.
  143.  */
  144. #define atomic_inc(v) atomic_add(1,(v))
  145. /*
  146.  * atomic_dec - decrement and test
  147.  * @v: pointer of type atomic_t
  148.  *
  149.  * Atomically decrements @v by 1.  Note that the guaranteed
  150.  * useful range of an atomic_t is only 24 bits.
  151.  */
  152. #define atomic_dec(v) atomic_sub(1,(v))
  153. /*
  154.  * atomic_add_negative - add and test if negative
  155.  * @v: pointer of type atomic_t
  156.  * @i: integer value to add
  157.  *
  158.  * Atomically adds @i to @v and returns true
  159.  * if the result is negative, or false when
  160.  * result is greater than or equal to zero.  Note that the guaranteed
  161.  * useful range of an atomic_t is only 24 bits.
  162.  *
  163.  * atomic_add_negative is currently not implemented for mips64.
  164.  */
  165. /* Atomic operations are already serializing */
  166. #define smp_mb__before_atomic_dec() smp_mb()
  167. #define smp_mb__after_atomic_dec() smp_mb()
  168. #define smp_mb__before_atomic_inc() smp_mb()
  169. #define smp_mb__after_atomic_inc() smp_mb()
  170. #endif /* defined(__KERNEL__) */
  171. #endif /* _ASM_ATOMIC_H */