[glib_cv_gcc_has_builtin_atomic_operations=no])
AC_MSG_RESULT($glib_cv_gcc_has_builtin_atomic_operations)
- if test $glib_cv_gcc_has_builtin_atomic_operations = yes; then
- glib_memory_barrier_needed=yes
- else
case $host_cpu in
i386)
AC_MSG_RESULT([none])
glib_memory_barrier_needed=yes
;;
esac
- fi
else
if test $glib_native_win32 = yes; then
# For Windows but not using gcc. No barriers needed then either.
int
main (void)
{
- /* not like this actually runs or anything... */
+ /* it is not like this actually runs or anything... */
syscall (SYS_futex, NULL, FUTEX_WAKE, FUTEX_WAIT);
return 0;
}
echo >>$outfile
echo "#define G_ATOMIC_OP_MEMORY_BARRIER_NEEDED 1" >>$outfile
fi
-
+ if test x"$g_gcc_atomic_ops" != xno; then
+ echo >>$outfile
+ echo "#define G_ATOMIC_OP_USE_GCC_BUILTINS 1" >>$outfile
+ fi
echo >>$outfile
g_bit_sizes="16 32 64"
for bits in $g_bit_sizes; do
g_mutex_contents="$glib_cv_byte_contents_gmutex"
g_memory_barrier_needed="$glib_memory_barrier_needed"
+g_gcc_atomic_ops="$glib_cv_gcc_has_builtin_atomic_operations"
g_module_suffix="$glib_gmodule_suffix"
#include "gatomic.h"
+/* All atomic operations are available as macros evaluating
+ * to gcc builtins (when using gcc builtins for atomic operations).
+ * For ABI stability, we provide functions for them too.
+ *
+ * To avoid interference, undefine the macros first.
+ */
+
+#undef g_atomic_int_exchange_and_add
+#undef g_atomic_int_compare_and_exchange
+#undef g_atomic_int_add
+#undef g_atomic_int_get
+#undef g_atomic_int_set
+#undef g_atomic_pointer_compare_and_exchange
+#undef g_atomic_pointer_get
+#undef g_atomic_pointer_set
+
gint
g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
- gint val)
+ gint val)
{
return __sync_fetch_and_add (atomic, val);
}
void
g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
- gint val)
+ gint val)
{
__sync_fetch_and_add (atomic, val);
}
gboolean
g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
- gint oldval,
- gint newval)
+ gint oldval,
+ gint newval)
{
return __sync_bool_compare_and_swap (atomic, oldval, newval);
}
gboolean
g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
- gpointer oldval,
- gpointer newval)
+ gpointer oldval,
+ gpointer newval)
{
return __sync_bool_compare_and_swap (atomic, oldval, newval);
}
}
gint
-(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+g_atomic_int_get (volatile gint G_GNUC_MAY_ALIAS *atomic)
{
__sync_synchronize ();
return *atomic;
}
void
-(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
- gint newval)
+g_atomic_int_set (volatile gint G_GNUC_MAY_ALIAS *atomic,
+ gint newval)
{
*atomic = newval;
__sync_synchronize ();
}
gpointer
-(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+g_atomic_pointer_get (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
{
__sync_synchronize ();
return *atomic;
}
void
-(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
- gpointer newval)
+g_atomic_pointer_set (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+ gpointer newval)
{
*atomic = newval;
__sync_synchronize ();
void g_atomic_pointer_set (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
gpointer newval);
-#ifndef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+#if defined(__GNUC__) && defined(G_ATOMIC_OP_USE_GCC_BUILTINS)
+
+#define g_atomic_int_exchange_and_add(atomic,val) \
+ __sync_fetch_and_add((atomic),(val))
+
+#define g_atomic_int_add(atomic,val) \
+ __sync_fetch_and_add((atomic),(val))
+
+#define g_atomic_int_compare_and_exchange(atomic,oldval,newval) \
+ __sync_bool_compare_and_swap((atomic),(oldval),(newval))
+
+#define g_atomic_int_get(atomic) \
+ __extension__ ({ __sync_synchronize(); *(atomic); })
+
+#define g_atomic_int_set(atomic,newval) \
+ __extension__ ({ *(atomic) = (newval); __sync_synchronize(); })
+
+#define g_atomic_pointer_compare_and_exchange(atomic,oldval,newval) \
+ __sync_bool_compare_and_swap((atomic),(oldval),(newval))
+
+#define g_atomic_pointer_get(atomic) \
+ __extension__ ({ __sync_synchronize(); *(atomic); })
+
+#define g_atomic_pointer_set(atomic,newval) \
+ __extension__ ({ *(atomic) = (newval); __sync_synchronize(); })
+
+#elif !defined(G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
+
# define g_atomic_int_get(atomic) ((gint)*(atomic))
# define g_atomic_int_set(atomic, newval) ((void) (*(atomic) = (newval)))
# define g_atomic_pointer_get(atomic) ((gpointer)*(atomic))
# define g_atomic_pointer_set(atomic, newval) ((void) (*(atomic) = (newval)))
+
#else
+
# define g_atomic_int_get(atomic) \
((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gint) ? 1 : -1]), \
(g_atomic_int_get) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
# define g_atomic_pointer_set(atomic, newval) \
((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gpointer) ? 1 : -1]), \
(g_atomic_pointer_set) ((volatile gpointer G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval)))
+
#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
/**