mirror of
https://github.com/reactos/reactos.git
synced 2024-12-27 09:34:43 +00:00
Added PowerPC interlocked functions from glib.
svn path=/trunk/; revision=13890
This commit is contained in:
parent
1dca540f6b
commit
72f40b7d14
1 changed files with 57 additions and 5 deletions
|
@ -15,6 +15,29 @@
|
||||||
* Copied from kernel32
|
* 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 *
|
* InterlockedIncrement *
|
||||||
|
@ -36,6 +59,7 @@ STDCALL
|
||||||
InterlockedIncrement(PLONG Addend)
|
InterlockedIncrement(PLONG Addend)
|
||||||
{
|
{
|
||||||
long ret = 0;
|
long ret = 0;
|
||||||
|
#ifdef _M_IX86
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"\tlock\n" /* for SMP systems */
|
"\tlock\n" /* for SMP systems */
|
||||||
|
@ -48,6 +72,10 @@ InterlockedIncrement(PLONG Addend)
|
||||||
"2:\n"
|
"2:\n"
|
||||||
:"=r" (ret):"r" (Addend), "0" (0): "memory"
|
:"=r" (ret):"r" (Addend), "0" (0): "memory"
|
||||||
);
|
);
|
||||||
|
#elif defined(_M_PPC)
|
||||||
|
ret = *Addend;
|
||||||
|
ret = InterlockedExchangeAdd( Addend, ret + 1 );
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +95,7 @@ STDCALL
|
||||||
InterlockedDecrement(LPLONG lpAddend)
|
InterlockedDecrement(LPLONG lpAddend)
|
||||||
{
|
{
|
||||||
long ret;
|
long ret;
|
||||||
|
#ifdef _M_IX86
|
||||||
__asm__
|
__asm__
|
||||||
(
|
(
|
||||||
"\tlock\n" /* for SMP systems */
|
"\tlock\n" /* for SMP systems */
|
||||||
|
@ -79,6 +108,10 @@ InterlockedDecrement(LPLONG lpAddend)
|
||||||
"2:\n"
|
"2:\n"
|
||||||
:"=r" (ret):"r" (lpAddend), "0" (0): "memory"
|
:"=r" (ret):"r" (lpAddend), "0" (0): "memory"
|
||||||
);
|
);
|
||||||
|
#elif defined(_M_PPC)
|
||||||
|
ret = *lpAddend;
|
||||||
|
ret = InterlockedExchangeAdd( lpAddend, ret - 1 );
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,14 +130,16 @@ LONG
|
||||||
STDCALL
|
STDCALL
|
||||||
InterlockedExchange(LPLONG target, LONG value )
|
InterlockedExchange(LPLONG target, LONG value )
|
||||||
{
|
{
|
||||||
|
|
||||||
long ret;
|
long ret;
|
||||||
|
#ifdef _M_IX86
|
||||||
__asm__ ( /* lock for SMP systems */
|
__asm__ ( /* lock for SMP systems */
|
||||||
"lock\n\txchgl %0,(%1)"
|
"lock\n\txchgl %0,(%1)"
|
||||||
:"=r" (ret):"r" (target), "0" (value):"memory" );
|
:"=r" (ret):"r" (target), "0" (value):"memory" );
|
||||||
|
#elif defined(_M_PPC)
|
||||||
|
ret = *target;
|
||||||
|
while( InterlockedCompareExchange( target, value, ret ) != value );
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
|
@ -124,8 +159,21 @@ InterlockedCompareExchange(
|
||||||
LONG Comperand )
|
LONG Comperand )
|
||||||
{
|
{
|
||||||
LONG ret;
|
LONG ret;
|
||||||
|
#ifdef _M_IX86
|
||||||
__asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
|
__asm__ __volatile__( "lock; cmpxchgl %2,(%1)"
|
||||||
: "=a" (ret) : "r" (Destination), "r" (Exchange), "0" (Comperand) : "memory" );
|
: "=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;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,14 +193,18 @@ InterlockedExchangeAdd(
|
||||||
LONG Increment
|
LONG Increment
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
|
|
||||||
LONG ret;
|
LONG ret;
|
||||||
|
#ifdef _M_IX86
|
||||||
__asm__ ( /* lock for SMP systems */
|
__asm__ ( /* lock for SMP systems */
|
||||||
"lock\n\t"
|
"lock\n\t"
|
||||||
"xaddl %0,(%1)"
|
"xaddl %0,(%1)"
|
||||||
:"=r" (ret)
|
:"=r" (ret)
|
||||||
:"r" (Addend), "0" (Increment)
|
:"r" (Addend), "0" (Increment)
|
||||||
:"memory" );
|
:"memory" );
|
||||||
|
#elif defined(_M_PPC)
|
||||||
|
do
|
||||||
|
ret = *Addend;
|
||||||
|
while (!InterlockedCompareExchange(Addend, ret, ret + Increment));
|
||||||
|
#endif
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue