]> git.ipfire.org Git - thirdparty/glibc.git/blob - ports/sysdeps/arm/bits/atomic.h
Update copyright notices with scripts/update-copyrights
[thirdparty/glibc.git] / ports / sysdeps / arm / bits / atomic.h
1 /* Atomic operations. Pure ARM version.
2 Copyright (C) 2002-2014 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
14
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library. If not, see
17 <http://www.gnu.org/licenses/>. */
18
19 #include <stdint.h>
20
21 typedef int8_t atomic8_t;
22 typedef uint8_t uatomic8_t;
23 typedef int_fast8_t atomic_fast8_t;
24 typedef uint_fast8_t uatomic_fast8_t;
25
26 typedef int32_t atomic32_t;
27 typedef uint32_t uatomic32_t;
28 typedef int_fast32_t atomic_fast32_t;
29 typedef uint_fast32_t uatomic_fast32_t;
30
31 typedef intptr_t atomicptr_t;
32 typedef uintptr_t uatomicptr_t;
33 typedef intmax_t atomic_max_t;
34 typedef uintmax_t uatomic_max_t;
35
36 void __arm_link_error (void);
37
38 #ifdef __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
39 # define atomic_full_barrier() __sync_synchronize ()
40 #else
41 # define atomic_full_barrier() __arm_assisted_full_barrier ()
42 #endif
43
44 /* An OS-specific bits/atomic.h file will define this macro if
45 the OS can provide something. If not, we'll fail to build
46 with a compiler that doesn't supply the operation. */
47 #ifndef __arm_assisted_full_barrier
48 # define __arm_assisted_full_barrier() __arm_link_error()
49 #endif
50
51 /* Use the atomic builtins provided by GCC in case the backend provides
52 a pattern to do this efficiently. */
53 #if __GNUC_PREREQ (4, 7) && defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
54
55 # define atomic_exchange_acq(mem, value) \
56 __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_ACQUIRE)
57
58 # define atomic_exchange_rel(mem, value) \
59 __atomic_val_bysize (__arch_exchange, int, mem, value, __ATOMIC_RELEASE)
60
61 /* Atomic exchange (without compare). */
62
63 # define __arch_exchange_8_int(mem, newval, model) \
64 (__arm_link_error (), (typeof (*mem)) 0)
65
66 # define __arch_exchange_16_int(mem, newval, model) \
67 (__arm_link_error (), (typeof (*mem)) 0)
68
69 # define __arch_exchange_32_int(mem, newval, model) \
70 __atomic_exchange_n (mem, newval, model)
71
72 # define __arch_exchange_64_int(mem, newval, model) \
73 (__arm_link_error (), (typeof (*mem)) 0)
74
75 /* Compare and exchange with "acquire" semantics, ie barrier after. */
76
77 # define atomic_compare_and_exchange_bool_acq(mem, new, old) \
78 __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
79 mem, new, old, __ATOMIC_ACQUIRE)
80
81 # define atomic_compare_and_exchange_val_acq(mem, new, old) \
82 __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
83 mem, new, old, __ATOMIC_ACQUIRE)
84
85 /* Compare and exchange with "release" semantics, ie barrier before. */
86
87 # define atomic_compare_and_exchange_bool_rel(mem, new, old) \
88 __atomic_bool_bysize (__arch_compare_and_exchange_bool, int, \
89 mem, new, old, __ATOMIC_RELEASE)
90
91 # define atomic_compare_and_exchange_val_rel(mem, new, old) \
92 __atomic_val_bysize (__arch_compare_and_exchange_val, int, \
93 mem, new, old, __ATOMIC_RELEASE)
94
95 /* Compare and exchange.
96 For all "bool" routines, we return FALSE if exchange succesful. */
97
98 # define __arch_compare_and_exchange_bool_8_int(mem, newval, oldval, model) \
99 ({__arm_link_error (); oldval; })
100
101 # define __arch_compare_and_exchange_bool_16_int(mem, newval, oldval, model) \
102 ({__arm_link_error (); oldval; })
103
104 # define __arch_compare_and_exchange_bool_32_int(mem, newval, oldval, model) \
105 ({ \
106 typeof (*mem) __oldval = (oldval); \
107 !__atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
108 model, __ATOMIC_RELAXED); \
109 })
110
111 # define __arch_compare_and_exchange_bool_64_int(mem, newval, oldval, model) \
112 ({__arm_link_error (); oldval; })
113
114 # define __arch_compare_and_exchange_val_8_int(mem, newval, oldval, model) \
115 ({__arm_link_error (); oldval; })
116
117 # define __arch_compare_and_exchange_val_16_int(mem, newval, oldval, model) \
118 ({__arm_link_error (); oldval; })
119
120 # define __arch_compare_and_exchange_val_32_int(mem, newval, oldval, model) \
121 ({ \
122 typeof (*mem) __oldval = (oldval); \
123 __atomic_compare_exchange_n (mem, (void *) &__oldval, newval, 0, \
124 model, __ATOMIC_RELAXED); \
125 __oldval; \
126 })
127
128 # define __arch_compare_and_exchange_val_64_int(mem, newval, oldval, model) \
129 ({__arm_link_error (); oldval; })
130
131 #elif defined __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
132 /* Atomic compare and exchange. */
133 # define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
134 __sync_val_compare_and_swap ((mem), (oldval), (newval))
135 #else
136 # define __arch_compare_and_exchange_val_32_acq(mem, newval, oldval) \
137 __arm_assisted_compare_and_exchange_val_32_acq ((mem), (newval), (oldval))
138 #endif
139
140 #if !__GNUC_PREREQ (4, 7) || !defined (__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
141 /* We don't support atomic operations on any non-word types.
142 So make them link errors. */
143 # define __arch_compare_and_exchange_val_8_acq(mem, newval, oldval) \
144 ({ __arm_link_error (); oldval; })
145
146 # define __arch_compare_and_exchange_val_16_acq(mem, newval, oldval) \
147 ({ __arm_link_error (); oldval; })
148
149 # define __arch_compare_and_exchange_val_64_acq(mem, newval, oldval) \
150 ({ __arm_link_error (); oldval; })
151 #endif
152
153 /* An OS-specific bits/atomic.h file will define this macro if
154 the OS can provide something. If not, we'll fail to build
155 with a compiler that doesn't supply the operation. */
156 #ifndef __arm_assisted_compare_and_exchange_val_32_acq
157 # define __arm_assisted_compare_and_exchange_val_32_acq(mem, newval, oldval) \
158 ({ __arm_link_error (); oldval; })
159 #endif