mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 09:46:21 +00:00
- Fix kernel SMP intrinsics:
- Correct typos and add missing casts - Use IPI_APC in KiRequestApcInterrupt as we are requesting an APC IPI, not DPC - Fix KiAcquireDispatcherObject (credit to Alex) - Add missing SMP versions of KiAcquire/ReleaseDispatcherLockAtDpcLevel and KiAcquire/ReleaseTimerLock - Stub out KiRundownThread for SMP svn path=/trunk/; revision=37075
This commit is contained in:
parent
b4787f49df
commit
d47975c0db
1 changed files with 123 additions and 62 deletions
|
@ -88,6 +88,46 @@ Ke386SanitizeDr(IN PVOID DrAddress,
|
||||||
}
|
}
|
||||||
#endif /* _M_IX86 */
|
#endif /* _M_IX86 */
|
||||||
|
|
||||||
|
#ifndef _M_ARM
|
||||||
|
PRKTHREAD
|
||||||
|
FORCEINLINE
|
||||||
|
KeGetCurrentThread(VOID)
|
||||||
|
{
|
||||||
|
#ifdef _M_IX86
|
||||||
|
/* Return the current thread */
|
||||||
|
return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
|
||||||
|
#else
|
||||||
|
PKPRCB Prcb = KeGetCurrentPrcb();
|
||||||
|
return Prcb->CurrentThread;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
UCHAR
|
||||||
|
FORCEINLINE
|
||||||
|
KeGetPreviousMode(VOID)
|
||||||
|
{
|
||||||
|
/* Return the current mode */
|
||||||
|
return KeGetCurrentThread()->PreviousMode;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORCEINLINE
|
||||||
|
KeFlushProcessTb(VOID)
|
||||||
|
{
|
||||||
|
/* Flush the TLB by resetting CR3 */
|
||||||
|
#ifdef _M_PPC
|
||||||
|
__asm__("sync\n\tisync\n\t");
|
||||||
|
#elif _M_ARM
|
||||||
|
//
|
||||||
|
// We need to implement this!
|
||||||
|
//
|
||||||
|
ASSERTMSG("Need ARM flush routine\n", FALSE);
|
||||||
|
#else
|
||||||
|
__writecr3(__readcr3());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// Enters a Guarded Region
|
// Enters a Guarded Region
|
||||||
//
|
//
|
||||||
|
@ -411,7 +451,10 @@ KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||||
{
|
{
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* On debug builds, we use a much slower but useful routine */
|
/* On debug builds, we use a much slower but useful routine */
|
||||||
Kii386SpinOnSpinLock(SpinLock, 5);
|
//Kii386SpinOnSpinLock(SpinLock, 5);
|
||||||
|
|
||||||
|
/* FIXME: Do normal yield for now */
|
||||||
|
YieldProcessor();
|
||||||
#else
|
#else
|
||||||
/* Otherwise, just yield and keep looping */
|
/* Otherwise, just yield and keep looping */
|
||||||
YieldProcessor();
|
YieldProcessor();
|
||||||
|
@ -422,7 +465,7 @@ KxAcquireSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||||
{
|
{
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* On debug builds, we OR in the KTHREAD */
|
/* On debug builds, we OR in the KTHREAD */
|
||||||
*SpinLock = KeGetCurrentThread() | 1;
|
*SpinLock = (KSPIN_LOCK)KeGetCurrentThread() | 1;
|
||||||
#endif
|
#endif
|
||||||
/* All is well, break out */
|
/* All is well, break out */
|
||||||
break;
|
break;
|
||||||
|
@ -439,21 +482,21 @@ KxReleaseSpinLock(IN PKSPIN_LOCK SpinLock)
|
||||||
{
|
{
|
||||||
#ifdef DBG
|
#ifdef DBG
|
||||||
/* Make sure that the threads match */
|
/* Make sure that the threads match */
|
||||||
if ((KeGetCurrentThread() | 1) != *SpinLock)
|
if (((KSPIN_LOCK)KeGetCurrentThread() | 1) != *SpinLock)
|
||||||
{
|
{
|
||||||
/* They don't, bugcheck */
|
/* They don't, bugcheck */
|
||||||
KeBugCheckEx(SPIN_LOCK_NOT_OWNED, SpinLock, 0, 0, 0);
|
KeBugCheckEx(SPIN_LOCK_NOT_OWNED, (ULONG_PTR)SpinLock, 0, 0, 0);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Clear the lock */
|
/* Clear the lock */
|
||||||
InterlockedAnd(SpinLock, 0);
|
InterlockedAnd((PLONG)SpinLock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
KIRQL
|
VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object)
|
KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object)
|
||||||
{
|
{
|
||||||
LONG OldValue, NewValue;
|
LONG OldValue;
|
||||||
|
|
||||||
/* Make sure we're at a safe level to touch the lock */
|
/* Make sure we're at a safe level to touch the lock */
|
||||||
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
||||||
|
@ -462,20 +505,23 @@ KiAcquireDispatcherObject(IN DISPATCHER_HEADER* Object)
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
/* Loop until the other CPU releases it */
|
/* Loop until the other CPU releases it */
|
||||||
while ((UCHAR)Object->Lock & KOBJECT_LOCK_BIT)
|
while (TRUE)
|
||||||
{
|
{
|
||||||
|
/* Check if it got released */
|
||||||
|
OldValue = Object->Lock;
|
||||||
|
if ((OldValue & KOBJECT_LOCK_BIT) == 0) break;
|
||||||
|
|
||||||
/* Let the CPU know that this is a loop */
|
/* Let the CPU know that this is a loop */
|
||||||
YieldProcessor();
|
YieldProcessor();
|
||||||
};
|
}
|
||||||
|
|
||||||
/* Try acquiring the lock now */
|
/* Try acquiring the lock now */
|
||||||
NewValue = InterlockedCompareExchange(&Object->Lock,
|
} while (InterlockedCompareExchange(&Object->Lock,
|
||||||
OldValue | KOBJECT_LOCK_BIT,
|
OldValue | KOBJECT_LOCK_BIT,
|
||||||
OldValue);
|
OldValue) != OldValue);
|
||||||
} while (NewValue != OldValue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
KIRQL
|
VOID
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
KiReleaseDispatcherObject(IN DISPATCHER_HEADER* Object)
|
KiReleaseDispatcherObject(IN DISPATCHER_HEADER* Object)
|
||||||
{
|
{
|
||||||
|
@ -506,6 +552,22 @@ KiReleaseDispatcherLock(IN KIRQL OldIrql)
|
||||||
KiExitDispatcher(OldIrql);
|
KiExitDispatcher(OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORCEINLINE
|
||||||
|
KiAcquireDispatcherLockAtDpcLevel(VOID)
|
||||||
|
{
|
||||||
|
/* Acquire the dispatcher lock */
|
||||||
|
KeAcquireQueuedSpinLockAtDpcLevel(LockQueueDispatcherLock);
|
||||||
|
}
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FORCEINLINE
|
||||||
|
KiReleaseDispatcherLockFromDpcLevel(VOID)
|
||||||
|
{
|
||||||
|
/* Release the dispatcher lock */
|
||||||
|
KeReleaseQueuedSpinLockFromDpcLevel(LockQueueDispatcherLock);
|
||||||
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
// This routine inserts a thread into the deferred ready list of the given CPU
|
// This routine inserts a thread into the deferred ready list of the given CPU
|
||||||
//
|
//
|
||||||
|
@ -569,7 +631,7 @@ KiAcquirePrcbLock(IN PKPRCB Prcb)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Acquire the lock and break out if we acquired it first */
|
/* Acquire the lock and break out if we acquired it first */
|
||||||
if (!InterlockedExchange(&Prcb->PrcbLock, 1)) break;
|
if (!InterlockedExchange((PLONG)&Prcb->PrcbLock, 1)) break;
|
||||||
|
|
||||||
/* Loop until the other CPU releases it */
|
/* Loop until the other CPU releases it */
|
||||||
do
|
do
|
||||||
|
@ -595,7 +657,7 @@ KiReleasePrcbLock(IN PKPRCB Prcb)
|
||||||
ASSERT(Prcb->PrcbLock != 0);
|
ASSERT(Prcb->PrcbLock != 0);
|
||||||
|
|
||||||
/* Release it */
|
/* Release it */
|
||||||
InterlockedAnd(&Prcb->PrcbLock, 0);
|
InterlockedAnd((PLONG)&Prcb->PrcbLock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -616,7 +678,7 @@ KiAcquireThreadLock(IN PKTHREAD Thread)
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
/* Acquire the lock and break out if we acquired it first */
|
/* Acquire the lock and break out if we acquired it first */
|
||||||
if (!InterlockedExchange(&Thread->ThreadLock, 1)) break;
|
if (!InterlockedExchange((PLONG)&Thread->ThreadLock, 1)) break;
|
||||||
|
|
||||||
/* Loop until the other CPU releases it */
|
/* Loop until the other CPU releases it */
|
||||||
do
|
do
|
||||||
|
@ -639,7 +701,7 @@ VOID
|
||||||
KiReleaseThreadLock(IN PKTHREAD Thread)
|
KiReleaseThreadLock(IN PKTHREAD Thread)
|
||||||
{
|
{
|
||||||
/* Release it */
|
/* Release it */
|
||||||
InterlockedAnd(&Thread->ThreadLock, 0);
|
InterlockedAnd((PLONG)&Thread->ThreadLock, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -653,7 +715,7 @@ KiTryThreadLock(IN PKTHREAD Thread)
|
||||||
|
|
||||||
/* Otherwise, try to acquire it and check the result */
|
/* Otherwise, try to acquire it and check the result */
|
||||||
Value = 1;
|
Value = 1;
|
||||||
Value = InterlockedExchange(&Thread->ThreadLock, &Value);
|
Value = InterlockedExchange((PLONG)&Thread->ThreadLock, Value);
|
||||||
|
|
||||||
/* Return the lock state */
|
/* Return the lock state */
|
||||||
return (Value == TRUE);
|
return (Value == TRUE);
|
||||||
|
@ -667,6 +729,16 @@ KiCheckDeferredReadyList(IN PKPRCB Prcb)
|
||||||
if (Prcb->DeferredReadyListHead.Next) KiProcessDeferredReadyList(Prcb);
|
if (Prcb->DeferredReadyListHead.Next) KiProcessDeferredReadyList(Prcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
KiRundownThread(IN PKTHREAD Thread)
|
||||||
|
{
|
||||||
|
#if defined(_M_IX86) || defined(_M_AMD64)
|
||||||
|
/* FIXME: TODO */
|
||||||
|
ASSERTMSG("Not yet implemented\n", FALSE);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
VOID
|
VOID
|
||||||
KiRequestApcInterrupt(IN BOOLEAN NeedApc,
|
KiRequestApcInterrupt(IN BOOLEAN NeedApc,
|
||||||
|
@ -676,10 +748,10 @@ KiRequestApcInterrupt(IN BOOLEAN NeedApc,
|
||||||
if (NeedApc)
|
if (NeedApc)
|
||||||
{
|
{
|
||||||
/* Check if it's on another CPU */
|
/* Check if it's on another CPU */
|
||||||
if (KeGetPcr()->Number != Cpu)
|
if (KeGetPcr()->Number != Processor)
|
||||||
{
|
{
|
||||||
/* Send an IPI to request delivery */
|
/* Send an IPI to request delivery */
|
||||||
KiIpiSendRequest(AFFINITY_MASK(Cpu), IPI_DPC);
|
KiIpiSendRequest(AFFINITY_MASK(Processor), IPI_APC);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -689,6 +761,36 @@ KiRequestApcInterrupt(IN BOOLEAN NeedApc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
PKSPIN_LOCK_QUEUE
|
||||||
|
KiAcquireTimerLock(IN ULONG Hand)
|
||||||
|
{
|
||||||
|
PKSPIN_LOCK_QUEUE LockQueue;
|
||||||
|
ULONG LockIndex;
|
||||||
|
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* Get the lock index */
|
||||||
|
LockIndex = Hand >> LOCK_QUEUE_TIMER_LOCK_SHIFT;
|
||||||
|
LockIndex &= (LOCK_QUEUE_TIMER_TABLE_LOCKS - 1);
|
||||||
|
|
||||||
|
/* Now get the lock */
|
||||||
|
LockQueue = &KeGetCurrentPrcb()->LockQueue[LockQueueTimerTableLock + LockIndex];
|
||||||
|
|
||||||
|
/* Acquire it and return */
|
||||||
|
KeAcquireQueuedSpinLockAtDpcLevel(LockQueue);
|
||||||
|
return LockQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
FORCEINLINE
|
||||||
|
VOID
|
||||||
|
KiReleaseTimerLock(IN PKSPIN_LOCK_QUEUE LockQueue)
|
||||||
|
{
|
||||||
|
ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
|
||||||
|
|
||||||
|
/* Release the lock */
|
||||||
|
KeReleaseQueuedSpinLockFromDpcLevel(LockQueue);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
FORCEINLINE
|
FORCEINLINE
|
||||||
|
@ -1525,44 +1627,3 @@ KiComputeNewPriority(IN PKTHREAD Thread,
|
||||||
/* Return the new priority */
|
/* Return the new priority */
|
||||||
return Priority;
|
return Priority;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef _M_ARM
|
|
||||||
PRKTHREAD
|
|
||||||
FORCEINLINE
|
|
||||||
KeGetCurrentThread(VOID)
|
|
||||||
{
|
|
||||||
#ifdef _M_IX86
|
|
||||||
/* Return the current thread */
|
|
||||||
return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
|
|
||||||
#else
|
|
||||||
PKPRCB Prcb = KeGetCurrentPrcb();
|
|
||||||
return Prcb->CurrentThread;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
UCHAR
|
|
||||||
FORCEINLINE
|
|
||||||
KeGetPreviousMode(VOID)
|
|
||||||
{
|
|
||||||
/* Return the current mode */
|
|
||||||
return KeGetCurrentThread()->PreviousMode;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
VOID
|
|
||||||
FORCEINLINE
|
|
||||||
KeFlushProcessTb(VOID)
|
|
||||||
{
|
|
||||||
/* Flush the TLB by resetting CR3 */
|
|
||||||
#ifdef _M_PPC
|
|
||||||
__asm__("sync\n\tisync\n\t");
|
|
||||||
#elif _M_ARM
|
|
||||||
//
|
|
||||||
// We need to implement this!
|
|
||||||
//
|
|
||||||
ASSERTMSG("Need ARM flush routine\n", FALSE);
|
|
||||||
#else
|
|
||||||
__writecr3(__readcr3());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue