-/* $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)
*/
/*
/* INCLUDES ****************************************************************/
#include <ntoskrnl.h>
+#define NDEBUG
#include <internal/debug.h>
/* FUNCTIONS ***************************************************************/
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;
}
/*
VOID FASTCALL
KefAcquireSpinLockAtDpcLevel(PKSPIN_LOCK SpinLock)
{
- assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
KiAcquireSpinLock(SpinLock);
}
VOID FASTCALL
KefReleaseSpinLockFromDpcLevel(PKSPIN_LOCK SpinLock)
{
- assert(KeGetCurrentIrql() == DISPATCH_LEVEL);
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
KiReleaseSpinLock(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);
}
/*
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 */