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

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _ALPHA_ATOMIC_H
  2. #define _ALPHA_ATOMIC_H
  3. /*
  4.  * Atomic operations that C can't guarantee us.  Useful for
  5.  * resource counting etc...
  6.  *
  7.  * But use these as seldom as possible since they are much slower
  8.  * than regular operations.
  9.  */
  10. /*
  11.  * Counter is volatile to make sure gcc doesn't try to be clever
  12.  * and move things around on us. We need to use _exactly_ the address
  13.  * the user gave us, not some alias that contains the same information.
  14.  */
  15. typedef struct { volatile int counter; } atomic_t;
  16. #define ATOMIC_INIT(i) ( (atomic_t) { (i) } )
  17. #define atomic_read(v) ((v)->counter)
  18. #define atomic_set(v,i) ((v)->counter = (i))
  19. /*
  20.  * To get proper branch prediction for the main line, we must branch
  21.  * forward to code at the end of this object's .text section, then
  22.  * branch back to restart the operation.
  23.  */
  24. static __inline__ void atomic_add(int i, atomic_t * v)
  25. {
  26. unsigned long temp;
  27. __asm__ __volatile__(
  28. "1: ldl_l %0,%1n"
  29. " addl %0,%2,%0n"
  30. " stl_c %0,%1n"
  31. " beq %0,2fn"
  32. ".subsection 2n"
  33. "2: br 1bn"
  34. ".previous"
  35. :"=&r" (temp), "=m" (v->counter)
  36. :"Ir" (i), "m" (v->counter));
  37. }
  38. static __inline__ void atomic_sub(int i, atomic_t * v)
  39. {
  40. unsigned long temp;
  41. __asm__ __volatile__(
  42. "1: ldl_l %0,%1n"
  43. " subl %0,%2,%0n"
  44. " stl_c %0,%1n"
  45. " beq %0,2fn"
  46. ".subsection 2n"
  47. "2: br 1bn"
  48. ".previous"
  49. :"=&r" (temp), "=m" (v->counter)
  50. :"Ir" (i), "m" (v->counter));
  51. }
  52. /*
  53.  * Same as above, but return the result value
  54.  */
  55. static __inline__ long atomic_add_return(int i, atomic_t * v)
  56. {
  57. long temp, result;
  58. __asm__ __volatile__(
  59. "1: ldl_l %0,%1n"
  60. " addl %0,%3,%2n"
  61. " addl %0,%3,%0n"
  62. " stl_c %0,%1n"
  63. " beq %0,2fn"
  64. " mbn"
  65. ".subsection 2n"
  66. "2: br 1bn"
  67. ".previous"
  68. :"=&r" (temp), "=m" (v->counter), "=&r" (result)
  69. :"Ir" (i), "m" (v->counter) : "memory");
  70. return result;
  71. }
  72. static __inline__ long atomic_sub_return(int i, atomic_t * v)
  73. {
  74. long temp, result;
  75. __asm__ __volatile__(
  76. "1: ldl_l %0,%1n"
  77. " subl %0,%3,%2n"
  78. " subl %0,%3,%0n"
  79. " stl_c %0,%1n"
  80. " beq %0,2fn"
  81. " mbn"
  82. ".subsection 2n"
  83. "2: br 1bn"
  84. ".previous"
  85. :"=&r" (temp), "=m" (v->counter), "=&r" (result)
  86. :"Ir" (i), "m" (v->counter) : "memory");
  87. return result;
  88. }
  89. #define atomic_dec_return(v) atomic_sub_return(1,(v))
  90. #define atomic_inc_return(v) atomic_add_return(1,(v))
  91. #define atomic_sub_and_test(i,v) (atomic_sub_return((i), (v)) == 0)
  92. #define atomic_dec_and_test(v) (atomic_sub_return(1, (v)) == 0)
  93. #define atomic_inc(v) atomic_add(1,(v))
  94. #define atomic_dec(v) atomic_sub(1,(v))
  95. #define smp_mb__before_atomic_dec() smp_mb()
  96. #define smp_mb__after_atomic_dec() smp_mb()
  97. #define smp_mb__before_atomic_inc() smp_mb()
  98. #define smp_mb__after_atomic_inc() smp_mb()
  99. #endif /* _ALPHA_ATOMIC_H */