mirror of
https://github.com/reactos/reactos.git
synced 2025-04-21 12:40:33 +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)
|
||||
list(APPEND SOURCE
|
||||
config/i386/cmhardwr.c
|
||||
ex/i386/interlck_asm.S
|
||||
ex/i386/fastinterlck_asm.S
|
||||
ex/i386/interlocked.c
|
||||
ex/i386/ioport.S
|
||||
ke/i386/abios.c
|
||||
ke/i386/cpu.c
|
||||
|
|
|
@ -51,331 +51,7 @@ PUBLIC @ExInterlockedAddLargeStatistic@8
|
|||
/* Return */
|
||||
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
|
||||
*FASTCALL
|
||||
|
@ -505,301 +181,5 @@ PUBLIC @ExInterlockedFlushSList@4
|
|||
pop ebx
|
||||
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
|
||||
/* 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