- Implement and export HalClearSoftawareInterrupt (currently implemented to match the hacked ROS version, no new version written yet).

- Implement CPU Idle Loop in assembly for UP and SMP systems. Differences:
  * Runs with interrupts off most of the time, except when it does interrupt cycling at each iteration.
  * Calls KiRetireDpcList directly, instead of going through KiDispatchInterrupt.
  * Support for new scheduler and immediate thread switch.
  * Support for Idle Scheduler.
  * Support for HAL/ACPI/CPU Driver-defined "Idle Function". currently disabled and STI+HLT harcoded instead.
- Removed ps/idle.c and dumped the hack code directly in psmgr.c wher eit's used.

svn path=/trunk/; revision=24062
This commit is contained in:
Alex Ionescu 2006-09-11 06:22:26 +00:00
parent a0fac81cfd
commit 81997fc0bc
8 changed files with 223 additions and 119 deletions

View file

@ -446,6 +446,13 @@ HalRequestSoftwareInterrupt(
UNIMPLEMENTED;
}
VOID FASTCALL
HalClearSoftwareInterrupt(
IN KIRQL Request)
{
UNIMPLEMENTED;
}
VOID
NTAPI

View file

@ -15,7 +15,7 @@ HalAllocateCrashDumpRegisters@8
HalAssignSlotResources@32
HalBeginSystemInterrupt@12
HalCalibratePerformanceCounter@4
;@HalClearSoftwareInterrupt@4
@HalClearSoftwareInterrupt@4
HalDisableSystemInterrupt@8
HalDisplayString@4
HalEnableSystemInterrupt@12

View file

@ -422,4 +422,23 @@ HalRequestSoftwareInterrupt(
}
}
VOID FASTCALL
HalClearSoftwareInterrupt(
IN KIRQL Request)
{
switch (Request)
{
case APC_LEVEL:
((PKIPCR)KeGetPcr())->HalReserved[HAL_APC_REQUEST] = FALSE;
break;
case DISPATCH_LEVEL:
((PKIPCR)KeGetPcr())->HalReserved[HAL_DPC_REQUEST] = FALSE;
break;
default:
KEBUGCHECK(0);
}
}
/* EOF */

View file

@ -147,6 +147,7 @@ Author:
#define KPCR_TSS 0x40
#define KPCR_SET_MEMBER 0x48
#define KPCR_NUMBER 0x51
#define KPCR_PRCB_DATA 0x120
#define KPCR_CURRENT_THREAD 0x124
#define KPCR_PRCB_NEXT_THREAD 0x128
#define KPCR_PRCB_IDLE_THREAD 0x12C

View file

@ -472,6 +472,7 @@ BugCheckDpc:
*
*--*/
.globl @KiSwapContext@8
.func @KiSwapContext@8, @KiSwapContext@8
@KiSwapContext@8:
/* Note, we CANNOT touch ebp */
@ -511,6 +512,130 @@ BugCheckDpc:
/* Clean stack */
add esp, 4 * 4
ret
.endfunc
.globl @KiIdleLoop@0
.func @KiIdleLoop@0, @KiIdleLoop@0
@KiIdleLoop@0:
/* Jump into mainline code */
jmp MainLoop
CpuIdle:
/* Call the CPU's idle function */
#if 0
lea ecx, [ebx+KPCR_PRCB_POWER_STATE_IDLE_FUNCTION]
call [ecx]
#else
sti
hlt
#endif
MainLoop:
/* Cycle interrupts for 1 cycle */
sti
nop
nop
cli
/* Check if we have to deliver DPCs, timers, or deferred threads */
mov eax, [ebx+KPCR_PRCB_DPC_QUEUE_DEPTH]
or eax, [ebx+KPCR_PRCB_TIMER_REQUEST]
#ifdef CONFIG_SMP
or eax, [ebx+KPCR_PRCB_DEFERRED_READY_LIST_HEAD]
#endif
jz CheckSchedule
/* Handle the above */
lea ecx, [ebx+KPCR_PRCB_DATA]
call @KiRetireDpcList@4
CheckSchedule:
/* Check if a next thread is queued */
cmp dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
#ifdef CONFIG_SMP
jz NoNextThread
#else
jz CpuIdle
#endif
#ifdef CONFIG_SMP
/* There is, raise IRQL to synch level */
mov ecx, SYNCH_LEVEL
call @KfRaiseIrql@4
#endif
sti
/* Set the current thread to ready */
mov edi, [ebx+KPCR_CURRENT_THREAD]
#ifdef CONFIG_SMP
mov [edi+KTHREAD_STATE], Ready
/* Acquire the PRCB Lock */
lock bts [ebx+KPCR_PRCB_PRCB_LOCK], 0
jnb CheckNext
lea ecx, [ebx+KPCR_PRCB_PRCB_LOCK]
call @KefAcquireSpinLockAtDpcLevel@4
#endif
CheckNext:
/* Check if the next thread is the current */
mov esi, [ebx+KPCR_PRCB_NEXT_THREAD]
#ifdef CONFIG_SMP
cmp esi, edi
jz SameThread
#endif
/* Clear the next thread and set this one instead */
and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
mov [ebx+KPCR_CURRENT_THREAD], esi
/* Set the thread as running */
mov byte ptr [esi+KTHREAD_STATE], Running
#ifdef CONFIG_SMP
/* Disable the idle scheduler and release the PRCB lock */
and byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE], 0
and [ebx+KPCR_PRCB_PRCB_LOCK], 0
#endif
SwapContext:
/* Swap context at APC_LEVEL */
mov ecx, APC_LEVEL
call @KiSwapContextInternal@0
#ifdef CONFIG_SMP
/* Lower to DPC level */
mov ecx, DISPATCH_LEVEL
call @KfLowerIrql@4
#endif
jmp MainLoop
#ifdef CONFIG_SMP
SameThread:
/* Clear the next thread, and put the thready as ready after lock release */
and dword ptr [ebx+KPCR_PRCB_NEXT_THREAD], 0
and dword ptr [ebx+KPCR_PRCB_PRCB_LOCK], 0
and byte ptr [edi+KTHREAD_STATE], Ready
jmp MainLoop
NoNextThread:
/* Check if the idle scheduler is enabled */
cmp byte ptr [ebx+KPCR_PRCB_IDLE_SCHEDULE], 0
jz CpuIdle
/* It is, so call the scheduler */
lea ecx, [ebx+KPCR_PRCBDATA]
call @KiIdleSchedule@4
test eax, eax
/* Get new thread pointers and either swap or idle loop again */
mov esi, eax
mov edi, [ebx+KPCR_PRCB_IDLE_THREAD]
jnz SwapContext
jmp MainLoop
#endif
.endfunc
.globl _Ki386AdjustEsp0@4
.func Ki386AdjustEsp0@4

View file

@ -292,7 +292,6 @@
</directory>
<directory name="ps">
<file>debug.c</file>
<file>idle.c</file>
<file>job.c</file>
<file>kill.c</file>
<file>notify.c</file>

View file

@ -1,115 +0,0 @@
/*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ps/idle.c
* PURPOSE: Using idle time
*
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
* David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, PsInitIdleThread)
#endif
/* FUNCTIONS *****************************************************************/
/** System idle thread procedure
*
*/
VOID STDCALL
PsIdleThreadMain(PVOID Context)
{
KIRQL oldlvl;
PKPRCB Prcb = KeGetCurrentPrcb();
for(;;)
{
if (Prcb->DpcData[0].DpcQueueDepth > 0)
{
KeRaiseIrql(DISPATCH_LEVEL,&oldlvl);
KiDispatchInterrupt();
KeLowerIrql(oldlvl);
}
NtYieldExecution();
Ke386HaltProcessor();
}
}
/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
NTSTATUS
NTAPI
PsInitializeIdleOrFirstThread(PEPROCESS Process,
PETHREAD* ThreadPtr,
PKSTART_ROUTINE StartRoutine,
KPROCESSOR_MODE AccessMode,
BOOLEAN First)
{
PETHREAD Thread;
PVOID KernelStack;
Thread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD));
RtlZeroMemory(Thread, sizeof(ETHREAD));
Thread->ThreadsProcess = Process;
if (First)
{
KernelStack = P0BootStack;
}
else
{
KernelStack = (PVOID)((ULONG_PTR)MmCreateKernelStack(FALSE) +
KERNEL_STACK_SIZE);
}
KeInitializeThread(&Process->Pcb,
&Thread->Tcb,
PspSystemThreadStartup,
StartRoutine,
NULL,
NULL,
NULL,
KernelStack);
InitializeListHead(&Thread->IrpList);
*ThreadPtr = Thread;
return STATUS_SUCCESS;
}
/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
VOID
INIT_FUNCTION
NTAPI
PsInitIdleThread(VOID)
{
PETHREAD IdleThread;
KIRQL oldIrql;
PsInitializeIdleOrFirstThread(PsIdleProcess,
&IdleThread,
PsIdleThreadMain,
KernelMode,
FALSE);
oldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&IdleThread->Tcb);
KiReleaseDispatcherLock(oldIrql);
KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb;
KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY);
KeSetAffinityThread(&IdleThread->Tcb, 1 << 0);
}

View file

@ -64,6 +64,74 @@ NTSTATUS STDCALL INIT_FUNCTION PspLookupKernelUserEntryPoints(VOID);
/* FUNCTIONS ***************************************************************/
VOID
FASTCALL
KiIdleLoop(VOID);
/* FUNCTIONS *****************************************************************/
/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
VOID
INIT_FUNCTION
NTAPI
PsInitHackThread(VOID)
{
PETHREAD IdleThread;
KIRQL oldIrql;
IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD));
RtlZeroMemory(IdleThread, sizeof(ETHREAD));
IdleThread->ThreadsProcess = PsIdleProcess;
KeInitializeThread(&PsIdleProcess->Pcb,
&IdleThread->Tcb,
PspSystemThreadStartup,
(PVOID)KiIdleLoop,
NULL,
NULL,
NULL,
P0BootStack);
InitializeListHead(&IdleThread->IrpList);
oldIrql = KiAcquireDispatcherLock ();
KiReadyThread(&IdleThread->Tcb);
KiReleaseDispatcherLock(oldIrql);
KeGetCurrentPrcb()->IdleThread = &IdleThread->Tcb;
KeSetPriorityThread(&IdleThread->Tcb, LOW_PRIORITY);
KeSetAffinityThread(&IdleThread->Tcb, 1 << 0);
}
/*
* HACK-O-RAMA
* Antique vestigial code left alive for the sole purpose of First/Idle Thread
* creation until I can merge my fix for properly creating them.
*/
VOID
INIT_FUNCTION
NTAPI
PsInitHackThread2(IN PETHREAD *Hack)
{
PETHREAD IdleThread;
IdleThread = ExAllocatePool(NonPagedPool, sizeof(ETHREAD));
RtlZeroMemory(IdleThread, sizeof(ETHREAD));
IdleThread->ThreadsProcess = PsInitialSystemProcess;
KeInitializeThread(&PsInitialSystemProcess->Pcb,
&IdleThread->Tcb,
PspSystemThreadStartup,
NULL,
NULL,
NULL,
NULL,
P0BootStack);
InitializeListHead(&IdleThread->IrpList);
*Hack = IdleThread;
}
VOID
INIT_FUNCTION
NTAPI
@ -72,7 +140,7 @@ PiInitProcessManager(VOID)
PsInitJobManagment();
PsInitProcessManagment();
PsInitThreadManagment();
PsInitIdleThread();
PsInitHackThread();
}
VOID
@ -115,7 +183,7 @@ PsInitThreadManagment(VOID)
ObjectTypeInitializer.DeleteProcedure = PspDeleteThread;
ObCreateObjectType(&Name, &ObjectTypeInitializer, NULL, &PsThreadType);
PsInitializeIdleOrFirstThread(PsInitialSystemProcess, &FirstThread, NULL, KernelMode, TRUE);
PsInitHackThread2(&FirstThread);
FirstThread->Tcb.State = Running;
FirstThread->Tcb.FreezeCount = 0;
FirstThread->Tcb.UserAffinity = (1 << 0); /* Set the affinity of the first thread to the boot processor */