mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[10 bug fixes]:
- Simplify KiSelectReadyThread. - Use ASSERT_IRQL_EQUAL instead of ASSERT_IRQL, because ASSERT_IRQL is braindead and doesn't actually do what the name proposes. This caused us to miss many critical bugs. - Don't lower IRQL to PASSIVE_LEVEL after KeInsertQueueApc. This caused a call to KiExitDispatcher at PASSIVE, which is completely fucked. Also do the same fix in KeFreezeAllThreads and KeThawAllThreads. - Implement code in KiDispatchInterrupt to switch to a new thread, but don't enable for now. - Fix the KiMask32Array. One of the values was totally off and screwed up priority/affinity masks. - Exit the dispatcher in KiAdjustQuantumThread. This wasn't done, thus causing a weird system state. - Fix a bug in KiSetPriorityThread which wasn't properly checking the ProcessReadyQueue member and thus not applying priority changes. - Fixup lock release and dispatcher exit in wait functions in the NoWait case. It was inverted and messed up, leading to system inconsistency. svn path=/trunk/; revision=25501
This commit is contained in:
parent
22033f60ea
commit
a04cac242c
16 changed files with 123 additions and 97 deletions
|
@ -101,15 +101,16 @@ Author:
|
||||||
#define KTHREAD_STACK_LIMIT 0x1C
|
#define KTHREAD_STACK_LIMIT 0x1C
|
||||||
#define KTHREAD_TEB 0x74
|
#define KTHREAD_TEB 0x74
|
||||||
#define KTHREAD_KERNEL_STACK 0x20
|
#define KTHREAD_KERNEL_STACK 0x20
|
||||||
#define KTHREAD_STATE 0x4C
|
|
||||||
#define KTHREAD_NPX_STATE 0x4D
|
|
||||||
#define KTHREAD_ALERTED 0x5E
|
#define KTHREAD_ALERTED 0x5E
|
||||||
#define KTHREAD_APCSTATE_PROCESS 0x28 + 0x10
|
#define KTHREAD_APCSTATE_PROCESS 0x28 + 0x10
|
||||||
#define KTHREAD_PENDING_USER_APC 0x28 + 0x16
|
#define KTHREAD_PENDING_USER_APC 0x28 + 0x16
|
||||||
#define KTHREAD_PENDING_KERNEL_APC 0x28 + 0x15
|
#define KTHREAD_PENDING_KERNEL_APC 0x28 + 0x15
|
||||||
#define KTHREAD_CONTEXT_SWITCHES 0x48
|
#define KTHREAD_CONTEXT_SWITCHES 0x48
|
||||||
|
#define KTHREAD_STATE 0x4C
|
||||||
|
#define KTHREAD_NPX_STATE 0x4D
|
||||||
#define KTHREAD_WAIT_IRQL 0x4E
|
#define KTHREAD_WAIT_IRQL 0x4E
|
||||||
#define KTHREAD_NEXT_PROCESSOR 0x40
|
#define KTHREAD_NEXT_PROCESSOR 0x40
|
||||||
|
#define KTHREAD_WAIT_REASON 0x5A
|
||||||
#define KTHREAD_SWAP_BUSY 0x5D
|
#define KTHREAD_SWAP_BUSY 0x5D
|
||||||
#define KTHREAD_SERVICE_TABLE 0x118
|
#define KTHREAD_SERVICE_TABLE 0x118
|
||||||
#define KTHREAD_PREVIOUS_MODE 0xD7
|
#define KTHREAD_PREVIOUS_MODE 0xD7
|
||||||
|
|
|
@ -8,13 +8,16 @@
|
||||||
// Do NOT ask when it will be fixed.
|
// Do NOT ask when it will be fixed.
|
||||||
// Failure to respect this will *ACHIEVE NOTHING*.
|
// Failure to respect this will *ACHIEVE NOTHING*.
|
||||||
//
|
//
|
||||||
// Ex:
|
|
||||||
// - Use pushlocks for handle implementation.
|
|
||||||
//
|
|
||||||
// Ke1:
|
// Ke1:
|
||||||
// - Implement KiInitMachineDependent.
|
// - Implement KiInitMachineDependent.
|
||||||
// - Implement Privileged Instruction Handler in Umode GPF.
|
// - Implement Privileged Instruction Handler in Umode GPF.
|
||||||
//
|
//
|
||||||
|
// Ex:
|
||||||
|
// - Use pushlocks for handle implementation.
|
||||||
|
//
|
||||||
|
// Ke2:
|
||||||
|
// - Dispatcher Rewrite (DPCs-Timers-Waits).
|
||||||
|
//
|
||||||
// Hal:
|
// Hal:
|
||||||
// - Use APC and DPC Interrupt Dispatchers.
|
// - Use APC and DPC Interrupt Dispatchers.
|
||||||
// - CMOS Initialization and CMOS Spinlock.
|
// - CMOS Initialization and CMOS Spinlock.
|
||||||
|
@ -22,10 +25,6 @@
|
||||||
// Fstub:
|
// Fstub:
|
||||||
// - Implement IoAssignDriveLetters using mount manager support.
|
// - Implement IoAssignDriveLetters using mount manager support.
|
||||||
//
|
//
|
||||||
// Ke2:
|
|
||||||
// - New optimized table-based tick-hashed timer implementation.
|
|
||||||
// - New Thread Scheduler based on 2003.
|
|
||||||
//
|
|
||||||
// Kd:
|
// Kd:
|
||||||
// - Implement KD Kernel Debugging and WinDBG support.
|
// - Implement KD Kernel Debugging and WinDBG support.
|
||||||
//
|
//
|
||||||
|
|
|
@ -1257,21 +1257,20 @@ PKTHREAD
|
||||||
KiSelectReadyThread(IN KPRIORITY Priority,
|
KiSelectReadyThread(IN KPRIORITY Priority,
|
||||||
IN PKPRCB Prcb)
|
IN PKPRCB Prcb)
|
||||||
{
|
{
|
||||||
LONG PriorityMask, PrioritySet, HighPriority;
|
ULONG PrioritySet, HighPriority;
|
||||||
PLIST_ENTRY ListEntry;
|
PLIST_ENTRY ListEntry;
|
||||||
PKTHREAD Thread = NULL;
|
PKTHREAD Thread = NULL;
|
||||||
|
|
||||||
/* Save the current mask and get the priority set for the CPU */
|
/* Save the current mask and get the priority set for the CPU */
|
||||||
PriorityMask = Priority;
|
PrioritySet = Prcb->ReadySummary >> Priority;
|
||||||
PrioritySet = Prcb->ReadySummary >> (UCHAR)Priority;
|
|
||||||
if (!PrioritySet) goto Quickie;
|
if (!PrioritySet) goto Quickie;
|
||||||
|
|
||||||
/* Get the highest priority possible */
|
/* Get the highest priority possible */
|
||||||
BitScanReverse((PULONG)&HighPriority, PrioritySet);
|
BitScanReverse((PULONG)&HighPriority, PrioritySet);
|
||||||
ASSERT((PrioritySet & PRIORITY_MASK(HighPriority)) != 0);
|
ASSERT((PrioritySet & PRIORITY_MASK(HighPriority)) != 0);
|
||||||
HighPriority += PriorityMask;
|
HighPriority += Priority;
|
||||||
|
|
||||||
/* Make sure the list isn't at highest priority */
|
/* Make sure the list isn't empty at the highest priority */
|
||||||
ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE);
|
ASSERT(IsListEmpty(&Prcb->DispatcherReadyListHead[HighPriority]) == FALSE);
|
||||||
|
|
||||||
/* Get the first thread on the list */
|
/* Get the first thread on the list */
|
||||||
|
|
|
@ -28,7 +28,7 @@ IoAllocateController(IN PCONTROLLER_OBJECT ControllerObject,
|
||||||
IN PVOID Context)
|
IN PVOID Context)
|
||||||
{
|
{
|
||||||
IO_ALLOCATION_ACTION Result;
|
IO_ALLOCATION_ACTION Result;
|
||||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
ASSERT_IRQL_EQUAL(DISPATCH_LEVEL);
|
||||||
|
|
||||||
/* Initialize the Wait Context Block */
|
/* Initialize the Wait Context Block */
|
||||||
DeviceObject->Queue.Wcb.DeviceContext = Context;
|
DeviceObject->Queue.Wcb.DeviceContext = Context;
|
||||||
|
|
|
@ -632,7 +632,7 @@ IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject,
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;
|
PEXTENDED_DEVOBJ_EXTENSION DeviceObjectExtension;
|
||||||
|
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
||||||
|
|
||||||
DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n",
|
DPRINT("IoRegisterDeviceInterface(): PDO %p, RefString: %wZ\n",
|
||||||
PhysicalDeviceObject, ReferenceString);
|
PhysicalDeviceObject, ReferenceString);
|
||||||
|
|
|
@ -725,7 +725,7 @@ KeInsertQueueApc(IN PKAPC Apc,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Release the APC lock and return success */
|
/* Release the APC lock and return success */
|
||||||
KiReleaseApcLock(&ApcLock);
|
KiReleaseApcLockFromDpcLevel(&ApcLock);
|
||||||
KiExitDispatcher(ApcLock.OldIrql);
|
KiExitDispatcher(ApcLock.OldIrql);
|
||||||
return State;
|
return State;
|
||||||
}
|
}
|
||||||
|
@ -951,3 +951,4 @@ KeAreAllApcsDisabled(VOID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ KiRetireDpcList(IN PKPRCB Prcb)
|
||||||
DeferredContext,
|
DeferredContext,
|
||||||
SystemArgument1,
|
SystemArgument1,
|
||||||
SystemArgument2);
|
SystemArgument2);
|
||||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||||
|
|
||||||
/* Disable interrupts and keep looping */
|
/* Disable interrupts and keep looping */
|
||||||
_disable();
|
_disable();
|
||||||
|
|
|
@ -764,7 +764,7 @@ NTAPI
|
||||||
KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
|
KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
|
||||||
{
|
{
|
||||||
PFNSAVE_FORMAT FpState;
|
PFNSAVE_FORMAT FpState;
|
||||||
ASSERT_IRQL(DISPATCH_LEVEL);
|
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
|
||||||
DPRINT1("%s is not really implemented\n", __FUNCTION__);
|
DPRINT1("%s is not really implemented\n", __FUNCTION__);
|
||||||
|
|
||||||
/* check if we are doing software emulation */
|
/* check if we are doing software emulation */
|
||||||
|
|
|
@ -11,11 +11,11 @@
|
||||||
/* INCLUDES ******************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <roscfg.h>
|
#include <roscfg.h>
|
||||||
#include <internal/i386/ke.h>
|
|
||||||
#include <ndk/asm.h>
|
#include <ndk/asm.h>
|
||||||
.intel_syntax noprefix
|
.intel_syntax noprefix
|
||||||
|
|
||||||
#define Running 2
|
#define Running 2
|
||||||
|
#define WrDispatchInt 0x1F
|
||||||
|
|
||||||
/* FUNCTIONS ****************************************************************/
|
/* FUNCTIONS ****************************************************************/
|
||||||
|
|
||||||
|
@ -289,6 +289,7 @@ BadThread:
|
||||||
* Absolutely all registers except ESP can be trampled here for maximum code flexibility.
|
* Absolutely all registers except ESP can be trampled here for maximum code flexibility.
|
||||||
*
|
*
|
||||||
*--*/
|
*--*/
|
||||||
|
.globl @KiSwapContextInternal@0
|
||||||
.func @KiSwapContextInternal@0, @KiSwapContextInternal@0
|
.func @KiSwapContextInternal@0, @KiSwapContextInternal@0
|
||||||
@KiSwapContextInternal@0:
|
@KiSwapContextInternal@0:
|
||||||
|
|
||||||
|
@ -413,7 +414,7 @@ SameProcess:
|
||||||
sub eax, NPX_FRAME_LENGTH
|
sub eax, NPX_FRAME_LENGTH
|
||||||
|
|
||||||
/* Check if this isn't V86 Mode, so we can bias the Esp0 */
|
/* Check if this isn't V86 Mode, so we can bias the Esp0 */
|
||||||
test dword ptr [eax - KTRAP_FRAME_SIZE + KTRAP_FRAME_EFLAGS], X86_EFLAGS_VM
|
test dword ptr [eax - KTRAP_FRAME_SIZE + KTRAP_FRAME_EFLAGS], EFLAGS_V86_MASK
|
||||||
jnz NoAdjust
|
jnz NoAdjust
|
||||||
|
|
||||||
/* Bias esp */
|
/* Bias esp */
|
||||||
|
@ -562,7 +563,6 @@ WrongCpu:
|
||||||
.globl @KiSwapContext@8
|
.globl @KiSwapContext@8
|
||||||
.func @KiSwapContext@8, @KiSwapContext@8
|
.func @KiSwapContext@8, @KiSwapContext@8
|
||||||
@KiSwapContext@8:
|
@KiSwapContext@8:
|
||||||
/* Note, we CANNOT touch ebp */
|
|
||||||
|
|
||||||
/* Save 4 registers */
|
/* Save 4 registers */
|
||||||
sub esp, 4 * 4
|
sub esp, 4 * 4
|
||||||
|
@ -664,7 +664,7 @@ CheckSchedule:
|
||||||
/* Set the current thread to ready */
|
/* Set the current thread to ready */
|
||||||
mov edi, [ebx+KPCR_CURRENT_THREAD]
|
mov edi, [ebx+KPCR_CURRENT_THREAD]
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
mov [edi+KTHREAD_STATE], Ready
|
mov byte ptr [edi+KTHREAD_SWAP_BUSY], 1
|
||||||
|
|
||||||
/* Acquire the PRCB Lock */
|
/* Acquire the PRCB Lock */
|
||||||
lock bts [ebx+KPCR_PRCB_PRCB_LOCK], 0
|
lock bts [ebx+KPCR_PRCB_PRCB_LOCK], 0
|
||||||
|
|
|
@ -6,18 +6,18 @@
|
||||||
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
* PROGRAMMER: Alex Ionescu (alex@relsoft.net)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* INCLUDES ****************************************************************/
|
/* INCLUDES ******************************************************************/
|
||||||
|
|
||||||
#include <ntoskrnl.h>
|
#include <ntoskrnl.h>
|
||||||
#define NDEBUG
|
#define NDEBUG
|
||||||
#include <internal/debug.h>
|
#include <debug.h>
|
||||||
|
|
||||||
typedef struct _KSHARED_CTXSWITCH_FRAME
|
typedef struct _KSWITCHFRAME
|
||||||
{
|
{
|
||||||
PVOID ExceptionList;
|
PVOID ExceptionList;
|
||||||
KIRQL WaitIrql;
|
BOOLEAN ApcBypassDisable;
|
||||||
PVOID RetEip;
|
PVOID RetAddr;
|
||||||
} KSHARED_CTXSWITCH_FRAME, *PKSHARED_CTXSWITCH_FRAME;
|
} KSWITCHFRAME, *PKSWITCHFRAME;
|
||||||
|
|
||||||
typedef struct _KSTART_FRAME
|
typedef struct _KSTART_FRAME
|
||||||
{
|
{
|
||||||
|
@ -27,65 +27,47 @@ typedef struct _KSTART_FRAME
|
||||||
BOOLEAN UserThread;
|
BOOLEAN UserThread;
|
||||||
} KSTART_FRAME, *PKSTART_FRAME;
|
} KSTART_FRAME, *PKSTART_FRAME;
|
||||||
|
|
||||||
/*
|
typedef struct _KUINIT_FRAME
|
||||||
* This is the Initial Thread Stack Frame on i386.
|
{
|
||||||
*
|
KSWITCHFRAME CtxSwitchFrame;
|
||||||
* It is composed of :
|
KSTART_FRAME StartFrame;
|
||||||
*
|
KTRAP_FRAME TrapFrame;
|
||||||
* - A shared Thread Switching frame so that we can use
|
FX_SAVE_AREA FxSaveArea;
|
||||||
* the context-switching code when initializing the thread.
|
|
||||||
*
|
|
||||||
* - The Stack Frame for KiThreadStartup, which are the parameters
|
|
||||||
* that it will receive (System/Start Routines & Context)
|
|
||||||
*
|
|
||||||
* - A Trap Frame with the Initial Context *IF AND ONLY IF THE THREAD IS USER*
|
|
||||||
*
|
|
||||||
* - The FPU Save Area, theoretically part of the Trap Frame's "ExtendedRegisters"
|
|
||||||
*
|
|
||||||
* This Initial Thread Stack Frame starts at Thread->InitialStack and it spans
|
|
||||||
* a total size of 0x2B8 bytes.
|
|
||||||
*/
|
|
||||||
typedef struct _KUINIT_FRAME {
|
|
||||||
KSHARED_CTXSWITCH_FRAME CtxSwitchFrame; /* -0x2B8 */
|
|
||||||
KSTART_FRAME StartFrame; /* -0x2AC */
|
|
||||||
KTRAP_FRAME TrapFrame; /* -0x29C */
|
|
||||||
FX_SAVE_AREA FxSaveArea; /* -0x210 */
|
|
||||||
} KUINIT_FRAME, *PKUINIT_FRAME;
|
} KUINIT_FRAME, *PKUINIT_FRAME;
|
||||||
|
|
||||||
typedef struct _KKINIT_FRAME {
|
typedef struct _KKINIT_FRAME
|
||||||
KSHARED_CTXSWITCH_FRAME CtxSwitchFrame; /* -0x22C */
|
{
|
||||||
KSTART_FRAME StartFrame; /* -0x220 */
|
KSWITCHFRAME CtxSwitchFrame;
|
||||||
FX_SAVE_AREA FxSaveArea; /* -0x210 */
|
KSTART_FRAME StartFrame;
|
||||||
|
FX_SAVE_AREA FxSaveArea;
|
||||||
} KKINIT_FRAME, *PKKINIT_FRAME;
|
} KKINIT_FRAME, *PKKINIT_FRAME;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
Ke386InitThreadWithContext(PKTHREAD Thread,
|
Ke386InitThreadWithContext(IN PKTHREAD Thread,
|
||||||
PKSYSTEM_ROUTINE SystemRoutine,
|
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||||
PKSTART_ROUTINE StartRoutine,
|
IN PKSTART_ROUTINE StartRoutine,
|
||||||
PVOID StartContext,
|
IN PVOID StartContext,
|
||||||
PCONTEXT ContextPointer)
|
IN PCONTEXT ContextPointer)
|
||||||
{
|
{
|
||||||
PFX_SAVE_AREA FxSaveArea;
|
PFX_SAVE_AREA FxSaveArea;
|
||||||
PFXSAVE_FORMAT FxSaveFormat;
|
PFXSAVE_FORMAT FxSaveFormat;
|
||||||
PKSTART_FRAME StartFrame;
|
PKSTART_FRAME StartFrame;
|
||||||
PKSHARED_CTXSWITCH_FRAME CtxSwitchFrame;
|
PKSWITCHFRAME CtxSwitchFrame;
|
||||||
PKTRAP_FRAME TrapFrame;
|
PKTRAP_FRAME TrapFrame;
|
||||||
CONTEXT LocalContext;
|
CONTEXT LocalContext;
|
||||||
PCONTEXT Context = NULL;
|
PCONTEXT Context = NULL;
|
||||||
ULONG ContextFlags;
|
ULONG ContextFlags;
|
||||||
|
|
||||||
/* Check if this is a With-Context Thread */
|
/* Check if this is a With-Context Thread */
|
||||||
DPRINT("Ke386InitThreadContext\n");
|
|
||||||
if (ContextPointer)
|
if (ContextPointer)
|
||||||
{
|
{
|
||||||
/* Set up the Initial Frame */
|
/* Set up the Initial Frame */
|
||||||
PKUINIT_FRAME InitFrame;
|
PKUINIT_FRAME InitFrame;
|
||||||
InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
|
InitFrame = (PKUINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
|
||||||
sizeof(KUINIT_FRAME));
|
sizeof(KUINIT_FRAME));
|
||||||
DPRINT("Setting up a user-mode thread. InitFrame at: %p\n", InitFrame);
|
|
||||||
|
|
||||||
/* Copy over the context we got */
|
/* Copy over the context we got */
|
||||||
RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
|
RtlCopyMemory(&LocalContext, ContextPointer, sizeof(CONTEXT));
|
||||||
|
@ -190,7 +172,6 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
|
||||||
PKKINIT_FRAME InitFrame;
|
PKKINIT_FRAME InitFrame;
|
||||||
InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
|
InitFrame = (PKKINIT_FRAME)((ULONG_PTR)Thread->InitialStack -
|
||||||
sizeof(KKINIT_FRAME));
|
sizeof(KKINIT_FRAME));
|
||||||
DPRINT("Setting up a kernel thread. InitFrame at: %p\n", InitFrame);
|
|
||||||
|
|
||||||
/* Setup the Fx Area */
|
/* Setup the Fx Area */
|
||||||
FxSaveArea = &InitFrame->FxSaveArea;
|
FxSaveArea = &InitFrame->FxSaveArea;
|
||||||
|
@ -230,15 +211,14 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
|
||||||
StartFrame->SystemRoutine = SystemRoutine;
|
StartFrame->SystemRoutine = SystemRoutine;
|
||||||
|
|
||||||
/* And set up the Context Switch Frame */
|
/* And set up the Context Switch Frame */
|
||||||
CtxSwitchFrame->RetEip = KiThreadStartup;
|
CtxSwitchFrame->RetAddr = KiThreadStartup;
|
||||||
CtxSwitchFrame->WaitIrql = APC_LEVEL;
|
CtxSwitchFrame->ApcBypassDisable = TRUE;
|
||||||
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
|
CtxSwitchFrame->ExceptionList = EXCEPTION_CHAIN_END;;
|
||||||
|
|
||||||
/* Save back the new value of the kernel stack. */
|
/* Save back the new value of the kernel stack. */
|
||||||
DPRINT("Final Kernel Stack: %x \n", CtxSwitchFrame);
|
|
||||||
Thread->KernelStack = (PVOID)CtxSwitchFrame;
|
Thread->KernelStack = (PVOID)CtxSwitchFrame;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* EOF */
|
/* EOF */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,9 @@
|
||||||
#include <internal/i386/asmmacro.S>
|
#include <internal/i386/asmmacro.S>
|
||||||
.intel_syntax noprefix
|
.intel_syntax noprefix
|
||||||
|
|
||||||
|
#define Running 2
|
||||||
|
#define WrDispatchInt 0x1F
|
||||||
|
|
||||||
/* GLOBALS *******************************************************************/
|
/* GLOBALS *******************************************************************/
|
||||||
|
|
||||||
.data
|
.data
|
||||||
|
@ -2082,7 +2085,7 @@ _KiDispatchInterrupt@0:
|
||||||
|
|
||||||
/* Restore stack and exception list */
|
/* Restore stack and exception list */
|
||||||
pop esp
|
pop esp
|
||||||
pop dword ptr [ebx]
|
pop dword ptr [ebx+KPCR_EXCEPTION_LIST]
|
||||||
pop ebp
|
pop ebp
|
||||||
|
|
||||||
CheckQuantum:
|
CheckQuantum:
|
||||||
|
@ -2096,10 +2099,44 @@ CheckQuantum:
|
||||||
|
|
||||||
/* Check if we have a thread to swap to */
|
/* Check if we have a thread to swap to */
|
||||||
cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
|
cmp byte ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
|
||||||
jz Return
|
jmp Return
|
||||||
|
|
||||||
/* FIXME: Schedule new thread */
|
/* Make space on the stack to save registers */
|
||||||
UNHANDLED_PATH
|
sub esp, 3 * 4
|
||||||
|
mov [esp+8], esi
|
||||||
|
mov [esi+4], edi
|
||||||
|
mov [esi+0], ebp
|
||||||
|
|
||||||
|
/* Get the current thread */
|
||||||
|
mov edi, [ebx+KPCR_CURRENT_THREAD]
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
#error SMP Interrupt not handled!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the next thread and clear it */
|
||||||
|
mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
|
||||||
|
and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
|
||||||
|
|
||||||
|
/* Set us as the current running thread */
|
||||||
|
mov [ebx+KPCR_CURRENT_THREAD], esi
|
||||||
|
mov byte ptr [esi+KTHREAD_STATE], Running
|
||||||
|
mov byte ptr [edi+KTHREAD_WAIT_REASON], WrDispatchInt
|
||||||
|
|
||||||
|
/* Put thread in ECX and get the PRCB in EDX */
|
||||||
|
mov ecx, edi
|
||||||
|
lea edx, [ebx+KPCR_PRCB_DATA]
|
||||||
|
call @KiQueueReadyThread@8
|
||||||
|
|
||||||
|
/* Set APC_LEVEL and do the swap */
|
||||||
|
mov cl, APC_LEVEL
|
||||||
|
call @KiSwapContextInternal@0
|
||||||
|
|
||||||
|
/* Restore registers */
|
||||||
|
mov ebp, [esp+0]
|
||||||
|
mov edi, [esp+4]
|
||||||
|
mov esi, [esp+8]
|
||||||
|
add esp, 3*4
|
||||||
|
|
||||||
Return:
|
Return:
|
||||||
/* All done */
|
/* All done */
|
||||||
|
|
|
@ -18,7 +18,7 @@ extern LIST_ENTRY PspReaperListHead;
|
||||||
ULONG KiMask32Array[MAXIMUM_PRIORITY] =
|
ULONG KiMask32Array[MAXIMUM_PRIORITY] =
|
||||||
{
|
{
|
||||||
0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
|
0x1, 0x2, 0x4, 0x8, 0x10, 0x20,
|
||||||
0x40, 0x80, 0x100, 0x200, 0x4000, 0x800,
|
0x40, 0x80, 0x100, 0x200, 0x400, 0x800,
|
||||||
0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000,
|
0x1000, 0x2000, 0x4000, 0x8000, 0x10000, 0x20000,
|
||||||
0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
|
0x40000, 0x80000, 0x100000, 0x200000, 0x400000, 0x800000,
|
||||||
0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
|
0x1000000, 0x2000000, 0x4000000, 0x8000000, 0x10000000, 0x20000000,
|
||||||
|
@ -311,7 +311,7 @@ KeFreezeAllThreads(VOID)
|
||||||
} while (NextEntry != ListHead);
|
} while (NextEntry != ListHead);
|
||||||
|
|
||||||
/* Release the process lock and exit the dispatcher */
|
/* Release the process lock and exit the dispatcher */
|
||||||
KiReleaseProcessLock(&LockHandle);
|
KiReleaseProcessLockFromDpcLevel(&LockHandle);
|
||||||
KiExitDispatcher(LockHandle.OldIrql);
|
KiExitDispatcher(LockHandle.OldIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -634,7 +634,7 @@ KeThawAllThreads(VOID)
|
||||||
} while (NextEntry != ListHead);
|
} while (NextEntry != ListHead);
|
||||||
|
|
||||||
/* Release the process lock and exit the dispatcher */
|
/* Release the process lock and exit the dispatcher */
|
||||||
KiReleaseProcessLock(&LockHandle);
|
KiReleaseProcessLockFromDpcLevel(&LockHandle);
|
||||||
KiExitDispatcher(LockHandle.OldIrql);
|
KiExitDispatcher(LockHandle.OldIrql);
|
||||||
|
|
||||||
/* Leave the critical region */
|
/* Leave the critical region */
|
||||||
|
|
|
@ -21,6 +21,15 @@ ULONG KiIdleSMTSummary;
|
||||||
|
|
||||||
/* FUNCTIONS *****************************************************************/
|
/* FUNCTIONS *****************************************************************/
|
||||||
|
|
||||||
|
VOID
|
||||||
|
FASTCALL
|
||||||
|
KiQueueReadyThread(IN PKTHREAD Thread,
|
||||||
|
IN PKPRCB Prcb)
|
||||||
|
{
|
||||||
|
/* Call the macro. We keep the API for compatibility with ASM code */
|
||||||
|
KxQueueReadyThread(Thread, Prcb);
|
||||||
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
VOID
|
VOID
|
||||||
KiInsertIntoThreadList(KPRIORITY Priority,
|
KiInsertIntoThreadList(KPRIORITY Priority,
|
||||||
|
@ -247,7 +256,7 @@ KiReadyThread(IN PKTHREAD Thread)
|
||||||
if (Process->State != ProcessInMemory)
|
if (Process->State != ProcessInMemory)
|
||||||
{
|
{
|
||||||
/* We don't page out processes in ROS */
|
/* We don't page out processes in ROS */
|
||||||
ASSERT(FALSE);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
else if (!Thread->KernelStackResident)
|
else if (!Thread->KernelStackResident)
|
||||||
{
|
{
|
||||||
|
@ -260,7 +269,7 @@ KiReadyThread(IN PKTHREAD Thread)
|
||||||
Thread->State = Transition;
|
Thread->State = Transition;
|
||||||
|
|
||||||
/* The stack is always resident in ROS */
|
/* The stack is always resident in ROS */
|
||||||
ASSERT(FALSE);
|
KEBUGCHECK(0);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -326,10 +335,11 @@ KiAdjustQuantumThread(IN PKTHREAD Thread)
|
||||||
/* Release locks */
|
/* Release locks */
|
||||||
KiReleasePrcbLock(Prcb);
|
KiReleasePrcbLock(Prcb);
|
||||||
KiReleaseThreadLock(Thread);
|
KiReleaseThreadLock(Thread);
|
||||||
|
KiExitDispatcher(Thread->WaitIrql);
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID
|
VOID
|
||||||
STDCALL
|
NTAPI
|
||||||
KiSetPriorityThread(IN PKTHREAD Thread,
|
KiSetPriorityThread(IN PKTHREAD Thread,
|
||||||
IN KPRIORITY Priority,
|
IN KPRIORITY Priority,
|
||||||
OUT PBOOLEAN Released)
|
OUT PBOOLEAN Released)
|
||||||
|
@ -351,7 +361,7 @@ KiSetPriorityThread(IN PKTHREAD Thread,
|
||||||
if (Thread->State == Ready)
|
if (Thread->State == Ready)
|
||||||
{
|
{
|
||||||
/* Make sure we're not on the ready queue */
|
/* Make sure we're not on the ready queue */
|
||||||
if (Thread->ProcessReadyQueue)
|
if (!Thread->ProcessReadyQueue)
|
||||||
{
|
{
|
||||||
/* Get the PRCB for the thread and lock it */
|
/* Get the PRCB for the thread and lock it */
|
||||||
Processor = Thread->NextProcessor;
|
Processor = Thread->NextProcessor;
|
||||||
|
@ -362,12 +372,12 @@ KiSetPriorityThread(IN PKTHREAD Thread,
|
||||||
if ((Thread->State == Ready) &&
|
if ((Thread->State == Ready) &&
|
||||||
(Thread->NextProcessor == Prcb->Number))
|
(Thread->NextProcessor == Prcb->Number))
|
||||||
{
|
{
|
||||||
|
#ifdef NEW_SCHEDULER
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
ASSERT((Prcb->ReadySummary &
|
ASSERT((Prcb->ReadySummary &
|
||||||
PRIORITY_MASK(Thread->Priority)));
|
PRIORITY_MASK(Thread->Priority)));
|
||||||
|
|
||||||
/* Remove it from the current queue */
|
/* Remove it from the current queue */
|
||||||
#ifdef NEW_SCHEDULER
|
|
||||||
if (RemoveEntryList(&Thread->WaitListEntry))
|
if (RemoveEntryList(&Thread->WaitListEntry))
|
||||||
{
|
{
|
||||||
/* Update the ready summary */
|
/* Update the ready summary */
|
||||||
|
@ -395,7 +405,6 @@ KiSetPriorityThread(IN PKTHREAD Thread,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Release the lock and loop again */
|
/* Release the lock and loop again */
|
||||||
KEBUGCHECK(0);
|
|
||||||
KiReleasePrcbLock(Prcb);
|
KiReleasePrcbLock(Prcb);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -409,7 +418,6 @@ KiSetPriorityThread(IN PKTHREAD Thread,
|
||||||
else if (Thread->State == Standby)
|
else if (Thread->State == Standby)
|
||||||
{
|
{
|
||||||
/* Get the PRCB for the thread and lock it */
|
/* Get the PRCB for the thread and lock it */
|
||||||
KEBUGCHECK(0);
|
|
||||||
Processor = Thread->NextProcessor;
|
Processor = Thread->NextProcessor;
|
||||||
Prcb = KiProcessorBlock[Processor];
|
Prcb = KiProcessorBlock[Processor];
|
||||||
KiAcquirePrcbLock(Prcb);
|
KiAcquirePrcbLock(Prcb);
|
||||||
|
|
|
@ -161,7 +161,7 @@ KiExitDispatcher(IN KIRQL OldIrql)
|
||||||
BOOLEAN PendingApc;
|
BOOLEAN PendingApc;
|
||||||
|
|
||||||
/* Make sure we're at synchronization level */
|
/* Make sure we're at synchronization level */
|
||||||
ASSERT_IRQL(SYNCH_LEVEL);
|
ASSERT_IRQL_EQUAL(SYNCH_LEVEL);
|
||||||
|
|
||||||
/* Check if we have deferred threads */
|
/* Check if we have deferred threads */
|
||||||
KiCheckDeferredReadyList(Prcb);
|
KiCheckDeferredReadyList(Prcb);
|
||||||
|
@ -484,11 +484,11 @@ StartWait:
|
||||||
return WaitStatus;
|
return WaitStatus;
|
||||||
|
|
||||||
DontWait:
|
DontWait:
|
||||||
/* Adjust the Quantum */
|
/* Release dispatcher lock but maintain high IRQL */
|
||||||
KiAdjustQuantumThread(Thread);
|
KiReleaseDispatcherLockFromDpcLevel();
|
||||||
|
|
||||||
/* Release & Return */
|
/* Adjust the Quantum and return the wait status */
|
||||||
KiReleaseDispatcherLock(Thread->WaitIrql);
|
KiAdjustQuantumThread(Thread);
|
||||||
return WaitStatus;
|
return WaitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -761,11 +761,11 @@ StartWait:
|
||||||
return WaitStatus;
|
return WaitStatus;
|
||||||
|
|
||||||
DontWait:
|
DontWait:
|
||||||
/* Adjust the Quantum */
|
/* Release dispatcher lock but maintain high IRQL */
|
||||||
KiAdjustQuantumThread(Thread);
|
KiReleaseDispatcherLockFromDpcLevel();
|
||||||
|
|
||||||
/* Release & Return */
|
/* Adjust the Quantum and return the wait status */
|
||||||
KiReleaseDispatcherLock(Thread->WaitIrql);
|
KiAdjustQuantumThread(Thread);
|
||||||
return WaitStatus;
|
return WaitStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -911,7 +911,7 @@ PspTerminateThreadByPointer(IN PETHREAD Thread,
|
||||||
if ((bSelf) || (PsGetCurrentThread() == Thread))
|
if ((bSelf) || (PsGetCurrentThread() == Thread))
|
||||||
{
|
{
|
||||||
/* This should only happen at passive */
|
/* This should only happen at passive */
|
||||||
ASSERT_IRQL(PASSIVE_LEVEL);
|
ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
|
||||||
|
|
||||||
/* Mark it as terminated */
|
/* Mark it as terminated */
|
||||||
PspSetCrossThreadFlag(Thread, CT_TERMINATED_BIT);
|
PspSetCrossThreadFlag(Thread, CT_TERMINATED_BIT);
|
||||||
|
|
|
@ -49,7 +49,7 @@ VdmSwapContext(IN PKTRAP_FRAME TrapFrame,
|
||||||
ULONG EFlags, OldEFlags;
|
ULONG EFlags, OldEFlags;
|
||||||
|
|
||||||
/* Make sure that we're at APC_LEVEL and that this is a valid frame */
|
/* Make sure that we're at APC_LEVEL and that this is a valid frame */
|
||||||
ASSERT_IRQL(APC_LEVEL);
|
ASSERT(KeGetCurrentIrql() == APC_LEVEL);
|
||||||
ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
|
ASSERT(TrapFrame->DbgArgMark == 0xBADB0D00);
|
||||||
|
|
||||||
/* Check if this is a V86 frame */
|
/* Check if this is a V86 frame */
|
||||||
|
@ -321,3 +321,4 @@ VdmDispatchBop(IN PKTRAP_FRAME TrapFrame)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue