--- crystalspace-src-1.2/include/csutil/threading/atomicops_gcc_ppc.h~ 2007-10-04 12:25:05.000000000 +0100 +++ crystalspace-src-1.2/include/csutil/threading/atomicops_gcc_ppc.h 2008-06-13 10:53:34.000000000 +0100 @@ -47,7 +47,23 @@ namespace Threading inline static void* Set (void** target, void* value) { +#if CS_PROCESSOR_SIZE == 32 return (void*)Set ((int32*)target, (int32)value); +#elif CS_PROCESSOR_SIZE == 64 + __asm__ __volatile__ + ( + " lwsync \n" + "1: ldarx %0,0,%2 \n" + " dcbt 0,%2 \n" + " stdcx. %3,0,%2 \n" + " bne- 1b\n" + " isync \n" + : "=&r" (value), "=m" (*(unsigned int *)target) + : "r" (target), "r" (value), "m" (*(unsigned int *)target) + : "cc", "memory" + ); + return value; +#endif } inline static int32 CompareAndSet (int32* target, int32 value, @@ -74,21 +90,47 @@ namespace Threading inline static void* CompareAndSet (void** target, void* value, void* comparand) { +#if CS_PROCESSOR_SIZE == 32 return (void*)CompareAndSet ((int32*)target, (int32)value, (int32)comparand); +#elif CS_PROCESSOR_SIZE == 64 + void *prev; + + __asm__ __volatile__ ( + " lwsync \n" + "1: ldarx %0,0,%2\n" + " cmpd 0,%0,%3\n" + " bne- 2f\n" + " dcbt 0,%2 \n" + " stdcx. %4,0,%2\n" + " bne- 1b\n" + " isync \n" + "2:" + : "=&r" (prev), "=m" (*target) + : "r" (target), "r" (comparand), "r" (value), "m" (*target) + : "cc", "memory"); + return prev; +#endif } inline static int32 Increment (int32* target, int32 incr = 1) { - //@@Potentially dangerous code, needs to be revisited - int32 prevValue, currValue, nextValue; - do - { - currValue = *target; - nextValue = currValue + incr; - prevValue = CompareAndSet (target, nextValue, currValue); - } while(prevValue == currValue); - return nextValue; + int32 value; + + __asm__ __volatile__ + ( + " lwsync \n" + "1: lwarx %0,0,%2 \n" + " addw %0,%0,%3 \n" + " dcbt 0,%2 \n" + " stwcx. %0,0,%2 \n" + " bne- 1b\n" + " isync \n" + : "=&r" (value), "=m" (*(unsigned int *)target) + : "r" (target), "r" (incr), "m" (*(unsigned int *)target) + : "cc", "memory" + ); + return value; } inline static int32 Decrement (int32* target)