Generic interface to atomic operations.
[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_acq
29 # define atomic_compare_and_exchange_acq(mem, newval, oldval) \
30   ({ __typeof (__arch_compare_and_exchange_32_acq (mem, newval, oldval))      \
31          __result;                                                            \
32      if (sizeof (*mem) == 1)                                                  \
33        __result = __arch_compare_and_exchange_8_acq (mem, newval, oldval);    \
34      else if (sizeof (*mem) == 2)                                             \
35        __result = __arch_compare_and_exchange_16_acq (mem, newval, oldval);   \
36      else if (sizeof (*mem) == 4)                                             \
37        __result = __arch_compare_and_exchange_32_acq (mem, newval, oldval);   \
38      else if (sizeof (*mem) == 8)                                             \
39        __result = __arch_compare_and_exchange_64_acq (mem, newval, oldval);   \
40      else                                                                     \
41        abort ();                                                              \
42      __result; })
43 #endif
44
45
46 #ifndef atomic_compare_and_exchange_rel
47 # define atomic_compare_and_exchange_rel(mem, oldval, newval) \
48   atomic_compare_and_exchange_acq (mem, oldval, newval)
49 #endif
50
51
52 #ifndef atomic_exchange_and_add
53 # define atomic_exchange_and_add(mem, value) \
54   ({ __typeof (*mem) __oldval;                                                \
55      __typeof (mem) __memp = (mem);                                           \
56      __typeof (*mem) __value = (value);                                       \
57                                                                               \
58      do                                                                       \
59        __oldval = (*__memp);                                                  \
60      while (atomic_compare_and_exchange_acq (__memp, __oldval + __value,      \
61                                              __oldval));                      \
62                                                                               \
63      __oldval + __value; })
64 #endif
65
66
67 #ifndef atomic_add
68 # define atomic_add(mem, value) (void) atomic_exchange_and_add (mem, value)
69 #endif
70
71
72 #ifndef atomic_increment
73 # define atomic_increment(mem) atomic_add (mem, 1)
74 #endif
75
76
77 #ifndef atomic_increment_and_test
78 # define atomic_increment_and_test(mem) \
79   (atomic_exchange_and_add (mem, 1) == 0)
80 #endif
81
82
83 #ifndef atomic_decrement
84 # define atomic_decrement(mem) atomic_add (mem, -1)
85 #endif
86
87
88 #ifndef atomic_decrement_and_test
89 # define atomic_decrement_and_test(mem) \
90   (atomic_exchange_and_add (mem, -1) == 0)
91 #endif
92
93
94 #ifndef atomic_add_negative
95 # define atomic_add_negative(mem, value) \
96   (atomic_exchange_and_add (mem, value) < 0)
97 #endif
98
99
100 #ifndef atomic_add_zero
101 # define atomic_add_zero(mem, value) \
102   (atomic_exchange_and_add (mem, value) == 0)
103 #endif
104
105
106 #ifndef atomic_bit_set
107 # define atomic_bit_set(mem, bit) \
108   (void) atomic_bit_test_set(mem, bit)
109 #endif
110
111
112 #ifndef atomic_bit_test_set
113 # define atomic_bit_test_set(mem, bit) \
114   ({ __typeof (*mem) __oldval;                                                \
115      __typeof (mem) __memp = (mem);                                           \
116      __typeof (*mem) __mask = (1 << (bit));                                   \
117                                                                               \
118      do                                                                       \
119        __oldval = (*__memp);                                                  \
120      while (atomic_compare_and_exchange_acq (__memp,                          \
121                                              __oldval | __mask, __oldval));   \
122                                                                               \
123      __oldval & __mask; })
124 #endif
125
126
127 #ifndef atomic_full_barrier
128 # define atomic_full_barrier() __asm ("" ::: "memory")
129 #endif
130
131
132 #ifndef atomic_read_barrier
133 # define atomic_read_barrier() atomic_full_barrier()
134 #endif
135
136
137 #ifndef atomic_write_barrier
138 # define atomic_write_barrier() atomic_full_barrier()
139 #endif
140
141 #endif  /* atomic.h */