- Implemented Ke386TestAndClearBit and Ke386TestAndSetBit.

- Fixed some interlocked functions.

svn path=/trunk/; revision=12688
This commit is contained in:
Hartmut Birr 2005-01-01 11:18:54 +00:00
parent 37d9e18817
commit 2d760db23f
2 changed files with 86 additions and 23 deletions

View file

@ -1,14 +1,30 @@
/* $Id: interlck.c,v 1.10 2004/12/12 17:48:20 hbirr Exp $
/* $Id$
*
* reactos/ntoskrnl/ex/i386/interlck.c
*
*/
#include <ntoskrnl.h>
#ifdef LOCK
#undef LOCK
#endif
#if defined(__GNUC__)
#ifdef MP
#define LOCK "lock "
#define LOCK "lock ; "
#else
#define LOCK " "
#define LOCK ""
#endif
#elif defined(_MSC_VER)
#ifdef MP
#define LOCK lock
#else
#define LOCK
#endif
#endif
#if defined(__GNUC__)
@ -21,6 +37,7 @@ Exfi386InterlockedIncrementLong(IN PLONG Addend);
__asm__("\n\t.global @Exfi386InterlockedIncrementLong@4\n\t"
"@Exfi386InterlockedIncrementLong@4:\n\t"
LOCK
"addl $1,(%ecx)\n\t"
"lahf\n\t"
"andl $0xC000, %eax\n\t"
@ -35,7 +52,7 @@ __declspec(naked)
INTERLOCKED_RESULT FASTCALL
Exfi386InterlockedIncrementLong(IN PLONG Addend)
{
__asm add ecx, 1
__asm LOCK add dword ptr [ecx], 1
__asm lahf
__asm and eax, 0xC000
__asm ret
@ -56,6 +73,7 @@ Exfi386InterlockedDecrementLong(IN PLONG Addend);
__asm__("\n\t.global @Exfi386InterlockedDecrementLong@4\n\t"
"@Exfi386InterlockedDecrementLong@4:\n\t"
LOCK
"subl $1,(%ecx)\n\t"
"lahf\n\t"
"andl $0xC000, %eax\n\t"
@ -70,7 +88,7 @@ __declspec(naked)
INTERLOCKED_RESULT FASTCALL
Exfi386InterlockedDecrementLong(IN PLONG Addend)
{
__asm sub ecx, 1
__asm LOCK sub dword ptr [ecx], 1
__asm lahf
__asm and eax, 0xC000
__asm ret
@ -92,7 +110,8 @@ Exfi386InterlockedExchangeUlong(IN PULONG Target,
__asm__("\n\t.global @Exfi386InterlockedExchangeUlong@8\n\t"
"@Exfi386InterlockedExchangeUlong@8:\n\t"
LOCK"xchgl %edx,(%ecx)\n\t"
LOCK
"xchgl %edx,(%ecx)\n\t"
"movl %edx,%eax\n\t"
"ret\n\t");
@ -106,7 +125,7 @@ ULONG FASTCALL
Exfi386InterlockedExchangeUlong(IN PULONG Target,
IN ULONG Value)
{
__asm xchg [ecx], edx
__asm LOCK xchg [ecx], edx
__asm mov eax, edx
__asm ret
}
@ -124,6 +143,7 @@ Exi386InterlockedIncrementLong(IN PLONG Addend);
__asm__("\n\t.global _Exi386InterlockedIncrementLong@4\n\t"
"_Exi386InterlockedIncrementLong@4:\n\t"
"movl 4(%esp),%eax\n\t"
LOCK
"addl $1,(%eax)\n\t"
"lahf\n\t"
"andl $0xC000, %eax\n\t"
@ -136,7 +156,7 @@ INTERLOCKED_RESULT STDCALL
Exi386InterlockedIncrementLong(IN PLONG Addend)
{
__asm mov eax, Addend
__asm add [eax], 1
__asm LOCK add dword ptr [eax], 1
__asm lahf
__asm and eax, 0xC000
__asm ret 4
@ -155,6 +175,7 @@ Exi386InterlockedDecrementLong(IN PLONG Addend);
__asm__("\n\t.global _Exi386InterlockedDecrementLong@4\n\t"
"_Exi386InterlockedDecrementLong@4:\n\t"
"movl 4(%esp),%eax\n\t"
LOCK
"subl $1,(%eax)\n\t"
"lahf\n\t"
"andl $0xC000, %eax\n\t"
@ -167,7 +188,7 @@ INTERLOCKED_RESULT STDCALL
Exi386InterlockedDecrementLong(IN PLONG Addend)
{
__asm mov eax, Addend
__asm sub [eax], 1
__asm LOCK sub dword ptr [eax], 1
__asm lahf
__asm and eax, 0xC000
__asm ret 4
@ -188,7 +209,8 @@ __asm__("\n\t.global _Exi386InterlockedExchangeUlong@8\n\t"
"_Exi386InterlockedExchangeUlong@8:\n\t"
"movl 4(%esp),%edx\n\t"
"movl 8(%esp),%eax\n\t"
LOCK"xchgl %eax,(%edx)\n\t"
LOCK
"xchgl %eax,(%edx)\n\t"
"ret $8\n\t");
#elif defined(_MSC_VER)
@ -200,7 +222,7 @@ Exi386InterlockedExchangeUlong(IN PULONG Target,
{
__asm mov edx, Value
__asm mov eax, Target
__asm xchg [edx], eax
__asm LOCK xchg [edx], eax
__asm ret 8
}
@ -231,7 +253,8 @@ InterlockedIncrement(PLONG Addend);
__asm__("\n\t.global @InterlockedIncrement@4\n\t"
"@InterlockedIncrement@4:\n\t"
"movl $1,%eax\n\t"
LOCK"xaddl %eax,(%ecx)\n\t"
LOCK
"xaddl %eax,(%ecx)\n\t"
"incl %eax\n\t"
"ret\n\t");
@ -244,7 +267,7 @@ LONG FASTCALL
InterlockedIncrement(PLONG Addend)
{
__asm mov eax, 1
__asm xadd [ecx], eax
__asm LOCK xadd [ecx], eax
__asm inc eax
__asm ret
}
@ -268,7 +291,8 @@ InterlockedDecrement(PLONG Addend);
__asm__("\n\t.global @InterlockedDecrement@4\n\t"
"@InterlockedDecrement@4:\n\t"
"movl $-1,%eax\n\t"
LOCK"xaddl %eax,(%ecx)\n\t"
LOCK
"xaddl %eax,(%ecx)\n\t"
"decl %eax\n\t"
"ret\n\t");
@ -282,7 +306,7 @@ LONG FASTCALL
InterlockedDecrement(PLONG Addend)
{
__asm mov eax, -1
__asm xadd [ecx], eax
__asm LOCK xadd [ecx], eax
__asm dec eax
__asm ret
}
@ -307,7 +331,8 @@ InterlockedExchange(PLONG Target,
__asm__("\n\t.global @InterlockedExchange@8\n\t"
"@InterlockedExchange@8:\n\t"
LOCK"xchgl %edx,(%ecx)\n\t"
LOCK
"xchgl %edx,(%ecx)\n\t"
"movl %edx,%eax\n\t"
"ret\n\t");
@ -320,7 +345,7 @@ LONG FASTCALL
InterlockedExchange(PLONG Target,
LONG Value)
{
__asm xchg [ecx], edx
__asm LOCK xchg [ecx], edx
__asm mov eax, edx
__asm ret
}
@ -343,7 +368,8 @@ InterlockedExchangeAdd(PLONG Addend,
__asm__("\n\t.global @InterlockedExchangeAdd@8\n\t"
"@InterlockedExchangeAdd@8:\n\t"
LOCK"xaddl %edx,(%ecx)\n\t"
LOCK
"xaddl %edx,(%ecx)\n\t"
"movl %edx,%eax\n\t"
"ret\n\t");
@ -356,7 +382,7 @@ LONG FASTCALL
InterlockedExchangeAdd(PLONG Addend,
LONG Value)
{
__asm xadd [ecx], edx
__asm LOCK xadd [ecx], edx
__asm mov eax, edx
__asm ret
}
@ -380,7 +406,8 @@ InterlockedCompareExchange(PLONG Destination,
__asm__("\n\t.global @InterlockedCompareExchange@12\n\t"
"@InterlockedCompareExchange@12:\n\t"
"movl 4(%esp),%eax\n\t"
LOCK"cmpxchg %edx,(%ecx)\n\t"
LOCK
"cmpxchg %edx,(%ecx)\n\t"
"ret $4\n\t");
#elif defined(_MSC_VER)
@ -392,7 +419,7 @@ InterlockedCompareExchange(PLONG Destination,
LONG Comperand)
{
__asm mov eax, Comperand
__asm cmpxchg [ecx], edx
__asm LOCK cmpxchg [ecx], edx
__asm ret 4
}
@ -418,7 +445,8 @@ __asm__("\n\t.global @ExfpInterlockedExchange64@8\n\t"
"\n1:\t"
"movl (%esi),%eax\n\t"
"movl 4(%esi),%edx\n\t"
LOCK"cmpxchg8b (%esi)\n\t"
LOCK
"cmpxchg8b (%esi)\n\t"
"jnz 1b\n\t"
"popl %esi\n\t"
"popl %ebx\n\t"
@ -447,7 +475,8 @@ __asm__("\n\t.global @ExfInterlockedCompareExchange64@12\n\t"
"movl 12(%esp),%edx\n\t"
"movl (%edx),%eax\n\t"
"movl 4(%edx),%edx\n\t"
LOCK"cmpxchg8b (%esi)\n\t"
LOCK
"cmpxchg8b (%esi)\n\t"
"popl %esi\n\t"
"popl %ebx\n\t"
"ret $4\n\t");

View file

@ -192,6 +192,13 @@ VOID KeFreeGdtSelector(ULONG Entry);
VOID
NtEarlyInitVdm(VOID);
#ifdef MP
#define LOCK "lock ; "
#else
#define LOCK ""
#endif
#if defined(__GNUC__)
#define Ke386DisableInterrupts() __asm__("cli\n\t");
#define Ke386EnableInterrupts() __asm__("sti\n\t");
@ -219,6 +226,33 @@ NtEarlyInitVdm(VOID);
#define Ke386GetCr4() _Ke386GetCr(4)
#define Ke386SetCr4(X) _Ke386SetCr(4,X)
static inline LONG Ke386TestAndClearBit(ULONG BitPos, volatile PULONG Addr)
{
LONG OldBit;
__asm__ __volatile__(LOCK
"btrl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Addr)
:"Ir" (BitPos)
: "memory");
return OldBit;
}
static inline LONG Ke386TestAndSetBit(ULONG BitPos, volatile PULONG Addr)
{
LONG OldBit;
__asm__ __volatile__(LOCK
"btsl %2,%1\n\t"
"sbbl %0,%0\n\t"
:"=r" (OldBit),"=m" (*Addr)
:"Ir" (BitPos)
: "memory");
return OldBit;
}
static inline void Ki386Cpuid(ULONG Op, PULONG Eax, PULONG Ebx, PULONG Ecx, PULONG Edx)
{
__asm__("cpuid"