mirror of
https://github.com/reactos/reactos.git
synced 2025-08-01 17:03:00 +00:00
- Implemented Queued and In-Stack Queued Spinlocks (at DPC-Level). See "Windows Internals II" Chapter 4, Pages 25-27.
svn path=/trunk/; revision=20573
This commit is contained in:
parent
4c4d352a5e
commit
5bba25c90e
1 changed files with 80 additions and 4 deletions
|
@ -18,6 +18,9 @@
|
||||||
#undef KefReleaseSpinLockFromDpcLevel
|
#undef KefReleaseSpinLockFromDpcLevel
|
||||||
#undef KeReleaseSpinLockFromDpcLevel
|
#undef KeReleaseSpinLockFromDpcLevel
|
||||||
|
|
||||||
|
#define LQ_WAIT 1
|
||||||
|
#define LQ_OWN 2
|
||||||
|
|
||||||
/* FUNCTIONS ***************************************************************/
|
/* FUNCTIONS ***************************************************************/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -190,25 +193,98 @@ KiReleaseSpinLock(PKSPIN_LOCK SpinLock)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KeAcquireQueuedSpinLockAtDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
PKSPIN_LOCK_QUEUE Prev;
|
||||||
|
|
||||||
|
/* Set the new lock */
|
||||||
|
Prev = (PKSPIN_LOCK_QUEUE)
|
||||||
|
InterlockedExchange((PLONG)LockHandle->LockQueue.Lock,
|
||||||
|
(LONG)LockHandle);
|
||||||
|
if (!Prev)
|
||||||
|
{
|
||||||
|
/* There was nothing there before. We now own it */
|
||||||
|
*(ULONG_PTR*)&LockHandle->LockQueue.Lock |= LQ_OWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set the wait flag */
|
||||||
|
*(ULONG_PTR*)&LockHandle->LockQueue.Lock |= LQ_WAIT;
|
||||||
|
|
||||||
|
/* Link us */
|
||||||
|
Prev->Next = (PKSPIN_LOCK_QUEUE)LockHandle;
|
||||||
|
|
||||||
|
/* Loop and wait */
|
||||||
|
while ( *(ULONG_PTR*)&LockHandle->LockQueue.Lock & LQ_WAIT) YieldProcessor();
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KeReleaseQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
KSPIN_LOCK LockVal;
|
||||||
|
PKSPIN_LOCK_QUEUE Waiter;
|
||||||
|
|
||||||
|
/* Remove own and wait flags */
|
||||||
|
*(ULONG_PTR*)&LockHandle->LockQueue.Lock &= ~(LQ_OWN | LQ_WAIT);
|
||||||
|
LockVal = *LockHandle->LockQueue.Lock;
|
||||||
|
|
||||||
|
/* Check if we already own it */
|
||||||
|
if (LockVal == (KSPIN_LOCK)LockHandle)
|
||||||
|
{
|
||||||
|
/* Disown it */
|
||||||
|
LockVal = (KSPIN_LOCK)
|
||||||
|
InterlockedCompareExchangePointer(LockHandle->LockQueue.Lock,
|
||||||
|
NULL,
|
||||||
|
LockHandle);
|
||||||
|
}
|
||||||
|
if (LockVal == (KSPIN_LOCK)LockHandle) return;
|
||||||
|
|
||||||
|
/* Need to wait for it */
|
||||||
|
Waiter = LockHandle->LockQueue.Next;
|
||||||
|
while (!Waiter)
|
||||||
|
{
|
||||||
|
YieldProcessor();
|
||||||
|
Waiter = LockHandle->LockQueue.Next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* It's gone */
|
||||||
|
*(ULONG_PTR*)&Waiter->Lock ^= (LQ_OWN | LQ_WAIT);
|
||||||
|
LockHandle->LockQueue.Next = NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock,
|
KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock,
|
||||||
IN PKLOCK_QUEUE_HANDLE LockHandle)
|
IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
/* Set it up properly */
|
||||||
|
LockHandle->LockQueue.Next = NULL;
|
||||||
|
LockHandle->LockQueue.Lock = SpinLock;
|
||||||
|
KeAcquireQueuedSpinLockAtDpcLevel((PKLOCK_QUEUE_HANDLE)
|
||||||
|
&LockHandle->LockQueue.Next);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @unimplemented
|
* @implemented
|
||||||
*/
|
*/
|
||||||
VOID
|
VOID
|
||||||
FASTCALL
|
FASTCALL
|
||||||
KeReleaseInStackQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
KeReleaseInStackQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
||||||
{
|
{
|
||||||
UNIMPLEMENTED;
|
/* Call the internal function */
|
||||||
|
KeReleaseQueuedSpinLockFromDpcLevel((PKLOCK_QUEUE_HANDLE)
|
||||||
|
&LockHandle->LockQueue.Next);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue