Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -951,10 +951,11 @@ AC_MSG_CHECKING(for threads) case "$host_os" in amigaos* | morphos*) AC_MSG_RESULT(Amiga) + have_amiga_threads="yes" ;; mingw*) AC_MSG_RESULT(WinAPI) ;; *) @@ -1800,11 +1801,11 @@ echo "features)." echo ]) AS_IF([test x"$enable_threads" != x"no" -a x"$atomic_ops" = x"none" \ - -a x"$have_spinlocks" != x"yes"], [ + -a x"$have_spinlocks" != x"yes" -a x"$have_amiga_threads" != x"yes"], [ echo printf " ** Warning: You have enabled threads, but neither atomic " echo "operations nor" printf " ** spinlocks are available. Expect *very* poor performance, " echo "as a mutex will" Index: src/OFObject.m ================================================================== --- src/OFObject.m +++ src/OFObject.m @@ -51,10 +51,14 @@ #endif #ifdef OF_WINDOWS # include #endif + +#ifdef OF_AMIGAOS +# include +#endif #import "OFString.h" #import "instance.h" #if defined(OF_HAVE_ATOMIC_OPS) @@ -71,11 +75,11 @@ # define of_forward_stret of_method_not_found_stret #endif struct pre_ivar { int retainCount; -#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS) +#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) of_spinlock_t retainCountSpinlock; #endif struct pre_mem *firstMem, *lastMem; }; @@ -184,11 +188,11 @@ @throw (id)&allocFailedException; } ((struct pre_ivar *)instance)->retainCount = 1; -#if !defined(OF_HAVE_ATOMIC_OPS) && defined(OF_HAVE_THREADS) +#if !defined(OF_HAVE_ATOMIC_OPS) && !defined(OF_AMIGAOS) if OF_UNLIKELY (!of_spinlock_new( &((struct pre_ivar *)instance)->retainCountSpinlock)) { free(instance); @throw [OFInitializationFailedException exceptionWithClass: class]; @@ -1181,10 +1185,23 @@ - (instancetype)retain { #if defined(OF_HAVE_ATOMIC_OPS) of_atomic_int_inc(&PRE_IVARS->retainCount); +#elif defined(OF_AMIGAOS) + /* + * On AmigaOS, we can only have one CPU. As increasing a variable is a + * single instruction on M68K, we don't need Forbid() / Permit() on + * M68K. + */ +# ifndef OF_AMIGAOS_M68K + Forbid(); +# endif + PRE_IVARS->retainCount++; +# ifndef OF_AMIGAOS_M68K + Permit(); +# endif #else OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock)); PRE_IVARS->retainCount++; OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock)); #endif @@ -1206,18 +1223,27 @@ if (of_atomic_int_dec(&PRE_IVARS->retainCount) <= 0) { of_memory_barrier_acquire(); [self dealloc]; } +#elif defined(OF_AMIGAOS) + int retainCount; + + Forbid(); + retainCount = --PRE_IVARS->retainCount; + Permit(); + + if (retainCount == 0) + [self dealloc]; #else - size_t c; + int retainCount; OF_ENSURE(of_spinlock_lock(&PRE_IVARS->retainCountSpinlock)); - c = --PRE_IVARS->retainCount; + retainCount = --PRE_IVARS->retainCount; OF_ENSURE(of_spinlock_unlock(&PRE_IVARS->retainCountSpinlock)); - if (c == 0) + if (retainCount == 0) [self dealloc]; #endif } - (instancetype)autorelease