mirror of
https://github.com/reactos/reactos.git
synced 2024-08-30 07:08:19 +00:00
* Implement 3 out of 4 486-compatible ExInterlocked functions which use spinlock instead of cmpxhcg8. Code not yet tested and this code path is not made hot (enabled) yet.
svn path=/trunk/; revision=20941
This commit is contained in:
parent
2bce2ab662
commit
419e7bb9d5
|
@ -679,4 +679,182 @@
|
|||
mov eax, edx
|
||||
ret
|
||||
|
||||
/*** Non-586 functions ***/
|
||||
|
||||
/*PSINGLE_LIST_ENTRY
|
||||
*NTAPI
|
||||
*ExfInterlockedPopEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
|
||||
* IN PKSPIN_LOCK Lock)
|
||||
*/
|
||||
.global @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 1f
|
||||
|
||||
/* Get address of the next link and store it */
|
||||
push [eax]
|
||||
pop [ecx]
|
||||
|
||||
/* Decrement list depth */
|
||||
dec dword ptr [ecx+4]
|
||||
|
||||
1:
|
||||
#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
|
||||
*NTAPI
|
||||
*ExInterlockedPushEntrySList(IN PSINGLE_LIST_ENTRY ListHead,
|
||||
* IN PSINGLE_LIST_ENTRY ListEntry,
|
||||
* IN PKSPIN_LOCK Lock)
|
||||
*/
|
||||
.global @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 0
|
||||
|
||||
#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)
|
||||
*/
|
||||
.global @ExpInterlockedCompareExchange64@16
|
||||
@ExpInterlockedCompareExchange64@16:
|
||||
|
||||
/* Save registers */
|
||||
push ebp
|
||||
push ebp
|
||||
|
||||
/* Get desination 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]
|
||||
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
|
||||
/* EOF */
|
||||
|
|
Loading…
Reference in a new issue