Define atomic_compare_and_exchange_val_acq,
[kopensolaris-gnu/glibc.git] / include / atomic.h
1 /* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #ifndef _ATOMIC_H
21 #define _ATOMIC_H       1
22
23 #include <stdlib.h>
24
25 #include <bits/atomic.h>
26
27
28 #ifndef atomic_compare_and_exchange_val_acq
29 # define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
30   ({ __typeof (*mem) __result;                                                \
31      if (sizeof (*mem) == 1)                                                  \
32        __result = __arch_compare_and_exchange_val_8_acq (mem, newval, oldval);\
33      else if (sizeof (*mem) == 2)                                             \
34        __result = __arch_compare_and_exchange_val_16_acq (mem, newval,oldval);\
35      else if (sizeof (*mem) == 4)                                             \
36        __result = __arch_compare_and_exchange_val_32_acq (mem, newval,oldval);\
37      else if (sizeof (*mem) == 8)                                             \
38        __result = __arch_compare_and_exchange_val_64_acq (mem, newval,oldval);\
39      else                                                                     \
40        abort ();                                                              \
41      __result; })
42 #endif
43
44
45 #ifndef atomic_compare_and_exchange_val_rel
46 # define atomic_compare_and_exchange_val_rel(mem, oldval, newval) \
47   atomic_compare_and_exchange_val_acq (mem, oldval, newval)
48 #endif
49
50
51 #ifndef atomic_compare_and_exchange_bool_acq
52 # ifdef __arch_compare_and_exchange_bool_32_acq
53 #  define atomic_compare_and_exchange_val_acq(mem, newval, oldval) \
54   ({ __typeof (__arch_compare_and_exchange_bool_32_acq (mem, 0, 0)) __result; \
55      if (sizeof (*mem) == 1)                                                  \
56        __result = __arch_compare_and_exchange_bool_8_acq (mem, newval,        \
57                                                           oldval);            \
58      else if (sizeof (*mem) == 2)                                             \
59        __result = __arch_compare_and_exchange_bool_16_acq (mem, newval,       \
60                                                            oldval);           \
61      else if (sizeof (*mem) == 4)                                             \
62        __result = __arch_compare_and_exchange_bool_32_acq (mem, newval,       \
63                                                            oldval);           \
64      else if (sizeof (*mem) == 8)                                             \
65        __result = __arch_compare_and_exchange_bool_64_acq (mem, newval,       \
66                                                            oldval);           \
67      else                                                                     \
68        abort ();                                                              \
69      __result; })
70 # else
71 #  define atomic_compare_and_exchange_bool_acq(mem, newval, oldval) \
72   ({ __typeof (oldval) __oldval = (oldval);                                   \
73      atomic_compare_and_exchange_val_acq (mem, newval, __oldval) != __oldval; \
74   })
75 # endif
76 #endif
77
78
79 #ifndef atomic_compare_and_exchange_bool_rel
80 # define atomic_compare_and_exchange_bool_rel(mem, oldval, newval) \
81   atomic_compare_and_exchange_bool_acq (mem, oldval, newval)
82 #endif
83
84
85 /* Store NEWVALUE in *MEM and return the old value.  */
86 #ifndef atomic_exchange
87 # define atomic_exchange(mem, newvalue) \
88   ({ __typeof (*mem) __oldval;                                                \
89      __typeof (mem) __memp = (mem);                                           \
90      __typeof (*mem) __value = (newvalue);                                    \
91                                                                               \
92      do                                                                       \
93        __oldval = (*__memp);                                                  \
94      while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
95                                                                     __value,  \
96                                                                     __oldval),\
97                               0));                                            \
98                                                                               \
99      __oldval; })
100 #endif
101
102
103 /* Add VALUE to *MEM and return the old value of *MEM.  */
104 #ifndef atomic_exchange_and_add
105 # define atomic_exchange_and_add(mem, value) \
106   ({ __typeof (*mem) __oldval;                                                \
107      __typeof (mem) __memp = (mem);                                           \
108      __typeof (*mem) __value = (value);                                       \
109                                                                               \
110      do                                                                       \
111        __oldval = (*__memp);                                                  \
112      while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
113                                                                     __oldval  \
114                                                                     + __value,\
115                                                                     __oldval),\
116                               0));                                            \
117                                                                               \
118      __oldval; })
119 #endif
120
121
122 #ifndef atomic_add
123 # define atomic_add(mem, value) (void) atomic_exchange_and_add (mem, value)
124 #endif
125
126
127 #ifndef atomic_increment
128 # define atomic_increment(mem) atomic_add (mem, 1)
129 #endif
130
131
132 #ifndef atomic_increment_and_test
133 # define atomic_increment_and_test(mem) \
134   (atomic_exchange_and_add (mem, 1) == 0)
135 #endif
136
137
138 #ifndef atomic_decrement
139 # define atomic_decrement(mem) atomic_add (mem, -1)
140 #endif
141
142
143 #ifndef atomic_decrement_and_test
144 # define atomic_decrement_and_test(mem) \
145   (atomic_exchange_and_add (mem, -1) == 0)
146 #endif
147
148
149 /* Decrement *MEM if it is > 0, and return the old value.  */
150 #ifndef atomic_decrement_if_positive
151 # define atomic_decrement_if_positive(mem) \
152   ({ __typeof (*mem) __oldval;                                                \
153      __typeof (mem) __memp;                                                   \
154                                                                               \
155      __val = *__memp;                                                         \
156      do                                                                       \
157        {                                                                      \
158          __oldval = *__memp;                                                  \
159          if (__builtin_expect (__oldval <= 0, 0))                             \
160            break;                                                             \
161        }                                                                      \
162      while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
163                                                                     __oldval  \
164                                                                     - 1,      \
165                                                                     __oldval),\
166                               0));\
167      __oldval; })
168 #endif
169
170
171 #ifndef atomic_add_negative
172 # define atomic_add_negative(mem, value) \
173   (atomic_exchange_and_add (mem, value) < 0)
174 #endif
175
176
177 #ifndef atomic_add_zero
178 # define atomic_add_zero(mem, value) \
179   (atomic_exchange_and_add (mem, value) == 0)
180 #endif
181
182
183 #ifndef atomic_bit_set
184 # define atomic_bit_set(mem, bit) \
185   (void) atomic_bit_test_set(mem, bit)
186 #endif
187
188
189 #ifndef atomic_bit_test_set
190 # define atomic_bit_test_set(mem, bit) \
191   ({ __typeof (*mem) __oldval;                                                \
192      __typeof (mem) __memp = (mem);                                           \
193      __typeof (*mem) __mask = (1 << (bit));                                   \
194                                                                               \
195      do                                                                       \
196        __oldval = (*__memp);                                                  \
197      while (__builtin_expect (atomic_compare_and_exchange_bool_acq (__memp,   \
198                                                                     __oldval  \
199                                                                     | __mask, \
200                                                                     __oldval),\
201                               0));                                            \
202                                                                               \
203      __oldval & __mask; })
204 #endif
205
206
207 #ifndef atomic_full_barrier
208 # define atomic_full_barrier() __asm ("" ::: "memory")
209 #endif
210
211
212 #ifndef atomic_read_barrier
213 # define atomic_read_barrier() atomic_full_barrier()
214 #endif
215
216
217 #ifndef atomic_write_barrier
218 # define atomic_write_barrier() atomic_full_barrier()
219 #endif
220
221 #endif  /* atomic.h */