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

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * PowerPC64 atomic operations
  3.  *
  4.  * Copyright (C) 2001 Paul Mackerras <paulus@au.ibm.com>, IBM
  5.  * Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
  6.  *
  7.  * This program is free software; you can redistribute it and/or
  8.  * modify it under the terms of the GNU General Public License
  9.  * as published by the Free Software Foundation; either version
  10.  * 2 of the License, or (at your option) any later version.
  11.  */
  12. #ifndef _ASM_PPC64_ATOMIC_H_ 
  13. #define _ASM_PPC64_ATOMIC_H_
  14. #include <asm/memory.h>
  15. typedef struct { volatile int counter; } atomic_t;
  16. #define ATOMIC_INIT(i) { (i) }
  17. #define atomic_read(v) ((v)->counter)
  18. #define atomic_set(v,i) (((v)->counter) = (i))
  19. static __inline__ void atomic_add(int a, atomic_t *v)
  20. {
  21. int t;
  22. __asm__ __volatile__(
  23. "1: lwarx %0,0,%3 # atomic_addn
  24. add %0,%2,%0n
  25. stwcx. %0,0,%3n
  26. bne- 1b"
  27. : "=&r" (t), "=m" (v->counter)
  28. : "r" (a), "r" (&v->counter), "m" (v->counter)
  29. : "cc");
  30. }
  31. static __inline__ int atomic_add_return(int a, atomic_t *v)
  32. {
  33. int t;
  34. __asm__ __volatile__(
  35. "1: lwarx %0,0,%2 # atomic_add_returnn
  36. add %0,%1,%0n
  37. stwcx. %0,0,%2n
  38. bne- 1b"
  39. ISYNC_ON_SMP
  40. : "=&r" (t)
  41. : "r" (a), "r" (&v->counter)
  42. : "cc", "memory");
  43. return t;
  44. }
  45. static __inline__ void atomic_sub(int a, atomic_t *v)
  46. {
  47. int t;
  48. __asm__ __volatile__(
  49. "1: lwarx %0,0,%3 # atomic_subn
  50. subf %0,%2,%0n
  51. stwcx. %0,0,%3n
  52. bne- 1b"
  53. : "=&r" (t), "=m" (v->counter)
  54. : "r" (a), "r" (&v->counter), "m" (v->counter)
  55. : "cc");
  56. }
  57. static __inline__ int atomic_sub_return(int a, atomic_t *v)
  58. {
  59. int t;
  60. __asm__ __volatile__(
  61. "1: lwarx %0,0,%2 # atomic_sub_returnn
  62. subf %0,%1,%0n
  63. stwcx. %0,0,%2n
  64. bne- 1b"
  65. ISYNC_ON_SMP
  66. : "=&r" (t)
  67. : "r" (a), "r" (&v->counter)
  68. : "cc", "memory");
  69. return t;
  70. }
  71. static __inline__ void atomic_inc(atomic_t *v)
  72. {
  73. int t;
  74. __asm__ __volatile__(
  75. "1: lwarx %0,0,%2 # atomic_incn
  76. addic %0,%0,1n
  77. stwcx. %0,0,%2n
  78. bne- 1b"
  79. : "=&r" (t), "=m" (v->counter)
  80. : "r" (&v->counter), "m" (v->counter)
  81. : "cc");
  82. }
  83. static __inline__ int atomic_inc_return(atomic_t *v)
  84. {
  85. int t;
  86. __asm__ __volatile__(
  87. "1: lwarx %0,0,%1 # atomic_inc_returnn
  88. addic %0,%0,1n
  89. stwcx. %0,0,%1n
  90. bne- 1b"
  91. ISYNC_ON_SMP
  92. : "=&r" (t)
  93. : "r" (&v->counter)
  94. : "cc", "memory");
  95. return t;
  96. }
  97. static __inline__ void atomic_dec(atomic_t *v)
  98. {
  99. int t;
  100. __asm__ __volatile__(
  101. "1: lwarx %0,0,%2 # atomic_decn
  102. addic %0,%0,-1n
  103. stwcx. %0,0,%2n
  104. bne- 1b"
  105. : "=&r" (t), "=m" (v->counter)
  106. : "r" (&v->counter), "m" (v->counter)
  107. : "cc");
  108. }
  109. static __inline__ int atomic_dec_return(atomic_t *v)
  110. {
  111. int t;
  112. __asm__ __volatile__(
  113. "1: lwarx %0,0,%1 # atomic_dec_returnn
  114. addic %0,%0,-1n
  115. stwcx. %0,0,%1n
  116. bne- 1b"
  117. ISYNC_ON_SMP
  118. : "=&r" (t)
  119. : "r" (&v->counter)
  120. : "cc", "memory");
  121. return t;
  122. }
  123. #define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
  124. #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
  125. /*
  126.  * Atomically test *v and decrement if it is greater than 0.
  127.  * The function returns the old value of *v minus 1.
  128.  */
  129. static __inline__ int atomic_dec_if_positive(atomic_t *v)
  130. {
  131. int t;
  132. __asm__ __volatile__(
  133. "1: lwarx %0,0,%1 # atomic_dec_if_positiven
  134. addic. %0,%0,-1n
  135. blt- 2fn
  136. stwcx. %0,0,%1n
  137. bne- 1b"
  138. ISYNC_ON_SMP
  139. "n
  140. 2:" : "=&r" (t)
  141. : "r" (&v->counter)
  142. : "cc", "memory");
  143. return t;
  144. }
  145. #define smp_mb__before_atomic_dec()     smp_mb()
  146. #define smp_mb__after_atomic_dec()      smp_mb()
  147. #define smp_mb__before_atomic_inc()     smp_mb()
  148. #define smp_mb__after_atomic_inc()      smp_mb()
  149. #endif /* _ASM_PPC64_ATOMIC_H_ */