Sync to trunk head (r42241)
[reactos.git] / reactos / ntoskrnl / ke / spinlock.c
index 0a63414..a1ed59b 100644 (file)
@@ -10,7 +10,7 @@
 
 #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
@@ -165,6 +199,40 @@ KiReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
     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
  */
@@ -177,8 +245,7 @@ KeAcquireInStackQueuedSpinLockAtDpcLevel(IN PKSPIN_LOCK SpinLock,
     /* Set it up properly */
     LockHandle->LockQueue.Next = NULL;
     LockHandle->LockQueue.Lock = SpinLock;
-    KeAcquireQueuedSpinLockAtDpcLevel((PKLOCK_QUEUE_HANDLE)
-                                      &LockHandle->LockQueue.Next);
+    KeAcquireQueuedSpinLockAtDpcLevel(LockHandle->LockQueue.Next);
 #endif
 }
 
@@ -191,66 +258,73 @@ KeReleaseInStackQueuedSpinLockFromDpcLevel(IN PKLOCK_QUEUE_HANDLE LockHandle)
 {
 #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 */