KD System Rewrite:
[reactos.git] / reactos / ntoskrnl / ke / spinlock.c
index e52f24e..258a15d 100644 (file)
@@ -1,12 +1,11 @@
-/* $Id: spinlock.c,v 1.22 2004/08/15 16:39:05 chorns Exp $
+/* $Id$
  *
  * COPYRIGHT:       See COPYING in the top level directory
  * PROJECT:         ReactOS kernel
  * FILE:            ntoskrnl/ke/spinlock.c
  * PURPOSE:         Implements spinlocks
- * PROGRAMMER:      David Welch (welch@cwcom.net)
- * UPDATE HISTORY:
- *                  3/6/98: Created
+ * 
+ * PROGRAMMERS:     David Welch (welch@cwcom.net)
  */
 
 /*
@@ -17,6 +16,7 @@
 /* INCLUDES ****************************************************************/
 
 #include <ntoskrnl.h>
+#define NDEBUG
 #include <internal/debug.h>
 
 /* FUNCTIONS ***************************************************************/
@@ -42,28 +42,29 @@ KeSynchronizeExecution (PKINTERRUPT         Interrupt,
    KIRQL oldlvl;
    BOOLEAN ret;
    
-   KeRaiseIrql(Interrupt->SynchLevel, &oldlvl);
-   KiAcquireSpinLock(Interrupt->IrqLock);
+   oldlvl = KeAcquireInterruptSpinLock(Interrupt);
    
    ret = SynchronizeRoutine(SynchronizeContext);
    
-   KiReleaseSpinLock(Interrupt->IrqLock);
-   KeLowerIrql(oldlvl);
+   KeReleaseInterruptSpinLock(Interrupt, oldlvl);
    
    return(ret);
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
-STDCALL
 KIRQL
+STDCALL
 KeAcquireInterruptSpinLock(
     IN PKINTERRUPT Interrupt
     )
 {
-       UNIMPLEMENTED;
-       return 0;
+   KIRQL oldIrql;
+        
+   KeRaiseIrql(Interrupt->SynchLevel, &oldIrql);
+   KiAcquireSpinLock(Interrupt->ActualLock);
+   return oldIrql;
 }
 
 /*
@@ -88,7 +89,7 @@ KeInitializeSpinLock (PKSPIN_LOCK     SpinLock)
 VOID FASTCALL
 KefAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock)
 {
-  assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
   KiAcquireSpinLock(SpinLock);
 }
 
@@ -132,7 +133,7 @@ KeAcquireInStackQueuedSpinLockAtDpcLevel(
 VOID FASTCALL
 KefReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock)
 {
-  assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+  ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
   KiReleaseSpinLock(SpinLock);  
 }
 
@@ -177,34 +178,40 @@ KiAcquireSpinLock(PKSPIN_LOCK SpinLock)
    * FIXME: This depends on gcc assembling this test to a single load from
    * the spinlock's value.
    */
-  if (*SpinLock >= 2)
-  {
-    DbgPrint("Lock %x has bad value %x\n", SpinLock, *SpinLock);
-    KEBUGCHECK(0);
-  }
+  ASSERT(*SpinLock < 2);
    
-  while ((i = InterlockedExchange((LONG *)SpinLock, 1)) == 1)
+  while ((i = InterlockedExchangeUL(SpinLock, 1)) == 1)
   {
-#ifndef MP
+#ifdef CONFIG_SMP
+    /* Avoid reading the value again too fast */
+#if 1
+    __asm__ __volatile__ ("1:\n\t"
+                         "cmpl $0,(%0)\n\t"
+                         "jne  1b\n\t"
+                         :
+                          : "r" (SpinLock));
+#else                    
+    while (0 != *(volatile KSPIN_LOCK*)SpinLock);
+#endif
+#else
     DbgPrint("Spinning on spinlock %x current value %x\n", SpinLock, i);
-    KEBUGCHECK(0);
-#else /* not MP */
-       /* Avoid reading the value again too fast */
-#endif /* MP */
+    KEBUGCHECKEX(SPIN_LOCK_ALREADY_OWNED, (ULONG)SpinLock, 0, 0, 0);
+#endif /* CONFIG_SMP */
   }
 }
 
 /*
- * @unimplemented
+ * @implemented
  */
-STDCALL
 VOID
+STDCALL
 KeReleaseInterruptSpinLock(
        IN PKINTERRUPT Interrupt,
        IN KIRQL OldIrql
        )
 {
-       UNIMPLEMENTED;
+   KiReleaseSpinLock(Interrupt->ActualLock);
+   KeLowerIrql(OldIrql);
 }
 
 /*
@@ -216,9 +223,9 @@ KiReleaseSpinLock(PKSPIN_LOCK SpinLock)
   if (*SpinLock != 1)
   {
     DbgPrint("Releasing unacquired spinlock %x\n", SpinLock);
-    KEBUGCHECK(0);
+    KEBUGCHECKEX(SPIN_LOCK_NOT_OWNED, (ULONG)SpinLock, 0, 0, 0);
   }
-  (void)InterlockedExchange((LONG *)SpinLock, 0);
+  (void)InterlockedExchangeUL(SpinLock, 0);
 }
 
 /* EOF */