Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -170,10 +170,14 @@ 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])]) fi AC_CHECK_LIB(socket, socket, LIBS="$LIBS -lsocket") AC_CHECK_LIB(ws2_32, main, LIBS="$LIBS -lws2_32") Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -33,10 +33,11 @@ INCLUDES := ${SRCS:.m=.h} \ OFFastEnumeration.h \ OFMacros.h \ ObjFW.h \ asprintf.h \ + atomic.h \ objfw-defs.h \ ${THREADING_H} SRCS += ${AS_PRINTF_M} \ iso_8859_15.m \ Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -28,10 +28,12 @@ #endif #ifdef OF_GNU_RUNTIME # import #endif +#import "atomic.h" + struct pre_ivar { void **memchunks; size_t memchunks_size; size_t retain_count; }; @@ -471,11 +473,11 @@ pointer: ptr]; } - retain { - PRE_IVAR->retain_count++; + of_atomic_inc32(&PRE_IVAR->retain_count); return self; } - (size_t)retainCount @@ -483,11 +485,11 @@ return PRE_IVAR->retain_count; } - (void)release { - if (!--PRE_IVAR->retain_count) + if (!of_atomic_dec32(&PRE_IVAR->retain_count)) [self dealloc]; } - autorelease { ADDED src/atomic.h Index: src/atomic.h ================================================================== --- src/atomic.h +++ src/atomic.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of ObjFW. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import "objfw-defs.h" + +#if !defined(OF_THREADS) +# define of_atomic_inc32(p) ++(*p) +# define of_atomic_dec32(p) --(*p) +#elif __GNUC_MINOR__ >= 1 +# 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 +# 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,7 +1,8 @@ #undef OF_APPLE_RUNTIME #undef OF_BIG_ENDIAN #undef OF_GNU_RUNTIME #undef OF_HAVE_ASPRINTF +#undef OF_HAVE_LIBKERN_OSATOMIC_H #undef OF_PLUGINS #undef OF_THREADS #undef SIZE_MAX