atomic.h 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /*
  2. * PowerPC atomic operations
  3. */
  4. #ifndef _ASM_PPC_ATOMIC_H_
  5. #define _ASM_PPC_ATOMIC_H_
  6. #ifdef CONFIG_SMP
  7. typedef struct { volatile int counter; } atomic_t;
  8. #else
  9. typedef struct { int counter; } atomic_t;
  10. #endif
  11. #define ATOMIC_INIT(i) { (i) }
  12. #define atomic_read(v) ((v)->counter)
  13. #define atomic_set(v,i) (((v)->counter) = (i))
  14. extern void atomic_clear_mask(unsigned long mask, unsigned long *addr);
  15. extern void atomic_set_mask(unsigned long mask, unsigned long *addr);
  16. static __inline__ int atomic_add_return(int a, atomic_t *v)
  17. {
  18. int t;
  19. __asm__ __volatile__("\n\
  20. 1: lwarx %0,0,%3\n\
  21. add %0,%2,%0\n\
  22. stwcx. %0,0,%3\n\
  23. bne- 1b"
  24. : "=&r" (t), "=m" (*v)
  25. : "r" (a), "r" (v), "m" (*v)
  26. : "cc");
  27. return t;
  28. }
  29. static __inline__ int atomic_sub_return(int a, atomic_t *v)
  30. {
  31. int t;
  32. __asm__ __volatile__("\n\
  33. 1: lwarx %0,0,%3\n\
  34. subf %0,%2,%0\n\
  35. stwcx. %0,0,%3\n\
  36. bne- 1b"
  37. : "=&r" (t), "=m" (*v)
  38. : "r" (a), "r" (v), "m" (*v)
  39. : "cc");
  40. return t;
  41. }
  42. static __inline__ int atomic_inc_return(atomic_t *v)
  43. {
  44. int t;
  45. __asm__ __volatile__("\n\
  46. 1: lwarx %0,0,%2\n\
  47. addic %0,%0,1\n\
  48. stwcx. %0,0,%2\n\
  49. bne- 1b"
  50. : "=&r" (t), "=m" (*v)
  51. : "r" (v), "m" (*v)
  52. : "cc");
  53. return t;
  54. }
  55. static __inline__ int atomic_dec_return(atomic_t *v)
  56. {
  57. int t;
  58. __asm__ __volatile__("\n\
  59. 1: lwarx %0,0,%2\n\
  60. addic %0,%0,-1\n\
  61. stwcx. %0,0,%2\n\
  62. bne 1b"
  63. : "=&r" (t), "=m" (*v)
  64. : "r" (v), "m" (*v)
  65. : "cc");
  66. return t;
  67. }
  68. #define atomic_add(a, v) ((void) atomic_add_return((a), (v)))
  69. #define atomic_sub(a, v) ((void) atomic_sub_return((a), (v)))
  70. #define atomic_sub_and_test(a, v) (atomic_sub_return((a), (v)) == 0)
  71. #define atomic_inc(v) ((void) atomic_inc_return((v)))
  72. #define atomic_dec(v) ((void) atomic_dec_return((v)))
  73. #define atomic_dec_and_test(v) (atomic_dec_return((v)) == 0)
  74. #endif /* _ASM_PPC_ATOMIC_H_ */