- Some micro-architectural changes and cleanups.

svn path=/trunk/; revision=23619
This commit is contained in:
Alex Ionescu 2006-08-20 19:08:57 +00:00
parent f448f3bae0
commit 58257141b3
5 changed files with 59 additions and 71 deletions

View file

@ -90,17 +90,20 @@ Author:
#define KTHREAD_STACK_LIMIT 0x1C
#define KTHREAD_TEB 0x74
#define KTHREAD_KERNEL_STACK 0x20
#define KTHREAD_NPX_STATE 0x4D
#define KTHREAD_STATE 0x4C
#define KTHREAD_NPX_STATE 0x4D
#define KTHREAD_ALERTED 0x5E
#define KTHREAD_APCSTATE_PROCESS 0x28 + 0x10
#define KTHREAD_PENDING_USER_APC 0x28 + 0x16
#define KTHREAD_PENDING_KERNEL_APC 0x28 + 0x15
#define KTHREAD_CONTEXT_SWITCHES 0x48
#define KTHREAD_WAIT_IRQL 0x4E
#define KTHREAD_NEXT_PROCESSOR 0x40
#define KTHREAD_SWAP_BUSY 0x5D
#define KTHREAD_SERVICE_TABLE 0x118
#define KTHREAD_PREVIOUS_MODE 0xD7
#define KTHREAD_COMBINED_APC_DISABLE 0x70
#define KTHREAD_SPECIAL_APC_DISABLE 0x72
#define KTHREAD_LARGE_STACK 0x107
#define KTHREAD_TRAP_FRAME 0x110
#define KTHREAD_CALLBACK_STACK 0x114
@ -113,7 +116,10 @@ Author:
#define KPROCESS_DIRECTORY_TABLE_BASE 0x18
#define KPROCESS_LDT_DESCRIPTOR0 0x20
#define KPROCESS_LDT_DESCRIPTOR1 0x24
#define KPROCESS_INT21_DESCRIPTOR0 0x28
#define KPROCESS_INT21_DESCRIPTOR1 0x2C
#define KPROCESS_IOPM_OFFSET 0x30
#define KPROCESS_ACTIVE_PROCESSORS 0x34
//
// KPCR Offsets
@ -121,12 +127,15 @@ Author:
#define KPCR_EXCEPTION_LIST 0x0
#define KPCR_INITIAL_STACK 0x4
#define KPCR_STACK_LIMIT 0x8
#define KPCR_PERF_GLOBAL_GROUP_MASK 0x8
#define KPCR_CONTEXT_SWITCHES 0x10
#define KPCR_SET_MEMBER_COPY 0x14
#define KPCR_TEB 0x18
#define KPCR_SELF 0x1C
#define KPCR_PRCB 0x20
#define KPCR_IRQL 0x24
#define KPCR_KD_VERSION_BLOCK 0x34
#define KPCR_IDT 0x38
#define KPCR_GDT 0x3C
#define KPCR_TSS 0x40
#define KPCR_SET_MEMBER 0x48
@ -134,6 +143,7 @@ Author:
#define KPCR_CURRENT_THREAD 0x124
#define KPCR_PROCESSOR_NUMBER 0x130
#define KPCR_PRCB_SET_MEMBER 0x134
#define KPCR_PRCB_CPU_TYPE 0x138
#define KPCR_NPX_THREAD 0x640
#define KPCR_DR6 0x428
#define KPCR_DR7 0x42C

View file

@ -122,7 +122,7 @@ extern KSPIN_LOCK DispatcherDatabaseLock;
/* Thread Scheduler Functions */
/* Readies a Thread for Execution. */
VOID
BOOLEAN
STDCALL
KiDispatchThreadNoLock(ULONG NewThreadStatus);
@ -148,7 +148,10 @@ KeSuspendThread(PKTHREAD Thread);
NTSTATUS
FASTCALL
KiSwapContext(PKTHREAD NewThread);
KiSwapContext(
IN PKTHREAD CurrentThread,
IN PKTHREAD NewThread
);
VOID
STDCALL

View file

@ -115,9 +115,6 @@ BadThread:
.globl @KiSwapContextInternal@0
@KiSwapContextInternal@0:
/* Get the PCR. It's faster to use ebx+offset then fs:offset */
mov ebx, [fs:KPCR_SELF]
/* Set the Thread to running */
mov byte ptr [esi+KTHREAD_STATE], Running
@ -140,24 +137,6 @@ BadThread:
mov [ebx+KPCR_INITIAL_STACK], eax
mov [ebx+KPCR_STACK_LIMIT], ecx
#ifdef CONFIG_SMP
/* Save FPU state if the thread has used it. */
mov ecx, [edi+KTHREAD_INITIAL_STACK]
sub ecx, NPX_FRAME_LENGTH
mov dword ptr [ebx+KPCR_NPX_THREAD], 0
test byte ptr [edi+KTHREAD_NPX_STATE], NPX_STATE_DIRTY
jz 3f
cmp dword ptr _KeI386FxsrPresent, 0
je 1f
fxsave [ecx]
jmp 2f
1:
fnsave [ecx]
2:
mov byte ptr [edi+KTHREAD_NPX_STATE], NPX_STATE_VALID
3:
#endif /* CONFIG_SMP */
/* Save the stack pointer in this processors TSS */
mov ebp, [ebx+KPCR_TSS]
@ -170,9 +149,6 @@ BadThread:
NoAdjust:
/* Save it */
push [ebp+KTSS_ESP0]
/* Set new ESP0 */
mov [ebp+KTSS_ESP0], eax
@ -250,28 +226,11 @@ SameProcess:
/* Increase context switches */
inc dword ptr [esi+KTHREAD_CONTEXT_SWITCHES]
/* Set TS in cr0 to catch FPU code and load the FPU state when needed */
#ifndef CONFIG_SMP
cmp [ebx+KPCR_NPX_THREAD], esi
je 4f
#endif /* !CONFIG_SMP */
mov eax, cr0
or eax, X86_CR0_TS
mov cr0, eax
4:
/* Restore ESP0 */
pop [ebp+KTSS_ESP0]
/* Restore exception list */
pop [ebx+KPCR_EXCEPTION_LIST]
/* Return */
#ifdef CONFIG_SMP
mov ecx, offset _DispatcherDatabaseLock
call @KefReleaseSpinLockFromDpcLevel@4
#endif
ret
ret
/*++
* KiSwapContext
@ -294,37 +253,43 @@ SameProcess:
* another thread switches to IT.
*
*--*/
.globl @KiSwapContext@4
@KiSwapContext@4:
.globl @KiSwapContext@8
@KiSwapContext@8:
/* Note, we CANNOT touch ebp */
/* Save 4 registers */
sub esp, 4 * 4
/* Save all the non-volatile ones */
mov [esp+12], ebx
mov [esp+8], esi
mov [esp+4], edi
mov [esp+0], ebp
/* Get the current KPCR */
mov ebx, fs:[KPCR_SELF]
/* Get the Current Thread */
mov edi, fs:[KPCR_CURRENT_THREAD]
mov edi, ecx
/* Get the New Thread */
mov esi, ecx
mov esi, edx
/* Get the wait IRQL */
movzx ecx, byte ptr [edi+KTHREAD_WAIT_IRQL]
/* Save it as Current thread */
mov fs:[KPCR_CURRENT_THREAD], esi
/* Do the swap with the registers correctly setup */
call @KiSwapContextInternal@0
/* Return the registers */
mov ebp, [esp+0]
mov edi, [esp+4]
mov esi, [esp+8]
mov ebx, [esp+12]
/* Clean stack */
add esp, 4 * 4
ret

View file

@ -14,7 +14,6 @@
typedef struct _KSHARED_CTXSWITCH_FRAME
{
ULONG Esp0;
PVOID ExceptionList;
PVOID RetEip;
} KSHARED_CTXSWITCH_FRAME, *PKSHARED_CTXSWITCH_FRAME;
@ -94,7 +93,6 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
/* Setup the Fx Area */
FxSaveArea = &InitFrame->FxSaveArea;
Thread->NpxState = NPX_STATE_INVALID;
/* Check if we support FXsr */
if (KeI386FxsrPresent)
@ -108,7 +106,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
FxSaveFormat->TagWord = 0;
FxSaveFormat->ErrorOffset = 0;
FxSaveFormat->ErrorSelector = 0;
FxSaveFormat->DataOffset =0;
FxSaveFormat->DataOffset = 0;
FxSaveFormat->DataSelector = 0;
FxSaveFormat->MXCsr = 0x1F80;
}
@ -137,7 +135,7 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
CONTEXT_FLOATING_POINT;
/* Set the Thread's NPX State */
Thread->NpxState = NPX_STATE_INVALID;
Thread->NpxState = NPX_STATE_NOT_LOADED;
Thread->DispatcherHeader.NpxIrql = PASSIVE_LEVEL;
}
else
@ -232,9 +230,6 @@ Ke386InitThreadWithContext(PKTHREAD Thread,
/* And set up the Context Switch Frame */
CtxSwitchFrame->RetEip = KiThreadStartup;
CtxSwitchFrame->Esp0 = (ULONG_PTR)Thread->InitialStack -
sizeof(FX_SAVE_AREA) -
0x10;
CtxSwitchFrame->ExceptionList = (PVOID)0xFFFFFFFF;
/* Save back the new value of the kernel stack. */

View file

@ -128,7 +128,7 @@ KiScanThreadList(KPRIORITY Priority,
return(NULL);
}
VOID
BOOLEAN
STDCALL
KiDispatchThreadNoLock(ULONG NewThreadStatus)
{
@ -136,6 +136,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
PKTHREAD Candidate;
ULONG Affinity;
PKTHREAD CurrentThread = KeGetCurrentThread();
BOOLEAN ApcState;
DPRINT("KiDispatchThreadNoLock() %d/%d/%d/%d\n", KeGetCurrentProcessorNumber(),
CurrentThread, NewThreadStatus, CurrentThread->State);
@ -158,7 +159,7 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
Candidate->State = Running;
KeReleaseDispatcherDatabaseLockFromDpcLevel();
return;
return FALSE;
}
if (Candidate != NULL) {
@ -186,15 +187,16 @@ KiDispatchThreadNoLock(ULONG NewThreadStatus)
MmUpdatePageDir((PEPROCESS)PsGetCurrentProcess(),((PETHREAD)CurrentThread)->ThreadsProcess, sizeof(EPROCESS));
/* Special note for Filip: This will release the Dispatcher DB Lock ;-) -- Alex */
DPRINT("You are : %x, swapping to: %x\n", OldThread, CurrentThread);
KiSwapContext(CurrentThread);
DPRINT("You are : %x, swapping to: %x.\n", OldThread, CurrentThread);
ApcState = KiSwapContext(OldThread, CurrentThread);
DPRINT("You are : %x, swapped from: %x\n", OldThread, CurrentThread);
return;
return ApcState;
}
}
DPRINT1("CRITICAL: No threads are ready (CPU%d)\n", KeGetCurrentProcessorNumber());
KEBUGCHECK(0);
return FALSE;
}
NTSTATUS
@ -202,13 +204,26 @@ NTAPI
KiSwapThread(VOID)
{
PKTHREAD CurrentThread = KeGetCurrentThread();
BOOLEAN ApcState;
/* Find a new thread to run */
DPRINT("Dispatching Thread as blocked\n");
KiDispatchThreadNoLock(Waiting);
ApcState = KiDispatchThreadNoLock(Waiting);
/* Lower IRQL back */
DPRINT("Lowering IRQL \n");
#if 0
/* Check if we need to deliver APCs */
if (ApcState)
{
/* Lower to APC_LEVEL */
KeLowerIrql(APC_LEVEL);
/* Deliver APCs */
KiDeliverApc(KernelMode, NULL, NULL);
ASSERT(CurrentThread->WaitIrql == 0);
}
#endif
/* Lower IRQL back to what it was */
KfLowerIrql(CurrentThread->WaitIrql);
/* Return the wait status */