* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
*/
+//
+// Thread Dispatcher Header DebugActive Mask
+//
+#define DR_MASK(x) 1 << x
+#define DR_ACTIVE_MASK 0x10
+#define DR_REG_MASK 0x4F
+
+//
+// Sanitizes a selector
+//
+FORCEINLINE
+ULONG
+Ke386SanitizeSeg(IN ULONG Cs,
+ IN KPROCESSOR_MODE Mode)
+{
+ //
+ // Check if we're in kernel-mode, and force CPL 0 if so.
+ // Otherwise, force CPL 3.
+ //
+ return ((Mode == KernelMode) ?
+ (Cs & (0xFFFF & ~RPL_MASK)) :
+ (RPL_MASK | (Cs & 0xFFFF)));
+}
+
+//
+// Sanitizes EFLAGS
+//
+FORCEINLINE
+ULONG
+Ke386SanitizeFlags(IN ULONG Eflags,
+ IN KPROCESSOR_MODE Mode)
+{
+ //
+ // Check if we're in kernel-mode, and sanitize EFLAGS if so.
+ // Otherwise, also force interrupt mask on.
+ //
+ return ((Mode == KernelMode) ?
+ (Eflags & (EFLAGS_USER_SANITIZE | EFLAGS_INTERRUPT_MASK)) :
+ (EFLAGS_INTERRUPT_MASK | (Eflags & EFLAGS_USER_SANITIZE)));
+}
+
+//
+// Gets a DR register from a CONTEXT structure
+//
+FORCEINLINE
+PVOID
+KiDrFromContext(IN ULONG Dr,
+ IN PCONTEXT Context)
+{
+ return *(PVOID*)((ULONG_PTR)Context + KiDebugRegisterContextOffsets[Dr]);
+}
+
+//
+// Gets a DR register from a KTRAP_FRAME structure
+//
+FORCEINLINE
+PVOID*
+KiDrFromTrapFrame(IN ULONG Dr,
+ IN PKTRAP_FRAME TrapFrame)
+{
+ return (PVOID*)((ULONG_PTR)TrapFrame + KiDebugRegisterTrapOffsets[Dr]);
+}
+
+//
+//
+//
+FORCEINLINE
+PVOID
+Ke386SanitizeDr(IN PVOID DrAddress,
+ IN KPROCESSOR_MODE Mode)
+{
+ //
+ // Check if we're in kernel-mode, and return the address directly if so.
+ // Otherwise, make sure it's not inside the kernel-mode address space.
+ // If it is, then clear the address.
+ //
+ return ((Mode == KernelMode) ? DrAddress :
+ (DrAddress <= MM_HIGHEST_USER_ADDRESS) ? DrAddress : 0);
+}
+
//
// Enters a Guarded Region
//
{ \
/* Check if we need to request an APC Delivery */ \
if (!(IsListEmpty(&_Thread->ApcState.ApcListHead[KernelMode])) && \
- !(_Thread->KernelApcDisable)) \
+ !(_Thread->SpecialApcDisable)) \
{ \
/* Check for the right environment */ \
KiCheckForKernelApcDelivery(); \
IN KPRIORITY Increment)
{
PLIST_ENTRY WaitEntry, WaitList;
- PKWAIT_BLOCK CurrentWaitBlock;
+ PKWAIT_BLOCK WaitBlock;
PKTHREAD WaitThread;
ULONG WaitKey;
/* Loop the Wait Entries */
WaitList = &Object->WaitListHead;
+ ASSERT(IsListEmpty(&Object->WaitListHead) == FALSE);
WaitEntry = WaitList->Flink;
do
{
/* Get the current wait block */
- CurrentWaitBlock = CONTAINING_RECORD(WaitEntry,
- KWAIT_BLOCK,
- WaitListEntry);
+ WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
/* Get the waiting thread */
- WaitThread = CurrentWaitBlock->Thread;
+ WaitThread = WaitBlock->Thread;
/* Check the current Wait Mode */
- if (CurrentWaitBlock->WaitType == WaitAny)
+ if (WaitBlock->WaitType == WaitAny)
{
/* Use the actual wait key */
- WaitKey = CurrentWaitBlock->WaitKey;
+ WaitKey = WaitBlock->WaitKey;
}
else
{
IN KPRIORITY Increment)
{
PLIST_ENTRY WaitEntry, WaitList;
- PKWAIT_BLOCK CurrentWaitBlock;
+ PKWAIT_BLOCK WaitBlock;
PKTHREAD WaitThread;
/* Loop the Wait Entries */
WaitList = &Event->Header.WaitListHead;
+ ASSERT(IsListEmpty(&Event->Header.WaitListHead) == FALSE);
WaitEntry = WaitList->Flink;
do
{
/* Get the current wait block */
- CurrentWaitBlock = CONTAINING_RECORD(WaitEntry,
- KWAIT_BLOCK,
- WaitListEntry);
+ WaitBlock = CONTAINING_RECORD(WaitEntry, KWAIT_BLOCK, WaitListEntry);
/* Get the waiting thread */
- WaitThread = CurrentWaitBlock->Thread;
+ WaitThread = WaitBlock->Thread;
/* Check the current Wait Mode */
- if (CurrentWaitBlock->WaitType == WaitAny)
+ if (WaitBlock->WaitType == WaitAny)
{
/* Un-signal it */
Event->Header.SignalState = 0;
/* Un-signal the event and unwait the thread */
- KiUnwaitThread(WaitThread, CurrentWaitBlock->WaitKey, Increment);
+ KiUnwaitThread(WaitThread, WaitBlock->WaitKey, Increment);
break;
}
- else
- {
- /* Unwait the thread with STATUS_KERNEL_APC */
- KiUnwaitThread(WaitThread, STATUS_KERNEL_APC, Increment);
- }
+
+ /* Unwait the thread with STATUS_KERNEL_APC */
+ KiUnwaitThread(WaitThread, STATUS_KERNEL_APC, Increment);
/* Next entry */
WaitEntry = WaitList->Flink;
{
LONG PriorityMask, PrioritySet, HighPriority;
PLIST_ENTRY ListEntry;
- PKTHREAD Thread;
+ PKTHREAD Thread = NULL;
/* Save the current mask and get the priority set for the CPU */
PriorityMask = Priority;
PrioritySet = Prcb->ReadySummary >> (UCHAR)Priority;
- if (!PrioritySet) return NULL;
+ if (!PrioritySet) goto Quickie;
/* Get the highest priority possible */
BitScanReverse((PULONG)&HighPriority, PrioritySet);
ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE);
/* Get the first thread on the list */
- ListEntry = &Prcb->DispatcherReadyListHead[HighPriority];
+ ListEntry = Prcb->DispatcherReadyListHead[HighPriority].Flink;
Thread = CONTAINING_RECORD(ListEntry, KTHREAD, WaitListEntry);
/* Make sure this thread is here for a reason */
ASSERT(Thread->NextProcessor == Prcb->Number);
/* Remove it from the list */
- RemoveEntryList(&Thread->WaitListEntry);
- if (IsListEmpty(&Thread->WaitListEntry))
+ if (RemoveEntryList(&Thread->WaitListEntry))
{
/* The list is empty now, reset the ready summary */
Prcb->ReadySummary ^= PRIORITY_MASK(HighPriority);
}
/* Sanity check and return the thread */
+Quickie:
ASSERT((Thread == NULL) ||
(Thread->BasePriority == 0) ||
(Thread->Priority != 0));
//
SCHAR
FORCEINLINE
-KiComputeNewPriority(IN PKTHREAD Thread)
+KiComputeNewPriority(IN PKTHREAD Thread,
+ IN SCHAR Adjustment)
{
SCHAR Priority;
if (Priority < LOW_REALTIME_PRIORITY)
{
/* Decrease priority by the priority decrement */
- Priority -= (Thread->PriorityDecrement + 1);
+ Priority -= (Thread->PriorityDecrement + Adjustment);
/* Don't go out of bounds */
if (Priority < Thread->BasePriority) Priority = Thread->BasePriority;