Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -29,15 +29,22 @@ #ifdef OF_GNU_RUNTIME # import #endif #import "atomic.h" + +#ifndef OF_ATOMIC_OPS +#import "threading.h" +#endif struct pre_ivar { - void **memchunks; - size_t memchunks_size; - int32_t retain_count; /* int32_t because atomic ops use int32_t */ + void **memchunks; + size_t memchunks_size; + int32_t retain_count; /* int32_t because atomic ops use int32_t */ +#ifndef OF_ATOMIC_OPS + of_spinlock_t retain_spinlock; +#endif }; /* Hopefully no arch needs more than 16 bytes padding */ #define PRE_IVAR_ALIGN ((sizeof(struct pre_ivar) + 15) & ~15) #define PRE_IVAR ((struct pre_ivar*)((char*)self - PRE_IVAR_ALIGN)) @@ -110,10 +117,14 @@ } ((struct pre_ivar*)instance)->memchunks = NULL; ((struct pre_ivar*)instance)->memchunks_size = 0; ((struct pre_ivar*)instance)->retain_count = 1; + +#ifndef OF_ATOMIC_OPS + of_spinlock_new(&((struct pre_ivar*)instance)->retain_spinlock); +#endif instance = (OFObject*)((char*)instance + PRE_IVAR_ALIGN); memset(instance, 0, isize); instance->isa = self; @@ -485,11 +496,17 @@ pointer: ptr]; } - retain { +#ifdef OF_ATOMIC_OPS of_atomic_inc32(&PRE_IVAR->retain_count); +#else + of_spinlock_lock(&PRE_IVAR->retain_spinlock); + PRE_IVAR->retain_count++; + of_spinlock_unlock(&PRE_IVAR->retain_spinlock); +#endif return self; } - (int32_t)retainCount @@ -497,12 +514,23 @@ return PRE_IVAR->retain_count; } - (void)release { +#ifdef OF_ATOMIC_OPS if (!of_atomic_dec32(&PRE_IVAR->retain_count)) [self dealloc]; +#else + int32_t c; + + of_spinlock_lock(&PRE_IVAR->retain_spinlock); + c = --PRE_IVAR->retain_count; + of_spinlock_unlock(&PRE_IVAR->retain_spinlock); + + if (!c) + [self dealloc]; +#endif } - autorelease { [OFAutoreleasePool addObjectToTopmostPool: self];