2 * Copyright © 2011 Ryan Lortie
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * licence, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19 * Author: Ryan Lortie <desrt@desrt.ca>
22 #if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
23 #error "Only <glib.h> can be included directly."
26 #ifndef __G_ATOMIC_H__
27 #define __G_ATOMIC_H__
29 #include <glib/gtypes.h>
33 gint g_atomic_int_get (volatile gint *atomic);
34 void g_atomic_int_set (volatile gint *atomic,
36 void g_atomic_int_inc (volatile gint *atomic);
37 gboolean g_atomic_int_dec_and_test (volatile gint *atomic);
38 gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic,
41 gint g_atomic_int_add (volatile gint *atomic,
43 guint g_atomic_int_and (volatile guint *atomic,
45 guint g_atomic_int_or (volatile guint *atomic,
47 guint g_atomic_int_xor (volatile guint *atomic,
50 gpointer g_atomic_pointer_get (volatile void *atomic);
51 void g_atomic_pointer_set (volatile void *atomic,
53 gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic,
56 gssize g_atomic_pointer_add (volatile void *atomic,
58 gsize g_atomic_pointer_and (volatile void *atomic,
60 gsize g_atomic_pointer_or (volatile void *atomic,
62 gsize g_atomic_pointer_xor (volatile void *atomic,
65 #ifndef G_DISABLE_DEPRECATED
66 gint g_atomic_int_exchange_and_add (volatile gint *atomic,
72 #if defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS)
74 #define g_atomic_int_get(atomic) \
76 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
77 (void) (0 ? *(atomic) ^ *(atomic) : 0); \
78 __sync_synchronize (); \
81 #define g_atomic_int_set(atomic, newval) \
83 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
84 (void) (0 ? *(atomic) ^ (newval) : 0); \
85 *(atomic) = (newval); \
86 __sync_synchronize (); \
88 #define g_atomic_int_inc(atomic) \
90 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
91 (void) (0 ? *(atomic) ^ *(atomic) : 0); \
92 (void) __sync_fetch_and_add ((atomic), 1); \
94 #define g_atomic_int_dec_and_test(atomic) \
96 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
97 (void) (0 ? *(atomic) ^ *(atomic) : 0); \
98 __sync_fetch_and_sub ((atomic), 1) == 1; \
100 #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
102 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
103 (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 0); \
104 (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \
106 #define g_atomic_int_add(atomic, val) \
108 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
109 (void) (0 ? *(atomic) ^ (val) : 0); \
110 (gint) __sync_fetch_and_add ((atomic), (val)); \
112 #define g_atomic_int_and(atomic, val) \
114 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
115 (void) (0 ? *(atomic) ^ (val) : 0); \
116 (guint) __sync_fetch_and_and ((atomic), (val)); \
118 #define g_atomic_int_or(atomic, val) \
120 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
121 (void) (0 ? *(atomic) ^ (val) : 0); \
122 (guint) __sync_fetch_and_or ((atomic), (val)); \
124 #define g_atomic_int_xor(atomic, val) \
126 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
127 (void) (0 ? *(atomic) ^ (val) : 0); \
128 (guint) __sync_fetch_and_xor ((atomic), (val)); \
131 #define g_atomic_pointer_get(atomic) \
133 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
134 __sync_synchronize (); \
135 (gpointer) *(atomic); \
137 #define g_atomic_pointer_set(atomic, newval) \
139 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
140 (void) (0 ? (gpointer) *(atomic) : 0); \
141 *(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \
142 __sync_synchronize (); \
144 #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
146 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
147 (void) (0 ? (gpointer) *(atomic) : 0); \
148 (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \
150 #define g_atomic_pointer_add(atomic, val) \
152 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
153 (void) (0 ? (gpointer) *(atomic) : 0); \
154 (void) (0 ? (val) ^ (val) : 0); \
155 (gssize) __sync_fetch_and_add ((atomic), (val)); \
157 #define g_atomic_pointer_and(atomic, val) \
159 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
160 (void) (0 ? (gpointer) *(atomic) : 0); \
161 (void) (0 ? (val) ^ (val) : 0); \
162 (gsize) __sync_fetch_and_and ((atomic), (val)); \
164 #define g_atomic_pointer_or(atomic, val) \
166 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
167 (void) (0 ? (gpointer) *(atomic) : 0); \
168 (void) (0 ? (val) ^ (val) : 0); \
169 (gsize) __sync_fetch_and_or ((atomic), (val)); \
171 #define g_atomic_pointer_xor(atomic, val) \
173 G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
174 (void) (0 ? (gpointer) *(atomic) : 0); \
175 (void) (0 ? (val) ^ (val) : 0); \
176 (gsize) __sync_fetch_and_xor ((atomic), (val)); \
179 #else /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */
181 #define g_atomic_int_get(atomic) \
182 (g_atomic_int_get ((gint *) (atomic)))
183 #define g_atomic_int_set(atomic, newval) \
184 (g_atomic_int_set ((gint *) (atomic), (gint) (newval)))
185 #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \
186 (g_atomic_int_compare_and_exchange ((gint *) (atomic), (oldval), (newval)))
187 #define g_atomic_int_add(atomic, val) \
188 (g_atomic_int_add ((gint *) (atomic), (val)))
189 #define g_atomic_int_and(atomic, val) \
190 (g_atomic_int_and ((gint *) (atomic), (val)))
191 #define g_atomic_int_or(atomic, val) \
192 (g_atomic_int_or ((gint *) (atomic), (val)))
193 #define g_atomic_int_xor(atomic, val) \
194 (g_atomic_int_xor ((gint *) (atomic), (val)))
195 #define g_atomic_int_inc(atomic) \
196 (g_atomic_int_inc ((gint *) (atomic)))
197 #define g_atomic_int_dec_and_test(atomic) \
198 (g_atomic_int_dec_and_test ((gint *) (atomic)))
200 #define g_atomic_pointer_get(atomic) \
201 (g_atomic_pointer_get (atomic))
202 #define g_atomic_pointer_set(atomic, newval) \
203 (g_atomic_pointer_set ((atomic), (gpointer) (newval)))
204 #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \
205 (g_atomic_pointer_compare_and_exchange ((atomic), (gpointer) (oldval), (gpointer) (newval)))
206 #define g_atomic_pointer_add(atomic, val) \
207 (g_atomic_pointer_add ((atomic), (gssize) (val)))
208 #define g_atomic_pointer_and(atomic, val) \
209 (g_atomic_pointer_and ((atomic), (gsize) (val)))
210 #define g_atomic_pointer_or(atomic, val) \
211 (g_atomic_pointer_or ((atomic), (gsize) (val)))
212 #define g_atomic_pointer_xor(atomic, val) \
213 (g_atomic_pointer_xor ((atomic), (gsize) (val)))
215 #endif /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */
217 #endif /* __G_ATOMIC_H__ */