atomic.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. /*
  2. * Copyright (C) 2007 Atmel Corporation
  3. *
  4. * This file is subject to the terms and conditions of the GNU Lesser General
  5. * Public License. See the file "COPYING.LIB" in the main directory of this
  6. * archive for more details.
  7. */
  8. #ifndef _AVR32_BITS_ATOMIC_H
  9. #define _AVR32_BITS_ATOMIC_H 1
  10. #include <inttypes.h>
  11. typedef int32_t atomic32_t;
  12. typedef uint32_t uatomic32_t;
  13. typedef int_fast32_t atomic_fast32_t;
  14. typedef uint_fast32_t uatomic_fast32_t;
  15. typedef intptr_t atomicptr_t;
  16. typedef uintptr_t uatomicptr_t;
  17. typedef intmax_t atomic_max_t;
  18. typedef uintmax_t uatomic_max_t;
  19. #define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
  20. (abort(), 0)
  21. #define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
  22. (abort(), 0)
  23. #define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
  24. ({ \
  25. __uint32_t __result; \
  26. __typeof__(*(mem)) __prev; \
  27. __asm__ __volatile__( \
  28. "/* __arch_compare_and_exchange_val_32_acq */\n" \
  29. "1: ssrf 5\n" \
  30. " ld.w %[result], %[m]\n" \
  31. " cp.w %[result], %[old]\n" \
  32. " brne 2f\n" \
  33. " stcond %[m], %[new]\n" \
  34. " brne 1b\n" \
  35. "2:" \
  36. : [result] "=&r"(__result), [m] "=m"(*(mem)) \
  37. : "m"(*(mem)), [old] "ir"(oldval), \
  38. [new] "r"(newval) \
  39. : "memory", "cc"); \
  40. __prev; \
  41. })
  42. #define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
  43. (abort(), 0)
  44. #define __arch_exchange_32_acq(mem, newval) \
  45. ({ \
  46. __typeof__(*(mem)) __oldval; \
  47. __asm__ __volatile__( \
  48. "/*__arch_exchange_32_acq */\n" \
  49. " xchg %[old], %[m], %[new]" \
  50. : [old] "=&r"(__oldval) \
  51. : [m] "r"(mem), [new] "r"(newval) \
  52. : "memory"); \
  53. __oldval; \
  54. })
  55. #define __arch_atomic_exchange_and_add_32(mem, value) \
  56. ({ \
  57. __typeof__(*(mem)) __oldval, __tmp; \
  58. __asm__ __volatile__( \
  59. "/* __arch_atomic_exchange_and_add_32 */\n" \
  60. "1: ssrf 5\n" \
  61. " ld.w %[old], %[m]\n" \
  62. " add %[tmp], %[old], %[val]\n" \
  63. " stcond %[m], %[tmp]\n" \
  64. " brne 1b" \
  65. : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp), \
  66. [m] "=m"(*(mem)) \
  67. : "m"(*(mem)), [val] "r"(value) \
  68. : "memory", "cc"); \
  69. __oldval; \
  70. })
  71. #define __arch_atomic_decrement_if_positive_32(mem) \
  72. ({ \
  73. __typeof__(*(mem)) __oldval, __tmp; \
  74. __asm__ __volatile__( \
  75. "/* __arch_atomic_decrement_if_positive_32 */\n" \
  76. "1: ssrf 5\n" \
  77. " ld.w %[old], %[m]\n" \
  78. " sub %[tmp], %[old], 1\n" \
  79. " brlt 2f\n" \
  80. " stcond %[m], %[tmp]\n" \
  81. " brne 1b" \
  82. "2:" \
  83. : [old] "=&r"(__oldval), [tmp] "=&r"(__tmp), \
  84. [m] "=m"(*(mem)) \
  85. : "m"(*(mem)) \
  86. : "memory", "cc"); \
  87. __oldval; \
  88. })
  89. #define atomic_exchange_acq(mem, newval) \
  90. ({ \
  91. if (sizeof(*(mem)) != 4) \
  92. abort(); \
  93. __arch_exchange_32_acq(mem, newval); \
  94. })
  95. #define atomic_exchange_and_add(mem, newval) \
  96. ({ \
  97. if (sizeof(*(mem)) != 4) \
  98. abort(); \
  99. __arch_atomic_exchange_and_add_32(mem, newval); \
  100. })
  101. #define atomic_decrement_if_positive(mem) \
  102. ({ \
  103. if (sizeof(*(mem)) != 4) \
  104. abort(); \
  105. __arch_atomic_decrement_if_positive_32(mem); \
  106. })
  107. #endif /* _AVR32_BITS_ATOMIC_H */