Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -171,13 +171,51 @@ AC_CHECK_FUNC(objc_sync_enter,, [ AC_SUBST(OBJC_SYNC_M, "objc_sync.m") AC_DEFINE(NEED_OBJC_SYNC_INIT, 1, [Whether objc_sync_init needs to be called])]) - AC_CHECK_HEADER(libkern/OSAtomic.h, [ - AC_DEFINE(OF_HAVE_LIBKERN_OSATOMIC_H, 1, - [Whether we have libkern/OSAtomic.h])]) + AC_TRY_LINK([#include ], [ + int32_t i, j; + if (__sync_add_and_fetch(&i, 1)) + j = __sync_sub_and_fetch(&i, 1); + while (!__sync_bool_compare_and_swap(&i, 0, 1)); + ], [ + have_gcc_atomic_ops="yes" + AC_DEFINE(OF_HAVE_GCC_ATOMIC_OPS, 1, + [Whether gcc atomic operations are available]) + ], [ + old_OBJCFLAGS="$OBJCFLAGS" + OBJCFLAGS="$OBJCFLAGS -march=i486" + AC_TRY_LINK([#include ], [ + int32_t i, j; + if (__sync_add_and_fetch(&i, 1)) + j = __sync_sub_and_fetch(&i, 1); + while (!__sync_bool_compare_and_swap(&i, 0, 1)); + ], [ + have_gcc_atomic_ops="yes" + AC_DEFINE(OF_HAVE_GCC_ATOMIC_OPS, 1, + [Whether gcc atomic operations are available]) + ], [ + have_gcc_atomic_ops="no" + OBJCFLAGS="$old_OBJCFLAGS"])]) + + if test x"$have_gcc_atomic_ops" != x"yes"; then + AC_CHECK_HEADER(libkern/OSAtomic.h, [ + have_libkern_osatomic_h="yes" + AC_DEFINE(OF_HAVE_LIBKERN_OSATOMIC_H, 1, + [Whether we have libkern/OSAtomic.h])]) + fi + + AC_MSG_CHECKING(for atomic operations) + if test x"$have_gcc_atomic_ops" = x"yes"; then + AC_MSG_RESULT(gcc builtins) + elif test x"$have_libkern_osatomic_h" = x"yes"; then + AC_MSG_RESULT(libkern/OSAtomic.h) + else + AC_MSG_RESULT(none) + AC_MSG_ERROR(No atomic operations found! Try --disable-threads.) + fi fi AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32") Index: src/atomic.h ================================================================== --- src/atomic.h +++ src/atomic.h @@ -12,15 +12,15 @@ #import "objfw-defs.h" #if !defined(OF_THREADS) # define of_atomic_inc32(p) ++(*p) # define of_atomic_dec32(p) --(*p) -#elif __GNUC_MINOR__ >= 1 +#elif defined(OF_HAVE_GCC_ATOMIC_OPS) # define of_atomic_inc32(p) __sync_add_and_fetch(p, 1) # define of_atomic_dec32(p) __sync_sub_and_fetch(p, 1) -#elif OF_HAVE_LIBKERN_OSATOMIC_H +#elif defined(OF_HAVE_LIBKERN_OSATOMIC_H) # include # define of_atomic_inc32(p) OSAtomicIncrement32Barrier((int32_t*)(p)) # define of_atomic_dec32(p) OSAtomicDecrement32Barrier((int32_t*)(p)) #else # error No atomic operations available! #endif Index: src/objfw-defs.h.in ================================================================== --- src/objfw-defs.h.in +++ src/objfw-defs.h.in @@ -1,8 +1,9 @@ #undef OF_APPLE_RUNTIME #undef OF_BIG_ENDIAN #undef OF_GNU_RUNTIME #undef OF_HAVE_ASPRINTF +#undef OF_HAVE_GCC_ATOMIC_OPS #undef OF_HAVE_LIBKERN_OSATOMIC_H #undef OF_PLUGINS #undef OF_THREADS #undef SIZE_MAX