2006-01-05 13:51:06 +00:00
|
|
|
/*
|
2006-11-29 08:28:20 +00:00
|
|
|
* PROJECT: ReactOS HAL
|
|
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
2015-11-04 13:30:52 +00:00
|
|
|
* FILE: hal/halx86/generic/spinlock.c
|
2006-11-29 08:28:20 +00:00
|
|
|
* PURPOSE: Spinlock and Queued Spinlock Support
|
|
|
|
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
2006-01-05 13:51:06 +00:00
|
|
|
*/
|
|
|
|
|
2006-11-29 08:28:20 +00:00
|
|
|
/* INCLUDES ******************************************************************/
|
2006-01-05 13:51:06 +00:00
|
|
|
|
2010-03-25 18:37:59 +00:00
|
|
|
/* This file is compiled twice. Once for UP and once for MP */
|
2009-09-30 20:30:57 +00:00
|
|
|
|
2006-01-05 13:51:06 +00:00
|
|
|
#include <hal.h>
|
|
|
|
#define NDEBUG
|
|
|
|
#include <debug.h>
|
|
|
|
|
2010-03-25 18:37:59 +00:00
|
|
|
#include <internal/spinlock.h>
|
|
|
|
|
2006-01-05 13:51:06 +00:00
|
|
|
#undef KeAcquireSpinLock
|
|
|
|
#undef KeReleaseSpinLock
|
|
|
|
|
2010-03-25 18:37:59 +00:00
|
|
|
/* GLOBALS *******************************************************************/
|
|
|
|
|
2012-03-28 12:15:54 +00:00
|
|
|
ULONG_PTR HalpSystemHardwareFlags;
|
2010-03-25 18:37:59 +00:00
|
|
|
KSPIN_LOCK HalpSystemHardwareLock;
|
|
|
|
|
2009-09-30 20:30:57 +00:00
|
|
|
/* FUNCTIONS *****************************************************************/
|
|
|
|
|
2010-03-25 18:37:59 +00:00
|
|
|
#ifdef _M_IX86
|
2006-01-05 13:51:06 +00:00
|
|
|
|
2022-03-08 03:44:46 +00:00
|
|
|
#ifdef _MINIHAL_
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KefAcquireSpinLockAtDpcLevel(
|
|
|
|
IN PKSPIN_LOCK SpinLock)
|
|
|
|
{
|
|
|
|
#if DBG
|
|
|
|
/* To be on par with HAL/NTOSKRNL */
|
|
|
|
*SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
#endif /* defined(_MINIHAL_) */
|
|
|
|
|
2006-01-05 13:51:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
|
|
|
KeAcquireSpinLockRaiseToSynch(PKSPIN_LOCK SpinLock)
|
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
/* Raise to sync */
|
|
|
|
KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
|
|
|
|
|
|
|
|
/* Acquire the lock and return */
|
|
|
|
KxAcquireSpinLock(SpinLock);
|
|
|
|
return OldIrql;
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
|
|
|
KfAcquireSpinLock(PKSPIN_LOCK SpinLock)
|
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
/* Raise to dispatch and acquire the lock */
|
|
|
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
|
|
|
KxAcquireSpinLock(SpinLock);
|
|
|
|
return OldIrql;
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KfReleaseSpinLock(PKSPIN_LOCK SpinLock,
|
|
|
|
KIRQL OldIrql)
|
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
/* Release the lock and lower IRQL back */
|
|
|
|
KxReleaseSpinLock(SpinLock);
|
|
|
|
KeLowerIrql(OldIrql);
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
2006-11-16 17:30:52 +00:00
|
|
|
KeAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
|
2006-01-05 13:51:06 +00:00
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
/* Raise to dispatch */
|
|
|
|
KeRaiseIrql(DISPATCH_LEVEL, &OldIrql);
|
|
|
|
|
|
|
|
/* Acquire the lock */
|
|
|
|
KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
|
|
|
|
return OldIrql;
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
KIRQL
|
|
|
|
FASTCALL
|
2006-05-10 17:47:44 +00:00
|
|
|
KeAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber)
|
2006-01-05 13:51:06 +00:00
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
KIRQL OldIrql;
|
|
|
|
|
|
|
|
/* Raise to synch */
|
|
|
|
KeRaiseIrql(SYNCH_LEVEL, &OldIrql);
|
|
|
|
|
|
|
|
/* Acquire the lock */
|
|
|
|
KxAcquireSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
|
|
|
|
return OldIrql;
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KeAcquireInStackQueuedSpinLock(IN PKSPIN_LOCK SpinLock,
|
|
|
|
IN PKLOCK_QUEUE_HANDLE LockHandle)
|
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
/* Set up the lock */
|
|
|
|
LockHandle->LockQueue.Next = NULL;
|
|
|
|
LockHandle->LockQueue.Lock = SpinLock;
|
|
|
|
|
|
|
|
/* Raise to dispatch */
|
|
|
|
KeRaiseIrql(DISPATCH_LEVEL, &LockHandle->OldIrql);
|
|
|
|
|
|
|
|
/* Acquire the lock */
|
|
|
|
KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
|
2006-09-10 16:09:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KeAcquireInStackQueuedSpinLockRaiseToSynch(IN PKSPIN_LOCK SpinLock,
|
|
|
|
IN PKLOCK_QUEUE_HANDLE LockHandle)
|
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
/* Set up the lock */
|
|
|
|
LockHandle->LockQueue.Next = NULL;
|
|
|
|
LockHandle->LockQueue.Lock = SpinLock;
|
|
|
|
|
|
|
|
/* Raise to synch */
|
|
|
|
KeRaiseIrql(SYNCH_LEVEL, &LockHandle->OldIrql);
|
|
|
|
|
|
|
|
/* Acquire the lock */
|
|
|
|
KxAcquireSpinLock(LockHandle->LockQueue.Lock); // HACK
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
2006-11-16 17:30:52 +00:00
|
|
|
KeReleaseQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
|
2006-01-05 13:51:06 +00:00
|
|
|
IN KIRQL OldIrql)
|
|
|
|
{
|
2009-09-30 20:30:57 +00:00
|
|
|
/* Release the lock */
|
|
|
|
KxReleaseSpinLock(KeGetCurrentPrcb()->LockQueue[LockNumber].Lock); // HACK
|
|
|
|
|
|
|
|
/* Lower IRQL back */
|
|
|
|
KeLowerIrql(OldIrql);
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
VOID
|
|
|
|
FASTCALL
|
|
|
|
KeReleaseInStackQueuedSpinLock(IN PKLOCK_QUEUE_HANDLE LockHandle)
|
|
|
|
{
|
|
|
|
/* Simply lower IRQL back */
|
2009-09-30 20:30:57 +00:00
|
|
|
KxReleaseSpinLock(LockHandle->LockQueue.Lock); // HACK
|
|
|
|
KeLowerIrql(LockHandle->OldIrql);
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
2021-05-26 15:03:55 +00:00
|
|
|
#ifndef _MINIHAL_
|
2006-01-05 13:51:06 +00:00
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
|
|
|
BOOLEAN
|
|
|
|
FASTCALL
|
2006-11-16 17:30:52 +00:00
|
|
|
KeTryToAcquireQueuedSpinLockRaiseToSynch(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
|
2006-01-05 13:51:06 +00:00
|
|
|
IN PKIRQL OldIrql)
|
|
|
|
{
|
2021-05-26 15:03:55 +00:00
|
|
|
PKSPIN_LOCK Lock = KeGetCurrentPrcb()->LockQueue[LockNumber].Lock;
|
2009-09-30 20:30:57 +00:00
|
|
|
|
2021-05-26 15:03:55 +00:00
|
|
|
/* KM tests demonstrate that this raises IRQL even if locking fails */
|
2009-09-30 20:30:57 +00:00
|
|
|
KeRaiseIrql(SYNCH_LEVEL, OldIrql);
|
2021-05-26 15:03:55 +00:00
|
|
|
/* HACK */
|
|
|
|
return KeTryToAcquireSpinLockAtDpcLevel(Lock);
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* @implemented
|
|
|
|
*/
|
2006-11-16 17:30:52 +00:00
|
|
|
LOGICAL
|
2006-01-05 13:51:06 +00:00
|
|
|
FASTCALL
|
2006-11-16 17:30:52 +00:00
|
|
|
KeTryToAcquireQueuedSpinLock(IN KSPIN_LOCK_QUEUE_NUMBER LockNumber,
|
|
|
|
OUT PKIRQL OldIrql)
|
2006-01-05 13:51:06 +00:00
|
|
|
{
|
2021-05-26 15:03:55 +00:00
|
|
|
PKSPIN_LOCK Lock = KeGetCurrentPrcb()->LockQueue[LockNumber].Lock;
|
2009-09-30 20:30:57 +00:00
|
|
|
|
2021-05-26 15:03:55 +00:00
|
|
|
/* KM tests demonstrate that this raises IRQL even if locking fails */
|
2009-09-30 20:30:57 +00:00
|
|
|
KeRaiseIrql(DISPATCH_LEVEL, OldIrql);
|
2021-05-26 15:03:55 +00:00
|
|
|
/* HACK */
|
|
|
|
return KeTryToAcquireSpinLockAtDpcLevel(Lock);
|
2006-01-05 13:51:06 +00:00
|
|
|
}
|
2021-05-26 15:03:55 +00:00
|
|
|
#endif /* !defined(_MINIHAL_) */
|
2022-03-08 03:44:46 +00:00
|
|
|
|
2021-05-26 15:03:55 +00:00
|
|
|
#endif /* defined(_M_IX86) */
|
2010-03-25 18:37:59 +00:00
|
|
|
|
2009-09-30 20:30:57 +00:00
|
|
|
VOID
|
|
|
|
NTAPI
|
2011-09-07 10:14:48 +00:00
|
|
|
HalpAcquireCmosSpinLock(VOID)
|
2009-09-30 20:30:57 +00:00
|
|
|
{
|
2012-03-28 12:15:54 +00:00
|
|
|
ULONG_PTR Flags;
|
2010-03-25 18:37:59 +00:00
|
|
|
|
|
|
|
/* Get flags and disable interrupts */
|
|
|
|
Flags = __readeflags();
|
|
|
|
_disable();
|
|
|
|
|
|
|
|
/* Acquire the lock */
|
|
|
|
KxAcquireSpinLock(&HalpSystemHardwareLock);
|
|
|
|
|
|
|
|
/* We have the lock, save the flags now */
|
|
|
|
HalpSystemHardwareFlags = Flags;
|
2009-09-30 20:30:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
NTAPI
|
2010-03-25 18:37:59 +00:00
|
|
|
HalpReleaseCmosSpinLock(VOID)
|
2009-09-30 20:30:57 +00:00
|
|
|
{
|
2012-03-28 12:15:54 +00:00
|
|
|
ULONG_PTR Flags;
|
2010-03-25 18:37:59 +00:00
|
|
|
|
|
|
|
/* Get the flags */
|
|
|
|
Flags = HalpSystemHardwareFlags;
|
|
|
|
|
|
|
|
/* Release the lock */
|
|
|
|
KxReleaseSpinLock(&HalpSystemHardwareLock);
|
|
|
|
|
|
|
|
/* Restore the flags */
|
|
|
|
__writeeflags(Flags);
|
2009-09-30 20:30:57 +00:00
|
|
|
}
|
2010-03-25 18:37:59 +00:00
|
|
|
|