X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=glib%2Fgatomic.h;h=9d04b1dfdbebf743b8db98defa87d294b5dadf56;hb=49b59e5ac4428a6a99a85d699c3662f96efc4e9d;hp=8b43bf0988455c6fa68d051e7dba2884328364ee;hpb=08d6e1147d2e6e3abf85ae7a399c689609a7b761;p=platform%2Fupstream%2Fglib.git diff --git a/glib/gatomic.h b/glib/gatomic.h index 8b43bf0..9d04b1d 100644 --- a/glib/gatomic.h +++ b/glib/gatomic.h @@ -12,172 +12,235 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, - * USA. + * License along with this library; if not, see . * * Author: Ryan Lortie */ -#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) -#error "Only can be included directly." -#endif - #ifndef __G_ATOMIC_H__ #define __G_ATOMIC_H__ +#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION) +#error "Only can be included directly." +#endif + #include G_BEGIN_DECLS -gint g_atomic_int_get (volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL +gint g_atomic_int_get (const volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL void g_atomic_int_set (volatile gint *atomic, gint newval); +GLIB_AVAILABLE_IN_ALL void g_atomic_int_inc (volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL gboolean g_atomic_int_dec_and_test (volatile gint *atomic); +GLIB_AVAILABLE_IN_ALL gboolean g_atomic_int_compare_and_exchange (volatile gint *atomic, gint oldval, gint newval); +GLIB_AVAILABLE_IN_ALL gint g_atomic_int_add (volatile gint *atomic, gint val); +GLIB_AVAILABLE_IN_2_30 guint g_atomic_int_and (volatile guint *atomic, guint val); +GLIB_AVAILABLE_IN_2_30 guint g_atomic_int_or (volatile guint *atomic, guint val); +GLIB_AVAILABLE_IN_ALL guint g_atomic_int_xor (volatile guint *atomic, guint val); -gpointer g_atomic_pointer_get (volatile void *atomic); +GLIB_AVAILABLE_IN_ALL +gpointer g_atomic_pointer_get (const volatile void *atomic); +GLIB_AVAILABLE_IN_ALL void g_atomic_pointer_set (volatile void *atomic, gpointer newval); +GLIB_AVAILABLE_IN_ALL gboolean g_atomic_pointer_compare_and_exchange (volatile void *atomic, gpointer oldval, gpointer newval); +GLIB_AVAILABLE_IN_ALL gssize g_atomic_pointer_add (volatile void *atomic, gssize val); +GLIB_AVAILABLE_IN_2_30 gsize g_atomic_pointer_and (volatile void *atomic, gsize val); +GLIB_AVAILABLE_IN_2_30 gsize g_atomic_pointer_or (volatile void *atomic, gsize val); +GLIB_AVAILABLE_IN_ALL gsize g_atomic_pointer_xor (volatile void *atomic, gsize val); -#ifndef G_DISABLE_DEPRECATED -GLIB_DEPRECATED_FOR(g_atomic_add) +GLIB_DEPRECATED_IN_2_30_FOR(g_atomic_int_add) gint g_atomic_int_exchange_and_add (volatile gint *atomic, gint val); -#endif G_END_DECLS -#if defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) +#if defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) + +/* We prefer the new C11-style atomic extension of GCC if available */ +#if defined(__ATOMIC_SEQ_CST) && !defined(__clang__) #define g_atomic_int_get(atomic) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ *(atomic) : 0); \ + (gint) __atomic_load_4 ((atomic), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_int_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ + (void) (0 ? *(atomic) ^ (newval) : 0); \ + __atomic_store_4 ((atomic), (newval), __ATOMIC_SEQ_CST); \ + })) + +#if GLIB_SIZEOF_VOID_P == 8 + +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (gpointer) __atomic_load_8 ((atomic), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + __atomic_store_8 ((atomic), (gsize) (newval), __ATOMIC_SEQ_CST); \ + })) + +#else /* GLIB_SIZEOF_VOID_P == 8 */ + +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (gpointer) __atomic_load_4 ((atomic), __ATOMIC_SEQ_CST); \ + })) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + __atomic_store_4 ((atomic), (gsize) (newval), __ATOMIC_SEQ_CST); \ + })) + +#endif /* GLIB_SIZEOF_VOID_P == 8 */ + +#else /* defined(__ATOMIC_SEQ_CST) */ + +#define g_atomic_int_get(atomic) \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ *(atomic) : 0); \ __sync_synchronize (); \ (gint) *(atomic); \ })) #define g_atomic_int_set(atomic, newval) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ (newval) : 0); \ *(atomic) = (newval); \ __sync_synchronize (); \ })) +#define g_atomic_pointer_get(atomic) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + __sync_synchronize (); \ + (gpointer) *(atomic); \ + })) +#define g_atomic_pointer_set(atomic, newval) \ + (G_GNUC_EXTENSION ({ \ + G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ + (void) (0 ? (gpointer) *(atomic) : 0); \ + *(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \ + __sync_synchronize (); \ + })) + +#endif /* !defined(__ATOMIC_SEQ_CST) */ + #define g_atomic_int_inc(atomic) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ *(atomic) : 0); \ (void) __sync_fetch_and_add ((atomic), 1); \ })) #define g_atomic_int_dec_and_test(atomic) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ *(atomic) : 0); \ __sync_fetch_and_sub ((atomic), 1) == 1; \ })) #define g_atomic_int_compare_and_exchange(atomic, oldval, newval) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ (newval) ^ (oldval) : 0); \ (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \ })) #define g_atomic_int_add(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ (val) : 0); \ (gint) __sync_fetch_and_add ((atomic), (val)); \ })) #define g_atomic_int_and(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ (val) : 0); \ (guint) __sync_fetch_and_and ((atomic), (val)); \ })) #define g_atomic_int_or(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ (val) : 0); \ (guint) __sync_fetch_and_or ((atomic), (val)); \ })) #define g_atomic_int_xor(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \ (void) (0 ? *(atomic) ^ (val) : 0); \ (guint) __sync_fetch_and_xor ((atomic), (val)); \ })) -#define g_atomic_pointer_get(atomic) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - __sync_synchronize (); \ - (gpointer) *(atomic); \ - })) -#define g_atomic_pointer_set(atomic, newval) \ - (G_GNUC_EXTENSION ({ \ - G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ - (void) (0 ? (gpointer) *(atomic) : 0); \ - *(atomic) = (__typeof__ (*(atomic))) (gsize) (newval); \ - __sync_synchronize (); \ - })) #define g_atomic_pointer_compare_and_exchange(atomic, oldval, newval) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : 0); \ (gboolean) __sync_bool_compare_and_swap ((atomic), (oldval), (newval)); \ })) #define g_atomic_pointer_add(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : 0); \ (void) (0 ? (val) ^ (val) : 0); \ (gssize) __sync_fetch_and_add ((atomic), (val)); \ })) #define g_atomic_pointer_and(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : 0); \ (void) (0 ? (val) ^ (val) : 0); \ (gsize) __sync_fetch_and_and ((atomic), (val)); \ })) #define g_atomic_pointer_or(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : 0); \ (void) (0 ? (val) ^ (val) : 0); \ (gsize) __sync_fetch_and_or ((atomic), (val)); \ })) #define g_atomic_pointer_xor(atomic, val) \ - (G_GNUC_EXTENSION ({ \ + (G_GNUC_EXTENSION ({ \ G_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \ (void) (0 ? (gpointer) *(atomic) : 0); \ (void) (0 ? (val) ^ (val) : 0); \ (gsize) __sync_fetch_and_xor ((atomic), (val)); \ })) -#else /* defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS) */ +#else /* defined(G_ATOMIC_LOCK_FREE) && defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4) */ #define g_atomic_int_get(atomic) \ (g_atomic_int_get ((gint *) (atomic))) @@ -188,11 +251,11 @@ G_END_DECLS #define g_atomic_int_add(atomic, val) \ (g_atomic_int_add ((gint *) (atomic), (val))) #define g_atomic_int_and(atomic, val) \ - (g_atomic_int_and ((gint *) (atomic), (val))) + (g_atomic_int_and ((guint *) (atomic), (val))) #define g_atomic_int_or(atomic, val) \ - (g_atomic_int_or ((gint *) (atomic), (val))) + (g_atomic_int_or ((guint *) (atomic), (val))) #define g_atomic_int_xor(atomic, val) \ - (g_atomic_int_xor ((gint *) (atomic), (val))) + (g_atomic_int_xor ((guint *) (atomic), (val))) #define g_atomic_int_inc(atomic) \ (g_atomic_int_inc ((gint *) (atomic))) #define g_atomic_int_dec_and_test(atomic) \