mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-03-14 19:55:12 +01:00
gatomic: use GCC C11-style atomics, if available
GCC does not yet support ISO C11 atomic operations, but it has compatible versions available as an extension. Use these for load and store if they are available in order to avoid emitting a hard fence instruction (since in many cases, we do not need it -- on x86, for example). For now we use the fully seqentially-consistent memory model, since these APIs are documented rather explicitly: "This call acts as a full compiler and hardware memory barrier". In the future we can consider introducing new APIs for the more relaxed memory models, if they are available (or fall back to stricter ones otherwise). https://bugzilla.gnome.org/show_bug.cgi?id=730807
This commit is contained in:
parent
875eeb2ca1
commit
db0e43d25a
@ -84,6 +84,54 @@ G_END_DECLS
|
||||
|
||||
#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)
|
||||
|
||||
#define g_atomic_int_get(atomic) \
|
||||
(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)); \
|
||||
@ -98,6 +146,22 @@ G_END_DECLS
|
||||
*(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_STATIC_ASSERT (sizeof *(atomic) == sizeof (gint)); \
|
||||
@ -141,19 +205,6 @@ G_END_DECLS
|
||||
(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_STATIC_ASSERT (sizeof *(atomic) == sizeof (gpointer)); \
|
||||
|
Loading…
x
Reference in New Issue
Block a user