#include <ntoskrnl.h>
#define NDEBUG
-#include <internal/debug.h>
+#include <debug.h>
#define LQ_WAIT 1
#define LQ_OWN 2
VOID
FASTCALL
-KeAcquireQueuedSpinLockAtDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
+KeAcquireQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK_QUEUE LockHandle)
{
#ifdef CONFIG_SMP
PKSPIN_LOCK_QUEUE Prev;
/* Set the new lock */
Prev = (PKSPIN_LOCK_QUEUE)
- InterlockedExchange((PLONG)LockHandle->LockQueue.Lock,
+ InterlockedExchange((PLONG)LockHandle->Next,
(LONG)LockHandle);
if (!Prev)
{
/* There was nothing there before. We now own it */
- *(ULONG_PTR*)&LockHandle->LockQueue.Lock |= LQ_OWN;
+ *LockHandle->Lock |= LQ_OWN;
return;
}
/* Set the wait flag */
- *(ULONG_PTR*)&LockHandle->LockQueue.Lock |= LQ_WAIT;
+ *LockHandle->Lock |= LQ_WAIT;
/* Link us */
Prev->Next = (PKSPIN_LOCK_QUEUE)LockHandle;
/* Loop and wait */
- while ( *(ULONG_PTR*)&LockHandle->LockQueue.Lock & LQ_WAIT) YieldProcessor();
- return;
+ while (*LockHandle->Lock & LQ_WAIT)
+ YieldProcessor();
#endif
}
VOID
FASTCALL
-KeReleaseQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
+KeReleaseQueuedSpinLockFromDpcLevel(IN PKSPIN_LOCK_QUEUE 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;
+ *LockHandle->Lock &= ~(LQ_OWN | LQ_WAIT);
+ LockVal = *LockHandle->Lock;
/* Check if we already own it */
if (LockVal == (KSPIN_LOCK)LockHandle)
{
/* Disown it */
LockVal = (KSPIN_LOCK)
- InterlockedCompareExchangePointer(LockHandle->LockQueue.Lock,
+ InterlockedCompareExchangePointer(LockHandle->Lock,
NULL,
LockHandle);
}
if (LockVal == (KSPIN_LOCK)LockHandle) return;
/* Need to wait for it */
- Waiter = LockHandle->LockQueue.Next;
+ Waiter = LockHandle->Next;
while (!Waiter)
{
YieldProcessor();
- Waiter = LockHandle->LockQueue.Next;
+ Waiter = LockHandle->Next;
}
/* It's gone */
*(ULONG_PTR*)&Waiter->Lock ^= (LQ_OWN | LQ_WAIT);
- LockHandle->LockQueue.Next = NULL;
+ LockHandle->Next = NULL;
#endif
}
/* PUBLIC FUNCTIONS **********************************************************/
+#ifdef _X86_
+/*
+ * @implemented
+ */
+KIRQL
+NTAPI
+KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
+{
+ KIRQL OldIrql;
+
+ /* Raise IRQL */
+ KeRaiseIrql(Interrupt->SynchronizeIrql, &OldIrql);
+
+ /* Acquire spinlock on MP */
+ KeAcquireSpinLockAtDpcLevel(Interrupt->ActualLock);
+ return OldIrql;
+}
+
/*
* @implemented
*/
VOID
NTAPI
-KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)
+KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt,
+ IN KIRQL OldIrql)
+{
+ /* Release lock on MP */
+ KeReleaseSpinLockFromDpcLevel(Interrupt->ActualLock);
+
+ /* Lower IRQL */
+ KeLowerIrql(OldIrql);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+_KeInitializeSpinLock(IN PKSPIN_LOCK SpinLock)
{
/* Clear it */
*SpinLock = 0;
}
+#endif
/*
* @implemented
KxReleaseSpinLock(SpinLock);
}
+/*
+ * @implemented
+ */
+BOOLEAN
+FASTCALL
+KeTryToAcquireSpinLockAtDpcLevel(IN OUT PKSPIN_LOCK SpinLock)
+{
+#ifdef CONFIG_SMP
+ /* Check if it's already acquired */
+ if (!(*SpinLock))
+ {
+ /* Try to acquire it */
+ if (InterlockedBitTestAndSet((PLONG)SpinLock, 0))
+ {
+ /* Someone else acquired it */
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* It was already acquired */
+ return FALSE;
+ }
+
+#if DBG
+ /* On debug builds, we OR in the KTHREAD */
+ *SpinLock = (ULONG_PTR)KeGetCurrentThread() | 1;
+#endif
+#endif
+
+ /* All is well, return TRUE */
+ return TRUE;
+}
+
/*
* @implemented
*/
/* Set it up properly */
LockHandle->LockQueue.Next = NULL;
LockHandle->LockQueue.Lock = SpinLock;
- KeAcquireQueuedSpinLockAtDpcLevel((PKLOCK_QUEUE_HANDLE)
- &LockHandle->LockQueue.Next);
+ KeAcquireQueuedSpinLockAtDpcLevel(LockHandle->LockQueue.Next);
#endif
}
{
#ifdef CONFIG_SMP
/* Call the internal function */
- KeReleaseQueuedSpinLockFromDpcLevel((PKLOCK_QUEUE_HANDLE)
- &LockHandle->LockQueue.Next);
+ KeReleaseQueuedSpinLockFromDpcLevel(LockHandle->LockQueue.Next);
#endif
}
/*
- * @implemented
+ * @unimplemented
*/
KIRQL
-NTAPI
-KeAcquireInterruptSpinLock(IN PKINTERRUPT Interrupt)
+FASTCALL
+KeAcquireSpinLockForDpc(IN PKSPIN_LOCK SpinLock)
{
- KIRQL OldIrql;
-
- /* Raise IRQL */
- KeRaiseIrql(Interrupt->SynchronizeIrql, &OldIrql);
-
- /* Acquire spinlock on MP */
- KefAcquireSpinLockAtDpcLevel(Interrupt->ActualLock);
- return OldIrql;
+ UNIMPLEMENTED;
+ return 0;
}
/*
- * @implemented
+ * @unimplemented
*/
-BOOLEAN
-NTAPI
-KeSynchronizeExecution(IN PKINTERRUPT Interrupt,
- IN PKSYNCHRONIZE_ROUTINE SynchronizeRoutine,
- IN PVOID SynchronizeContext)
+VOID
+FASTCALL
+KeReleaseSpinLockForDpc(IN PKSPIN_LOCK SpinLock,
+ IN KIRQL OldIrql)
{
- KIRQL OldIrql;
- BOOLEAN Status;
-
- /* Raise IRQL and acquire lock on MP */
- OldIrql = KeAcquireInterruptSpinLock(Interrupt);
-
- /* Call the routine */
- Status = SynchronizeRoutine(SynchronizeContext);
+ UNIMPLEMENTED;
+}
- /* Release lock and lower IRQL */
- KeReleaseInterruptSpinLock(Interrupt, OldIrql);
+/*
+ * @unimplemented
+ */
+KIRQL
+FASTCALL
+KeAcquireInStackQueuedSpinLockForDpc(IN PKSPIN_LOCK SpinLock,
+ IN PKLOCK_QUEUE_HANDLE LockHandle)
+{
+ UNIMPLEMENTED;
+ return 0;
+}
- /* Return routine status */
- return Status;
+/*
+ * @unimplemented
+ */
+VOID
+FASTCALL
+KeReleaseInStackQueuedSpinLockForDpc(IN PKLOCK_QUEUE_HANDLE LockHandle)
+{
+ UNIMPLEMENTED;
}
/*
* @implemented
*/
-VOID
-NTAPI
-KeReleaseInterruptSpinLock(IN PKINTERRUPT Interrupt,
- IN KIRQL OldIrql)
+BOOLEAN
+FASTCALL
+KeTestSpinLock(IN PKSPIN_LOCK SpinLock)
{
- /* Release lock on MP */
- KefReleaseSpinLockFromDpcLevel(Interrupt->ActualLock);
+ /* Test this spinlock */
+ if (*SpinLock)
+ {
+ /* Spinlock is busy, yield execution */
+ YieldProcessor();
- /* Lower IRQL */
- KeLowerIrql(OldIrql);
+ /* Return busy flag */
+ return FALSE;
+ }
+
+ /* Spinlock appears to be free */
+ return TRUE;
}
/* EOF */