diff --git a/reactos/lib/rosrtl/misc/intrlck.c b/reactos/lib/rosrtl/misc/intrlck.c index 780176dcd3f..3ccabe0ce20 100644 --- a/reactos/lib/rosrtl/misc/intrlck.c +++ b/reactos/lib/rosrtl/misc/intrlck.c @@ -15,6 +15,29 @@ * Copied from kernel32 */ +/* PowerPC Functions from gatomic.c in glib + * + * GLIB - Library of useful routines for C programming + * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald + * + * g_atomic_*: atomic operations. + * Copyright (C) 2003 Sebastian Wilhelmi + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ /************************************************************************ * InterlockedIncrement * @@ -36,6 +59,7 @@ STDCALL InterlockedIncrement(PLONG Addend) { long ret = 0; +#ifdef _M_IX86 __asm__ ( "\tlock\n" /* for SMP systems */ @@ -48,6 +72,10 @@ InterlockedIncrement(PLONG Addend) "2:\n" :"=r" (ret):"r" (Addend), "0" (0): "memory" ); +#elif defined(_M_PPC) + ret = *Addend; + ret = InterlockedExchangeAdd( Addend, ret + 1 ); +#endif return ret; } @@ -67,6 +95,7 @@ STDCALL InterlockedDecrement(LPLONG lpAddend) { long ret; +#ifdef _M_IX86 __asm__ ( "\tlock\n" /* for SMP systems */ @@ -79,6 +108,10 @@ InterlockedDecrement(LPLONG lpAddend) "2:\n" :"=r" (ret):"r" (lpAddend), "0" (0): "memory" ); +#elif defined(_M_PPC) + ret = *lpAddend; + ret = InterlockedExchangeAdd( lpAddend, ret - 1 ); +#endif return ret; @@ -97,14 +130,16 @@ LONG STDCALL InterlockedExchange(LPLONG target, LONG value ) { - long ret; +#ifdef _M_IX86 __asm__ ( /* lock for SMP systems */ "lock\n\txchgl %0,(%1)" :"=r" (ret):"r" (target), "0" (value):"memory" ); +#elif defined(_M_PPC) + ret = *target; + while( InterlockedCompareExchange( target, value, ret ) != value ); +#endif return ret; - - } /************************************************************************ @@ -124,8 +159,21 @@ InterlockedCompareExchange( LONG Comperand ) { LONG ret; +#ifdef _M_IX86 __asm__ __volatile__( "lock; cmpxchgl %2,(%1)" : "=a" (ret) : "r" (Destination), "r" (Exchange), "0" (Comperand) : "memory" ); +#elif defined(_M_PPC) + __asm__ __volatile__ ("sync\n" + "1: lwarx %0,0,%1\n" + " subf. %0,%2,%0\n" + " bne 2f\n" + " stwcx. %3,0,%1\n" + " bne- 1b\n" + "2: isync" + : "=&r" (ret) + : "b" (Destination), "r" (Comperand), "r" (Exchange) + : "cr0", "memory"); +#endif return ret; } @@ -145,14 +193,18 @@ InterlockedExchangeAdd( LONG Increment ) { - LONG ret; +#ifdef _M_IX86 __asm__ ( /* lock for SMP systems */ "lock\n\t" "xaddl %0,(%1)" :"=r" (ret) :"r" (Addend), "0" (Increment) :"memory" ); +#elif defined(_M_PPC) + do + ret = *Addend; + while (!InterlockedCompareExchange(Addend, ret, ret + Increment)); +#endif return ret; - }