mirror of
https://github.com/reactos/reactos.git
synced 2025-04-22 05:00:27 +00:00
[NTOSKRNL]
Convert most ExInterlocked* functions from asm to C Exceptions are ExInterlockedAddLargeStatistic and SList funcions svn path=/trunk/; revision=52852
This commit is contained in:
parent
d040534b02
commit
dc06eeafec
4 changed files with 544 additions and 1191 deletions
|
@ -276,8 +276,8 @@ list(APPEND SOURCE
|
||||||
if(ARCH MATCHES i386)
|
if(ARCH MATCHES i386)
|
||||||
list(APPEND SOURCE
|
list(APPEND SOURCE
|
||||||
config/i386/cmhardwr.c
|
config/i386/cmhardwr.c
|
||||||
ex/i386/interlck_asm.S
|
|
||||||
ex/i386/fastinterlck_asm.S
|
ex/i386/fastinterlck_asm.S
|
||||||
|
ex/i386/interlocked.c
|
||||||
ex/i386/ioport.S
|
ex/i386/ioport.S
|
||||||
ke/i386/abios.c
|
ke/i386/abios.c
|
||||||
ke/i386/cpu.c
|
ke/i386/cpu.c
|
||||||
|
|
|
@ -51,331 +51,7 @@ PUBLIC @ExInterlockedAddLargeStatistic@8
|
||||||
/* Return */
|
/* Return */
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/*ULONG
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedAddUlong(IN PULONG Addend,
|
|
||||||
* IN ULONG Increment,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedAddUlong@12
|
|
||||||
@ExfInterlockedAddUlong@12:
|
|
||||||
|
|
||||||
/* Save flags */
|
|
||||||
pushfd
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Get lock address */
|
|
||||||
mov eax, [esp+8]
|
|
||||||
.start1:
|
|
||||||
#endif
|
|
||||||
/* Disable interrupts */
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
ACQUIRE_SPINLOCK(eax, .spin1)
|
|
||||||
|
|
||||||
/* Do the add */
|
|
||||||
mov eax, [ecx]
|
|
||||||
add [ecx], edx
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Get spinlock address and release it */
|
|
||||||
mov edx, [esp+8]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags and return */
|
|
||||||
popfd
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin1:
|
|
||||||
/* Restore flags and spin */
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
SPIN_ON_LOCK(eax, .start1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedInsertHeadList(IN PLIST_ENTRY ListHead,
|
|
||||||
* IN PLIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedInsertHeadList@12
|
|
||||||
@ExfInterlockedInsertHeadList@12:
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Save lock address */
|
|
||||||
push esi
|
|
||||||
mov esi, [esp+8]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
pushfd
|
|
||||||
.start2:
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
ACQUIRE_SPINLOCK(esi, .spin2)
|
|
||||||
|
|
||||||
/* Get list pointer */
|
|
||||||
mov eax, [ecx]
|
|
||||||
|
|
||||||
/* Do the insert */
|
|
||||||
mov [edx], eax
|
|
||||||
mov [edx+4], ecx
|
|
||||||
mov [ecx], edx
|
|
||||||
mov [eax+4], edx
|
|
||||||
|
|
||||||
/* Release lock and restore flags */
|
|
||||||
RELEASE_SPINLOCK(esi)
|
|
||||||
popfd
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
pop esi
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if list was empty */
|
|
||||||
xor eax, ecx
|
|
||||||
jz .l2
|
|
||||||
|
|
||||||
/* Return list pointer */
|
|
||||||
xor eax, ecx
|
|
||||||
.l2:
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin2:
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
SPIN_ON_LOCK(esi, .start2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedInsertTailList(IN PLIST_ENTRY ListHead,
|
|
||||||
* IN PLIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedInsertTailList@12
|
|
||||||
@ExfInterlockedInsertTailList@12:
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Save lock address */
|
|
||||||
push esi
|
|
||||||
mov esi, [esp+8]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
pushfd
|
|
||||||
.start3:
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
ACQUIRE_SPINLOCK(esi, .spin3)
|
|
||||||
|
|
||||||
/* Get list pointer */
|
|
||||||
mov eax, [ecx+4]
|
|
||||||
|
|
||||||
/* Do the insert */
|
|
||||||
mov [edx], ecx
|
|
||||||
mov [edx+4], eax
|
|
||||||
mov [ecx+4], edx
|
|
||||||
mov [eax], edx
|
|
||||||
|
|
||||||
/* Release lock and restore flags */
|
|
||||||
RELEASE_SPINLOCK(esi)
|
|
||||||
popfd
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
pop esi
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Check if list was empty */
|
|
||||||
xor eax, ecx
|
|
||||||
jz .l3
|
|
||||||
|
|
||||||
/* Return list pointer */
|
|
||||||
xor eax, ecx
|
|
||||||
.l3:
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin3:
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
SPIN_ON_LOCK(esi, .start3)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedRemoveHeadList(IN PLIST_ENTRY ListHead,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedRemoveHeadList@8
|
|
||||||
@ExfInterlockedRemoveHeadList@8:
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start4:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin4)
|
|
||||||
|
|
||||||
/* Get list pointer */
|
|
||||||
mov eax, [ecx]
|
|
||||||
|
|
||||||
/* Check if it's empty */
|
|
||||||
cmp eax, ecx
|
|
||||||
je .l4
|
|
||||||
|
|
||||||
/* Get the next entry and do the deletion */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
push ebx
|
|
||||||
mov ebx, [eax]
|
|
||||||
mov [ecx], ebx
|
|
||||||
mov [ebx+4], ecx
|
|
||||||
#else
|
|
||||||
mov edx, [eax]
|
|
||||||
mov [ecx], edx
|
|
||||||
mov [edx+4], ecx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
pop ebx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret
|
|
||||||
|
|
||||||
.l4:
|
|
||||||
/* Release lock */
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return empty list */
|
|
||||||
xor eax, eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin4:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start4)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedPopEntryList@8
|
|
||||||
@ExfInterlockedPopEntryList@8:
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start5:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin5)
|
|
||||||
|
|
||||||
/* Get list pointer */
|
|
||||||
mov eax, [ecx]
|
|
||||||
|
|
||||||
/* Check if it's empty */
|
|
||||||
or eax, eax
|
|
||||||
je .l6
|
|
||||||
|
|
||||||
/* Get next entry and do deletion */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
push edx
|
|
||||||
#endif
|
|
||||||
mov edx, [eax]
|
|
||||||
mov [ecx], edx
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
pop edx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
.l5:
|
|
||||||
/* Release lock */
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret
|
|
||||||
|
|
||||||
.l6:
|
|
||||||
/* Return empty list */
|
|
||||||
xor eax, eax
|
|
||||||
jmp .l5
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin5:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start5)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead,
|
|
||||||
* IN PSINGLE_LIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedPushEntryList@12
|
|
||||||
@ExfInterlockedPushEntryList@12:
|
|
||||||
|
|
||||||
/* Save flags */
|
|
||||||
pushfd
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
push edx
|
|
||||||
mov edx, [esp+12]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
.start6:
|
|
||||||
cli
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin6)
|
|
||||||
pop edx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get list pointer */
|
|
||||||
mov eax, [ecx]
|
|
||||||
|
|
||||||
/* Do push */
|
|
||||||
mov [edx], eax
|
|
||||||
mov [ecx], edx
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+8]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin6:
|
|
||||||
pop edx
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
push edx
|
|
||||||
mov edx, [esp+12]
|
|
||||||
SPIN_ON_LOCK(edx, .start6)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
/*PSINGLE_LIST_ENTRY
|
||||||
*FASTCALL
|
*FASTCALL
|
||||||
|
@ -505,301 +181,5 @@ PUBLIC @ExInterlockedFlushSList@4
|
||||||
pop ebx
|
pop ebx
|
||||||
ret
|
ret
|
||||||
|
|
||||||
/*INTERLOCKED_RESULT
|
|
||||||
*FASTCALL
|
|
||||||
*Exfi386InterlockedIncrementLong(IN PLONG Addend)
|
|
||||||
*/
|
|
||||||
PUBLIC @Exfi386InterlockedIncrementLong@4
|
|
||||||
@Exfi386InterlockedIncrementLong@4:
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK add dword ptr [ecx], 1
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
lahf
|
|
||||||
and eax, EFLAG_SELECT
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*INTERLOCKED_RESULT
|
|
||||||
*FASTCALL
|
|
||||||
*Exfi386InterlockedDecrementLong(IN PLONG Addend)
|
|
||||||
*/
|
|
||||||
PUBLIC @Exfi386InterlockedDecrementLong@4
|
|
||||||
@Exfi386InterlockedDecrementLong@4:
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK sub dword ptr [ecx], 1
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
lahf
|
|
||||||
and eax, EFLAG_SELECT
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*ULONG
|
|
||||||
*FASTCALL
|
|
||||||
*Exfi386InterlockedExchangeUlong(IN PULONG Target,
|
|
||||||
* IN ULONG Value)
|
|
||||||
*/
|
|
||||||
PUBLIC @Exfi386InterlockedExchangeUlong@8
|
|
||||||
@Exfi386InterlockedExchangeUlong@8:
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* On MP, do the exchange */
|
|
||||||
xchg [ecx], edx
|
|
||||||
mov eax, edx
|
|
||||||
#else
|
|
||||||
/* On UP, use cmpxchg */
|
|
||||||
mov eax, [ecx]
|
|
||||||
.l11:
|
|
||||||
cmpxchg [ecx], edx
|
|
||||||
jnz .l11
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret
|
|
||||||
|
|
||||||
/*PVOID
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedCompareExchange64(IN PLONGLONG Destination,
|
|
||||||
* IN PLONGLONG Exchange,
|
|
||||||
* IN PLONGLONG Comperand)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedCompareExchange64@12
|
|
||||||
@ExfInterlockedCompareExchange64@12:
|
|
||||||
|
|
||||||
/* Save registers */
|
|
||||||
push ebx
|
|
||||||
push ebp
|
|
||||||
|
|
||||||
/* Get destination pointer, exchange value and comperand value/address */
|
|
||||||
mov ebp, ecx
|
|
||||||
mov ebx, [edx]
|
|
||||||
mov ecx, [edx+4]
|
|
||||||
mov edx, [esp+12]
|
|
||||||
mov eax, [edx]
|
|
||||||
mov edx, [edx+4]
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK cmpxchg8b qword ptr [ebp]
|
|
||||||
|
|
||||||
/* Restore volatiles */
|
|
||||||
pop ebp
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
/*PVOID
|
|
||||||
*FASTCALL
|
|
||||||
*ExInterlockedCompareExchange64(IN PLONGLONG Destination,
|
|
||||||
* IN PLONGLONG Exchange,
|
|
||||||
* IN PLONGLONG Comperand,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExInterlockedCompareExchange64@16
|
|
||||||
@ExInterlockedCompareExchange64@16:
|
|
||||||
|
|
||||||
/* Save registers */
|
|
||||||
push ebx
|
|
||||||
push ebp
|
|
||||||
|
|
||||||
/* Get destination pointer, exchange value and comperand value/address */
|
|
||||||
mov ebp, ecx
|
|
||||||
mov ebx, [edx]
|
|
||||||
mov ecx, [edx+4]
|
|
||||||
mov edx, [esp+12]
|
|
||||||
mov eax, [edx]
|
|
||||||
mov edx, [edx+4]
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK cmpxchg8b qword ptr [ebp]
|
|
||||||
|
|
||||||
/* Restore volatiles */
|
|
||||||
pop ebp
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
/*** Non-586 functions ***/
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedPopEntrySList@8
|
|
||||||
@ExfInterlockedPopEntrySList@8:
|
|
||||||
|
|
||||||
/* Save flags */
|
|
||||||
.starta:
|
|
||||||
pushfd
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spina)
|
|
||||||
|
|
||||||
/* Get the next link and check if it's empty */
|
|
||||||
mov eax, [ecx]
|
|
||||||
or eax, eax
|
|
||||||
jz .l12
|
|
||||||
|
|
||||||
/* Get address of the next link and store it */
|
|
||||||
push [eax]
|
|
||||||
pop [ecx]
|
|
||||||
|
|
||||||
/* Decrement list depth */
|
|
||||||
dec dword ptr [ecx+4]
|
|
||||||
|
|
||||||
.l12:
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Release spinlock */
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags and return */
|
|
||||||
popfd
|
|
||||||
ret 0
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spina:
|
|
||||||
/* Restore flags and spin */
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .starta)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
|
||||||
*FASTCALL
|
|
||||||
*ExfInterlockedPushEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
|
|
||||||
* IN PSINGLE_LIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExfInterlockedPushEntrySList@12
|
|
||||||
@ExfInterlockedPushEntrySList@12:
|
|
||||||
|
|
||||||
/* Save flags */
|
|
||||||
.startb:
|
|
||||||
pushfd
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
#ifndef CONFIG_SMP
|
|
||||||
mov eax, [esp+8]
|
|
||||||
ACQUIRE_SPINLOCK(eax, .spinb)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Get the next link and check if it's empty */
|
|
||||||
push [ecx]
|
|
||||||
|
|
||||||
/* Get address of the next link and store it */
|
|
||||||
pop [edx]
|
|
||||||
mov [ecx], edx
|
|
||||||
|
|
||||||
/* Increment list depth */
|
|
||||||
inc dword ptr [ecx+4]
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Release spinlock */
|
|
||||||
RELEASE_SPINLOCK(eax)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags and return */
|
|
||||||
popfd
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spinb:
|
|
||||||
/* Restore flags and spin */
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(eax, .startb)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PVOID
|
|
||||||
*FASTCALL
|
|
||||||
*ExpInterlockedCompareExchange64(IN PLONGLONG Destination,
|
|
||||||
* IN PLONGLONG Exchange,
|
|
||||||
* IN PLONGLONG Comperand,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC @ExpInterlockedCompareExchange64@16
|
|
||||||
@ExpInterlockedCompareExchange64@16:
|
|
||||||
|
|
||||||
/* Save registers */
|
|
||||||
push ebp
|
|
||||||
push ebp
|
|
||||||
|
|
||||||
/* Get destination pointer, exchange value and comperand value/address */
|
|
||||||
mov ebp, ecx
|
|
||||||
mov ebx, [edx]
|
|
||||||
mov ecx, [edx+4]
|
|
||||||
mov edx, [esp+12]
|
|
||||||
mov eax, [edx]
|
|
||||||
mov edx, [edx+4]
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Save ESI so we can store KSPINLOCK in it */
|
|
||||||
push esi
|
|
||||||
|
|
||||||
/* Save flags and lock, and disable interrupts */
|
|
||||||
pushfd
|
|
||||||
mov esi, [esp+24]
|
|
||||||
.startc:
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire the spinlock */
|
|
||||||
ACQUIRE_SPINLOCK(esi, .spinc)
|
|
||||||
#else
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Compare bottom */
|
|
||||||
cmp eax, [ebp]
|
|
||||||
jne NoMatch
|
|
||||||
|
|
||||||
/* Compare top */
|
|
||||||
cmp edx, [ebp+4]
|
|
||||||
jne NoMatch
|
|
||||||
|
|
||||||
/* Save new value */
|
|
||||||
mov [ebp], ebx
|
|
||||||
mov [ebp+4], ecx
|
|
||||||
|
|
||||||
AfterSave:
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Release lock, restore volatiles and flags */
|
|
||||||
RELEASE_SPINLOCK(esi)
|
|
||||||
popfd
|
|
||||||
pop esi
|
|
||||||
#else
|
|
||||||
popfd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore the other volatiles and return */
|
|
||||||
pop ebp
|
|
||||||
pop ebx
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
NoMatch:
|
|
||||||
/* Return the current value */
|
|
||||||
mov eax, [ebp]
|
|
||||||
mov edx, [ebp+4]
|
|
||||||
jmp AfterSave
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spinc:
|
|
||||||
/* Restore flags and spin */
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
SPIN_ON_LOCK(esi, .startc)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
END
|
END
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
|
@ -1,569 +0,0 @@
|
||||||
/*
|
|
||||||
* COPYRIGHT: See COPYING in the top level directory
|
|
||||||
* PROJECT: ReactOS kernel
|
|
||||||
* FILE: ntoskrnl/ex/i386/interlck_asm.S
|
|
||||||
* PURPOSE: STDCALL Interlocked Functions
|
|
||||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* INCLUDES ******************************************************************/
|
|
||||||
|
|
||||||
#include <asm.inc>
|
|
||||||
#include <ks386.inc>
|
|
||||||
#include <internal/i386/asmmacro.S>
|
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
|
||||||
|
|
||||||
.code32
|
|
||||||
|
|
||||||
/*
|
|
||||||
* NOTE: These functions must obey the following rules:
|
|
||||||
* - Acquire locks only on MP systems.
|
|
||||||
* - Be safe at HIGH_LEVEL (no paged access).
|
|
||||||
* - Preserve flags.
|
|
||||||
* - Disable interrups.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedAddLargeInteger(IN PLARGE_INTEGER Addend,
|
|
||||||
* IN LARGE_INTEGER Increment,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedAddLargeInteger@16
|
|
||||||
_ExInterlockedAddLargeInteger@16:
|
|
||||||
|
|
||||||
/* Prepare stack frame */
|
|
||||||
push ebp
|
|
||||||
mov ebp, esp
|
|
||||||
sub esp, 8
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov eax, [ebp+20]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start1:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
ACQUIRE_SPINLOCK(eax, .spin1)
|
|
||||||
|
|
||||||
/* Do the calculation */
|
|
||||||
mov eax, [ebp+8]
|
|
||||||
mov ecx, [eax]
|
|
||||||
mov edx, [eax+4]
|
|
||||||
|
|
||||||
/* Save result */
|
|
||||||
mov [ebp-8], ecx
|
|
||||||
mov [ebp-4], edx
|
|
||||||
|
|
||||||
/* Add increment */
|
|
||||||
add ecx, [ebp+12]
|
|
||||||
adc edx, [ebp+16]
|
|
||||||
|
|
||||||
/* Save result */
|
|
||||||
mov [eax], ecx
|
|
||||||
mov [eax+4], edx
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov eax, [ebp+20]
|
|
||||||
RELEASE_SPINLOCK(eax)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Restore frame and return values */
|
|
||||||
mov eax, [ebp-8]
|
|
||||||
mov edx, [ebp-4]
|
|
||||||
mov esp, ebp
|
|
||||||
pop ebp
|
|
||||||
ret 16
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin1:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(eax, .start1)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedAddUlong(IN PULONG Addend,
|
|
||||||
* IN ULONG Increment,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedAddUlong@12
|
|
||||||
_ExInterlockedAddUlong@12:
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
pushfd
|
|
||||||
|
|
||||||
/* Get lock address */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [ebp+16]
|
|
||||||
#endif
|
|
||||||
.start2:
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Acquire lock */
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin2)
|
|
||||||
|
|
||||||
/* Do the calculation */
|
|
||||||
mov ecx, [esp+8]
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov eax, [ecx]
|
|
||||||
add eax, [esp+12]
|
|
||||||
|
|
||||||
/* Save result */
|
|
||||||
mov [ecx], eax
|
|
||||||
#else
|
|
||||||
|
|
||||||
/* Do the calculation */
|
|
||||||
mov edx, [ecx]
|
|
||||||
mov eax, edx
|
|
||||||
add edx, [esp+12]
|
|
||||||
|
|
||||||
/* Save result */
|
|
||||||
mov [ecx], edx
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Release lock, restore flags and return */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
sub eax, [esp+12]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
popfd
|
|
||||||
ret 12
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin2:
|
|
||||||
popfd
|
|
||||||
pushfd
|
|
||||||
SPIN_ON_LOCK(eax, .start2)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedInsertHeadList(IN PLIST_ENTRY ListHead,
|
|
||||||
* IN PLIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedInsertHeadList@12
|
|
||||||
_ExInterlockedInsertHeadList@12:
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+12]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start3:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin3)
|
|
||||||
|
|
||||||
/* Get list pointers */
|
|
||||||
mov eax, [esp+8]
|
|
||||||
mov ecx, [esp+12]
|
|
||||||
mov edx, [eax]
|
|
||||||
|
|
||||||
/* Do the insert */
|
|
||||||
mov [ecx], edx
|
|
||||||
mov [ecx+4], eax
|
|
||||||
mov [eax], ecx
|
|
||||||
mov [edx+4], ecx
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov ecx, [esp+16]
|
|
||||||
RELEASE_SPINLOCK(ecx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* check if the list was empty and return NULL */
|
|
||||||
xor eax, edx
|
|
||||||
jz .l2
|
|
||||||
|
|
||||||
/* Return pointer */
|
|
||||||
mov eax, edx
|
|
||||||
|
|
||||||
.l2:
|
|
||||||
ret 12
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin3:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start3)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedInsertTailList(IN PLIST_ENTRY ListHead,
|
|
||||||
* IN PLIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedInsertTailList@12
|
|
||||||
_ExInterlockedInsertTailList@12:
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+12]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start4:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin4)
|
|
||||||
|
|
||||||
/* Get list pointers */
|
|
||||||
mov eax, [esp+8]
|
|
||||||
mov ecx, [esp+12]
|
|
||||||
mov edx, [eax+4]
|
|
||||||
|
|
||||||
/* Do the insert */
|
|
||||||
mov [ecx], eax
|
|
||||||
mov [ecx+4], edx
|
|
||||||
mov [eax+4], ecx
|
|
||||||
mov [edx], ecx
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov ecx, [esp+16]
|
|
||||||
RELEASE_SPINLOCK(ecx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Check if the list was empty and return NULL */
|
|
||||||
xor eax, edx
|
|
||||||
jz .l3
|
|
||||||
|
|
||||||
/* Return pointer */
|
|
||||||
mov eax, edx
|
|
||||||
|
|
||||||
.l3:
|
|
||||||
ret 12
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin4:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start4)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PLIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedRemoveHeadList(IN PLIST_ENTRY ListHead,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedRemoveHeadList@8
|
|
||||||
_ExInterlockedRemoveHeadList@8:
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+8]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start5:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin5)
|
|
||||||
|
|
||||||
/* Get list pointers */
|
|
||||||
mov edx, [esp+8]
|
|
||||||
mov eax, [edx]
|
|
||||||
|
|
||||||
/* Check if it's empty */
|
|
||||||
cmp eax, edx
|
|
||||||
je .l4
|
|
||||||
|
|
||||||
/* Get next entry and do deletion */
|
|
||||||
mov ecx, [eax]
|
|
||||||
mov [edx], ecx
|
|
||||||
mov [ecx+4], edx
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov ecx, [esp+12]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
.l4:
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+12]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return empty list */
|
|
||||||
xor eax, eax
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin5:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start5)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedPopEntryList(IN PSINGLE_LIST_ENTRY ListHead,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedPopEntryList@8
|
|
||||||
_ExInterlockedPopEntryList@8:
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+8]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start6:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin6)
|
|
||||||
|
|
||||||
/* Get list pointers */
|
|
||||||
mov edx, [esp+8]
|
|
||||||
mov eax, [ecx]
|
|
||||||
|
|
||||||
/* Check if it's empty */
|
|
||||||
or eax, eax
|
|
||||||
je .l6
|
|
||||||
|
|
||||||
/* Get next entry and do deletion */
|
|
||||||
mov edx, [eax]
|
|
||||||
mov [ecx], edx
|
|
||||||
|
|
||||||
.l5:
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov ecx, [esp+12]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
.l6:
|
|
||||||
/* Return empty list */
|
|
||||||
xor eax, eax
|
|
||||||
jmp .l5
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin6:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start6)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*PSINGLE_LIST_ENTRY
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedPushEntryList(IN PSINGLE_LIST_ENTRY ListHead,
|
|
||||||
* IN PSINGLE_LIST_ENTRY ListEntry,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedPushEntryList@12
|
|
||||||
_ExInterlockedPushEntryList@12:
|
|
||||||
|
|
||||||
/* Save lock pointer */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov edx, [esp+12]
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save flags and disable interrupts */
|
|
||||||
.start7:
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
ACQUIRE_SPINLOCK(edx, .spin7)
|
|
||||||
|
|
||||||
/* Get list pointers */
|
|
||||||
mov edx, [esp+8]
|
|
||||||
mov eax, [edx]
|
|
||||||
mov ecx, [esp+12]
|
|
||||||
|
|
||||||
/* Do push */
|
|
||||||
mov [ecx], eax
|
|
||||||
mov [edx], ecx
|
|
||||||
|
|
||||||
/* Release lock */
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
mov ecx, [esp+16]
|
|
||||||
RELEASE_SPINLOCK(edx)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Restore flags */
|
|
||||||
popfd
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 12
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
.spin7:
|
|
||||||
popfd
|
|
||||||
SPIN_ON_LOCK(edx, .start7)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*INTERLOCKED_RESULT
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedIncrementLong(IN PLONG Addend,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedIncrementLong@8
|
|
||||||
_ExInterlockedIncrementLong@8:
|
|
||||||
|
|
||||||
/* Get addend */
|
|
||||||
mov eax, [esp+4]
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK add dword ptr [eax], 1
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
lahf
|
|
||||||
and eax, EFLAG_SELECT
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
/*INTERLOCKED_RESULT
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedDecrementLong(IN PLONG Addend,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedDecrementLong@8
|
|
||||||
_ExInterlockedDecrementLong@8:
|
|
||||||
|
|
||||||
/* Get addend */
|
|
||||||
mov eax, [esp+4]
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK sub dword ptr [eax], 1
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
lahf
|
|
||||||
and eax, EFLAG_SELECT
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
/*ULONG
|
|
||||||
*NTAPI
|
|
||||||
*ExInterlockedExchangeUlong(IN PULONG Target,
|
|
||||||
* IN ULONG Value,
|
|
||||||
* IN PKSPIN_LOCK Lock)
|
|
||||||
*/
|
|
||||||
PUBLIC _ExInterlockedExchangeUlong@12
|
|
||||||
_ExInterlockedExchangeUlong@12:
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Get pointers */
|
|
||||||
mov edx, [esp+4]
|
|
||||||
mov eax, [esp+8]
|
|
||||||
|
|
||||||
/* On MP, do the exchange */
|
|
||||||
xchg [edx], eax
|
|
||||||
#else
|
|
||||||
/* Get pointers */
|
|
||||||
mov edx, [esp+4]
|
|
||||||
mov ecx, [esp+8]
|
|
||||||
|
|
||||||
/* On UP, disable interrupts and save flags */
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Switch values */
|
|
||||||
mov eax, [edx]
|
|
||||||
mov [edx], ecx
|
|
||||||
popfd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 12
|
|
||||||
|
|
||||||
/*INTERLOCKED_RESULT
|
|
||||||
*NTAPI
|
|
||||||
*Exi386InterlockedIncrementLong(IN PLONG Addend)
|
|
||||||
*/
|
|
||||||
PUBLIC _Exi386InterlockedIncrementLong@4
|
|
||||||
_Exi386InterlockedIncrementLong@4:
|
|
||||||
|
|
||||||
/* Get addend */
|
|
||||||
mov eax, [esp+4]
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK add dword ptr [eax], 1
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
lahf
|
|
||||||
and eax, EFLAG_SELECT
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
/*INTERLOCKED_RESULT
|
|
||||||
*NTAPI
|
|
||||||
*Exi386InterlockedDecrementLong(IN PLONG Addend)
|
|
||||||
*/
|
|
||||||
PUBLIC _Exi386InterlockedDecrementLong@4
|
|
||||||
_Exi386InterlockedDecrementLong@4:
|
|
||||||
|
|
||||||
/* Get addend */
|
|
||||||
mov eax, [esp+4]
|
|
||||||
|
|
||||||
/* Do the op */
|
|
||||||
LOCK sub dword ptr [eax], 1
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
lahf
|
|
||||||
and eax, EFLAG_SELECT
|
|
||||||
ret 4
|
|
||||||
|
|
||||||
/*ULONG
|
|
||||||
*NTAPI
|
|
||||||
*Exi386InterlockedExchangeUlong(IN PULONG Target,
|
|
||||||
* IN ULONG Value)
|
|
||||||
*/
|
|
||||||
PUBLIC _Exi386InterlockedExchangeUlong@8
|
|
||||||
_Exi386InterlockedExchangeUlong@8:
|
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
/* Get pointers */
|
|
||||||
mov edx, [esp+4]
|
|
||||||
mov eax, [esp+8]
|
|
||||||
|
|
||||||
/* On MP, do the exchange */
|
|
||||||
xchg [edx], eax
|
|
||||||
#else
|
|
||||||
/* Get pointers */
|
|
||||||
mov edx, [esp+4]
|
|
||||||
mov ecx, [esp+8]
|
|
||||||
|
|
||||||
/* On UP, disable interrupts and save flags */
|
|
||||||
pushfd
|
|
||||||
cli
|
|
||||||
|
|
||||||
/* Switch values */
|
|
||||||
mov eax, [edx]
|
|
||||||
mov [edx], ecx
|
|
||||||
popfd
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Return */
|
|
||||||
ret 8
|
|
||||||
|
|
||||||
END
|
|
||||||
/* EOF */
|
|
542
reactos/ntoskrnl/ex/i386/interlocked.c
Normal file
542
reactos/ntoskrnl/ex/i386/interlocked.c
Normal file
|
@ -0,0 +1,542 @@
|
||||||
|
/*
|
||||||
|
* PROJECT: ReactOS Kernel
|
||||||
|
* LICENSE: GPL - See COPYING in the top level directory
|
||||||
|
* FILE: ntoskrnl/ex/interlocked.c
|
||||||
|
* PURPOSE: Interlocked functions
|
||||||
|
* PROGRAMMERS: Timo Kreuzer (timo.kreuzer@reactos.org)
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* INCLUDES *****************************************************************/
|
||||||
|
|
||||||
|
#include <ntoskrnl.h>
|
||||||
|
|
||||||
|
#define NDEBUG
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
|
#undef ExInterlockedAddUlong
|
||||||
|
#undef ExInterlockedInsertHeadList
|
||||||
|
#undef ExInterlockedInsertTailList
|
||||||
|
#undef ExInterlockedRemoveHeadList
|
||||||
|
#undef ExInterlockedPopEntryList
|
||||||
|
#undef ExInterlockedPushEntryList
|
||||||
|
#undef ExInterlockedIncrementLong
|
||||||
|
#undef ExInterlockedDecrementLong
|
||||||
|
#undef ExInterlockedExchangeUlong
|
||||||
|
#undef ExInterlockedCompareExchange64
|
||||||
|
|
||||||
|
|
||||||
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
#if defined(_M_IX86 ) || defined(_M_AMD64)
|
||||||
|
FORCEINLINE
|
||||||
|
ULONG_PTR
|
||||||
|
_ExiDisableInteruptsAndAcquireSpinlock(
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
UINT_PTR EFlags;
|
||||||
|
|
||||||
|
/* Save flags */
|
||||||
|
EFlags = __readeflags();
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
_disable();
|
||||||
|
|
||||||
|
/* Acquire the spinlock (inline) */
|
||||||
|
KxAcquireSpinLock(Lock);
|
||||||
|
|
||||||
|
return EFlags;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(
|
||||||
|
IN OUT PKSPIN_LOCK Lock,
|
||||||
|
ULONG_PTR EFlags)
|
||||||
|
{
|
||||||
|
/* Release the spinlock */
|
||||||
|
KxReleaseSpinLock(Lock);
|
||||||
|
|
||||||
|
/* Restore flags */
|
||||||
|
__writeeflags(EFlags);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
#error Unimplemented
|
||||||
|
#endif
|
||||||
|
|
||||||
|
LARGE_INTEGER
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedAddLargeInteger(
|
||||||
|
IN OUT PLARGE_INTEGER Addend,
|
||||||
|
IN LARGE_INTEGER Increment,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
LARGE_INTEGER OldValue;
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the old value */
|
||||||
|
OldValue.QuadPart = Addend->QuadPart;
|
||||||
|
|
||||||
|
/* Do the operation */
|
||||||
|
Addend->QuadPart += Increment.QuadPart;
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the old value */
|
||||||
|
return OldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedAddUlong(
|
||||||
|
IN OUT PULONG Addend,
|
||||||
|
IN ULONG Increment,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
ULONG OldValue;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the old value */
|
||||||
|
OldValue = *Addend;
|
||||||
|
|
||||||
|
/* Do the operation */
|
||||||
|
*Addend += Increment;
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the old value */
|
||||||
|
return OldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLIST_ENTRY
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedInsertHeadList(
|
||||||
|
IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN OUT PLIST_ENTRY ListEntry,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PLIST_ENTRY FirstEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the first entry */
|
||||||
|
FirstEntry = ListHead->Flink;
|
||||||
|
|
||||||
|
/* Insert the new entry */
|
||||||
|
InsertHeadList(ListHead, ListEntry);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the first entry */
|
||||||
|
return FirstEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLIST_ENTRY
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedInsertTailList(
|
||||||
|
IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN OUT PLIST_ENTRY ListEntry,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PLIST_ENTRY LastEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the last entry */
|
||||||
|
LastEntry = ListHead->Blink;
|
||||||
|
|
||||||
|
/* Insert the new entry */
|
||||||
|
InsertTailList(ListHead, ListEntry);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the last entry */
|
||||||
|
return LastEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLIST_ENTRY
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedRemoveHeadList(
|
||||||
|
IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Remove the first entry from the list head */
|
||||||
|
ListEntry = RemoveHeadList(ListHead);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the entry */
|
||||||
|
return ListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSINGLE_LIST_ENTRY
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedPopEntryList(
|
||||||
|
IN OUT PSINGLE_LIST_ENTRY ListHead,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PSINGLE_LIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Pop the first entry from the list */
|
||||||
|
ListEntry = PopEntryList(ListHead);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the entry */
|
||||||
|
return ListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSINGLE_LIST_ENTRY
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedPushEntryList(
|
||||||
|
IN OUT PSINGLE_LIST_ENTRY ListHead,
|
||||||
|
IN OUT PSINGLE_LIST_ENTRY ListEntry,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PSINGLE_LIST_ENTRY OldListEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the old top entry */
|
||||||
|
OldListEntry = ListHead->Next;
|
||||||
|
|
||||||
|
/* Push a new entry on the list */
|
||||||
|
PushEntryList(ListHead, ListEntry);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the entry */
|
||||||
|
return OldListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERLOCKED_RESULT
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedIncrementLong(
|
||||||
|
IN PLONG Addend,
|
||||||
|
IN PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
LONG Result;
|
||||||
|
|
||||||
|
Result = _InterlockedIncrement(Addend);
|
||||||
|
return (Result < 0) ? ResultNegative :
|
||||||
|
(Result > 0) ? ResultPositive :
|
||||||
|
ResultZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERLOCKED_RESULT
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedDecrementLong(
|
||||||
|
IN PLONG Addend,
|
||||||
|
IN PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
LONG Result;
|
||||||
|
|
||||||
|
Result = _InterlockedDecrement(Addend);
|
||||||
|
return (Result < 0) ? ResultNegative :
|
||||||
|
(Result > 0) ? ResultPositive :
|
||||||
|
ResultZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
NTAPI
|
||||||
|
ExInterlockedExchangeUlong(
|
||||||
|
IN PULONG Target,
|
||||||
|
IN ULONG Value,
|
||||||
|
IN PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
return (ULONG)_InterlockedExchange((PLONG)Target, (LONG)Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef _M_IX86
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedAddUlong(
|
||||||
|
IN OUT PULONG Addend,
|
||||||
|
IN ULONG Increment,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
ULONG OldValue;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the old value */
|
||||||
|
OldValue = *Addend;
|
||||||
|
|
||||||
|
/* Do the operation */
|
||||||
|
*Addend += Increment;
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the old value */
|
||||||
|
return OldValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLIST_ENTRY
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedInsertHeadList(
|
||||||
|
IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN PLIST_ENTRY ListEntry,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PLIST_ENTRY FirstEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the first entry */
|
||||||
|
FirstEntry = ListHead->Flink;
|
||||||
|
|
||||||
|
/* Insert the new entry */
|
||||||
|
InsertHeadList(ListHead, ListEntry);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the first entry */
|
||||||
|
return FirstEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PLIST_ENTRY
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedInsertTailList(
|
||||||
|
IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN PLIST_ENTRY ListEntry,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PLIST_ENTRY LastEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the last entry */
|
||||||
|
LastEntry = ListHead->Blink;
|
||||||
|
|
||||||
|
/* Insert the new entry */
|
||||||
|
InsertTailList(ListHead, ListEntry);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the last entry */
|
||||||
|
return LastEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PLIST_ENTRY
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedRemoveHeadList(
|
||||||
|
IN OUT PLIST_ENTRY ListHead,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PLIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Check if the list is empty */
|
||||||
|
if (IsListEmpty(ListHead))
|
||||||
|
{
|
||||||
|
/* Return NULL */
|
||||||
|
ListEntry = NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Remove the first entry from the list head */
|
||||||
|
ListEntry = RemoveHeadList(ListHead);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the entry */
|
||||||
|
return ListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSINGLE_LIST_ENTRY
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedPopEntryList(
|
||||||
|
IN OUT PSINGLE_LIST_ENTRY ListHead,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PSINGLE_LIST_ENTRY ListEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Pop the first entry from the list */
|
||||||
|
ListEntry = PopEntryList(ListHead);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the entry */
|
||||||
|
return ListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
PSINGLE_LIST_ENTRY
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedPushEntryList(
|
||||||
|
IN OUT PSINGLE_LIST_ENTRY ListHead,
|
||||||
|
IN PSINGLE_LIST_ENTRY ListEntry,
|
||||||
|
IN OUT PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
ULONG_PTR LockHandle;
|
||||||
|
PSINGLE_LIST_ENTRY OldListEntry;
|
||||||
|
|
||||||
|
/* Disable interrupts and acquire the spinlock */
|
||||||
|
LockHandle = _ExiDisableInteruptsAndAcquireSpinlock(Lock);
|
||||||
|
|
||||||
|
/* Save the old top entry */
|
||||||
|
OldListEntry = ListHead->Next;
|
||||||
|
|
||||||
|
/* Push a new entry on the list */
|
||||||
|
PushEntryList(ListHead, ListEntry);
|
||||||
|
|
||||||
|
/* Release the spinlock and restore interrupts */
|
||||||
|
_ExiReleaseSpinLockAndRestoreInterupts(Lock, LockHandle);
|
||||||
|
|
||||||
|
/* return the entry */
|
||||||
|
return OldListEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERLOCKED_RESULT
|
||||||
|
NTAPI
|
||||||
|
Exi386InterlockedIncrementLong(
|
||||||
|
IN PLONG Addend)
|
||||||
|
{
|
||||||
|
LONG Result;
|
||||||
|
|
||||||
|
Result = _InterlockedIncrement(Addend);
|
||||||
|
return (Result < 0) ? ResultNegative :
|
||||||
|
(Result > 0) ? ResultPositive :
|
||||||
|
ResultZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERLOCKED_RESULT
|
||||||
|
FASTCALL
|
||||||
|
Exfi386InterlockedIncrementLong(
|
||||||
|
IN OUT LONG volatile *Addend)
|
||||||
|
{
|
||||||
|
LONG Result;
|
||||||
|
|
||||||
|
Result = _InterlockedIncrement(Addend);
|
||||||
|
return (Result < 0) ? ResultNegative :
|
||||||
|
(Result > 0) ? ResultPositive :
|
||||||
|
ResultZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERLOCKED_RESULT
|
||||||
|
NTAPI
|
||||||
|
Exi386InterlockedDecrementLong(
|
||||||
|
IN PLONG Addend)
|
||||||
|
{
|
||||||
|
LONG Result;
|
||||||
|
|
||||||
|
Result = _InterlockedDecrement(Addend);
|
||||||
|
return (Result < 0) ? ResultNegative :
|
||||||
|
(Result > 0) ? ResultPositive :
|
||||||
|
ResultZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
INTERLOCKED_RESULT
|
||||||
|
FASTCALL
|
||||||
|
Exfi386InterlockedDecrementLong(
|
||||||
|
IN OUT PLONG Addend)
|
||||||
|
{
|
||||||
|
LONG Result;
|
||||||
|
|
||||||
|
Result = _InterlockedDecrement(Addend);
|
||||||
|
return (Result < 0) ? ResultNegative :
|
||||||
|
(Result > 0) ? ResultPositive :
|
||||||
|
ResultZero;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG
|
||||||
|
NTAPI
|
||||||
|
Exi386InterlockedExchangeUlong(
|
||||||
|
PLONG Target,
|
||||||
|
LONG Exchange)
|
||||||
|
{
|
||||||
|
return _InterlockedExchange(Target, Exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
ULONG
|
||||||
|
FASTCALL
|
||||||
|
Exfi386InterlockedExchangeUlong(
|
||||||
|
IN OUT PULONG Target,
|
||||||
|
IN ULONG Exchange)
|
||||||
|
{
|
||||||
|
return _InterlockedExchange((PLONG)Target, Exchange);
|
||||||
|
}
|
||||||
|
|
||||||
|
LONGLONG
|
||||||
|
FASTCALL
|
||||||
|
ExInterlockedCompareExchange64(
|
||||||
|
IN OUT LONGLONG volatile *Destination,
|
||||||
|
IN PLONGLONG Exchange,
|
||||||
|
IN PLONGLONG Comparand,
|
||||||
|
IN PKSPIN_LOCK Lock)
|
||||||
|
{
|
||||||
|
return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand);
|
||||||
|
}
|
||||||
|
|
||||||
|
LONGLONG
|
||||||
|
FASTCALL
|
||||||
|
ExfInterlockedCompareExchange64(
|
||||||
|
IN OUT LONGLONG volatile *Destination,
|
||||||
|
IN PLONGLONG Exchange,
|
||||||
|
IN PLONGLONG Comparand)
|
||||||
|
{
|
||||||
|
return _InterlockedCompareExchange64(Destination, *Exchange, *Comparand);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
ExInterlockedAddLargeStatistic(
|
||||||
|
IN OUT PLARGE_INTEGER Addend,
|
||||||
|
IN ULONG Increment)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in a new issue