atomic.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. /* Copyright (C) 2010-2012 Free Software Foundation, Inc.
  2. This file is part of the GNU C Library.
  3. Contributed by Maxim Kuvyrkov <maxim@codesourcery.com>, 2010.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library. If not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #ifndef _BITS_ATOMIC_H
  16. #define _BITS_ATOMIC_H 1
  17. #include <stdint.h>
  18. /* This is needed to break a depencency loop, we do not need errno anyway */
  19. #ifndef _ERRNO_H
  20. # define _ERRNO_H
  21. # include <sysdep.h>
  22. # undef _ERRNO_H
  23. #else
  24. # include <sysdep.h>
  25. #endif
  26. /* Or1k has no atomic compare-and-exchange operation, but the
  27. kernel provides userspace atomicity operations. Use them. */
  28. typedef int32_t atomic32_t;
  29. typedef uint32_t uatomic32_t;
  30. typedef int_fast32_t atomic_fast32_t;
  31. typedef uint_fast32_t uatomic_fast32_t;
  32. typedef intptr_t atomicptr_t;
  33. typedef uintptr_t uatomicptr_t;
  34. typedef intmax_t atomic_max_t;
  35. typedef uintmax_t uatomic_max_t;
  36. /* TODO: Move these to a kernel header */
  37. #define OR1K_ATOMIC_SWAP 1
  38. #define OR1K_ATOMIC_CMPXCHG 2
  39. #define OR1K_ATOMIC_XCHG 3
  40. #define OR1K_ATOMIC_ADD 4
  41. #define OR1K_ATOMIC_DECPOS 5
  42. #define OR1K_ATOMIC_AND 6
  43. #define OR1K_ATOMIC_OR 7
  44. #define OR1K_ATOMIC_UMAX 8
  45. #define OR1K_ATOMIC_UMIN 9
  46. #define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
  47. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  48. INTERNAL_SYSCALL (or1k_atomic, , 4, \
  49. OR1K_ATOMIC_CMPXCHG, mem, oldval, newval) \
  50. : __atomic_error_bad_argument_size ()))
  51. #define atomic_exchange_acq(mem, newval) \
  52. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  53. INTERNAL_SYSCALL (or1k_atomic, , 3, \
  54. OR1K_ATOMIC_XCHG, mem, newval) \
  55. : __atomic_error_bad_argument_size ()))
  56. #define atomic_exchange_and_add_acq(mem, val) \
  57. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  58. INTERNAL_SYSCALL (or1k_atomic, , 3, \
  59. OR1K_ATOMIC_ADD, mem, val) \
  60. : __atomic_error_bad_argument_size ()))
  61. #define atomic_decrement_if_positive(mem) \
  62. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  63. INTERNAL_SYSCALL (or1k_atomic, , 2, \
  64. OR1K_ATOMIC_DECPOS, mem) \
  65. : __atomic_error_bad_argument_size ()))
  66. #define atomic_and_val(mem, mask) \
  67. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  68. INTERNAL_SYSCALL (or1k_atomic, , 3, \
  69. OR1K_ATOMIC_AND, mem, mask) \
  70. : __atomic_error_bad_argument_size ()))
  71. #define atomic_or_val(mem, mask) \
  72. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  73. INTERNAL_SYSCALL (or1k_atomic, , 3, \
  74. OR1K_ATOMIC_OR, mem, mask) \
  75. : __atomic_error_bad_argument_size ()))
  76. #define atomic_max_val(mem, val) \
  77. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  78. INTERNAL_SYSCALL (or1k_atomic, , 3, \
  79. OR1K_ATOMIC_UMAX, mem, val) \
  80. : __atomic_error_bad_argument_size ()))
  81. #define atomic_min_val(mem, val) \
  82. ((__typeof (*(mem))) ((sizeof (*(mem)) == 4) ? \
  83. INTERNAL_SYSCALL (or1k_atomic, , 3, \
  84. OR1K_ATOMIC_UMIN, mem, val) \
  85. : __atomic_error_bad_argument_size ()))
  86. /* atomic_bit_test_set in terms of atomic_or_val. */
  87. #define atomic_bit_test_set(mem, bit) \
  88. ({ __typeof (*(mem)) __att0_mask = ((__typeof (*(mem))) 1 << (bit)); \
  89. atomic_or_val ((mem), __att0_mask) & __att0_mask; })
  90. /* Various macros that should just be synonyms. */
  91. #define catomic_exchange_and_add atomic_exchange_and_add
  92. #define atomic_and(mem, mask) ((void) atomic_and_val ((mem), (mask)))
  93. #define catomic_and atomic_and
  94. #define atomic_or(mem, mask) ((void) atomic_or_val ((mem), (mask)))
  95. #define catomic_or atomic_or
  96. #define atomic_max(mem, val) ((void)atomic_max_val ((mem), (val)))
  97. #define catomic_max atomic_max
  98. #define atomic_min(mem, val) ((void)atomic_min_val ((mem), (val)))
  99. #define catomic_min atomic_min
  100. /*
  101. * This non-existent symbol is called for unsupporrted sizes,
  102. * indicating a bug in the caller.
  103. */
  104. extern int __atomic_error_bad_argument_size(void)
  105. __attribute__ ((error ("bad sizeof atomic argument")));
  106. #endif