Dedicated Idle process and thread initialization with dynamic affinity allocation
This commit is contained in:
@@ -478,8 +478,8 @@ typedef struct _KPROCESS
|
||||
ULONG_PTR DirectoryTable[2];
|
||||
USHORT IopmOffset;
|
||||
UCHAR Iopl;
|
||||
KAFFINITY_MAP Affinity;
|
||||
VOLATILE KAFFINITY_MAP ActiveProcessors;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
PKAFFINITY_MAP ActiveProcessors;
|
||||
ULONG KernelTime;
|
||||
ULONG UserTime;
|
||||
LIST_ENTRY ReadyListHead;
|
||||
@@ -603,9 +603,9 @@ typedef struct _KTHREAD
|
||||
CHAR PreviousMode;
|
||||
UCHAR ResourceIndex;
|
||||
UCHAR DisableBoost;
|
||||
KAFFINITY_MAP UserAffinity;
|
||||
PKAFFINITY_MAP UserAffinity;
|
||||
PKPROCESS Process;
|
||||
KAFFINITY_MAP Affinity;
|
||||
PKAFFINITY_MAP Affinity;
|
||||
PVOID ServiceTable;
|
||||
PKAPC_STATE ApcStatePointer[2];
|
||||
KAPC_STATE SavedApcState;
|
||||
|
||||
@@ -21,10 +21,12 @@ namespace KE
|
||||
STATIC EPROCESS InitialProcess;
|
||||
|
||||
public:
|
||||
STATIC XTAPI PKPROCESS GetIdleProcess(VOID);
|
||||
STATIC XTAPI PEPROCESS GetInitialProcess(VOID);
|
||||
STATIC XTAPI VOID InitializeIdleProcess(IN OUT PKPROCESS Process,
|
||||
IN PULONG_PTR DirectoryTable);
|
||||
STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process,
|
||||
IN KPRIORITY Priority,
|
||||
IN KAFFINITY Affinity,
|
||||
IN PULONG_PTR DirectoryTable,
|
||||
IN BOOLEAN Alignment);
|
||||
};
|
||||
|
||||
@@ -22,6 +22,10 @@ namespace KE
|
||||
|
||||
public:
|
||||
STATIC XTAPI PETHREAD GetInitialThread(VOID);
|
||||
STATIC XTAPI VOID InitializeIdleThread(IN PKPROCESS IdleProcess,
|
||||
IN OUT PKTHREAD IdleThread,
|
||||
IN PKPROCESSOR_CONTROL_BLOCK Prcb,
|
||||
IN PVOID Stack);
|
||||
STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process,
|
||||
IN OUT PKTHREAD Thread,
|
||||
IN PKSYSTEM_ROUTINE SystemRoutine,
|
||||
|
||||
@@ -26,6 +26,8 @@ VOID
|
||||
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
|
||||
PKPROCESS IdleProcess;
|
||||
PKTHREAD IdleThread;
|
||||
|
||||
/* Initialize application CPU */
|
||||
AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
|
||||
@@ -57,6 +59,15 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
|
||||
/* Initialize local clock for this CPU */
|
||||
HL::Timer::InitializeLocalClock();
|
||||
|
||||
/* Allocate and wipe memory for Idle thread */
|
||||
MM::Allocator::AllocatePool(NonPagedPool, sizeof(KTHREAD), (PVOID *)&IdleThread);
|
||||
RTL::Memory::ZeroMemory(IdleThread, sizeof(KTHREAD));
|
||||
|
||||
/* Initialize Idle thread */
|
||||
IdleProcess = KE::KProcess::GetIdleProcess();
|
||||
ControlBlock->CurrentThread = IdleThread;
|
||||
KE::KThread::InitializeIdleThread(IdleProcess, IdleThread, ControlBlock, StartBlock->Stack);
|
||||
|
||||
/* Register DISPATCH interrupt handler */
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt);
|
||||
|
||||
@@ -106,30 +117,18 @@ KE::KernelInit::BootstrapKernel(VOID)
|
||||
/* Initialize XTOS kernel */
|
||||
InitializeKernel();
|
||||
|
||||
/* Initialize Idle process */
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
CurrentProcess->Quantum = MAXCHAR;
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, AR::ProcessorSupport::GetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
CurrentThread->State = Running;
|
||||
CurrentThread->Affinity.Count = 1;
|
||||
CurrentThread->Affinity.Size = 1;
|
||||
CurrentThread->Affinity.Bitmap[0] = (KAFFINITY)1 << Prcb->CpuNumber;
|
||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||
CurrentProcess->ActiveProcessors.Bitmap[0] |= (KAFFINITY)1 << Prcb->CpuNumber;
|
||||
|
||||
/* Initialize Memory Manager */
|
||||
MM::Manager::InitializeMemoryManager();
|
||||
|
||||
/* Enable shadow buffer for framebuffer */
|
||||
HL::FrameBuffer::EnableShadowBuffer();
|
||||
|
||||
/* Initialize Idle process and Idle thread */
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KE::KProcess::InitializeIdleProcess(CurrentProcess, PageDirectory);
|
||||
KE::KThread::InitializeIdleThread(CurrentProcess, CurrentThread, Prcb, AR::ProcessorSupport::GetBootStack());
|
||||
|
||||
/* Start all application processors */
|
||||
KE::Processor::InitializeProcessorBlocks();
|
||||
HL::Cpu::StartAllProcessors();
|
||||
|
||||
@@ -26,6 +26,8 @@ VOID
|
||||
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
|
||||
{
|
||||
PKPROCESSOR_CONTROL_BLOCK ControlBlock;
|
||||
PKPROCESS IdleProcess;
|
||||
PKTHREAD IdleThread;
|
||||
|
||||
/* Initialize application CPU */
|
||||
AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
|
||||
@@ -57,6 +59,15 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
|
||||
/* Initialize local clock for this CPU */
|
||||
HL::Timer::InitializeLocalClock();
|
||||
|
||||
/* Allocate and wipe memory for Idle thread */
|
||||
MM::Allocator::AllocatePool(NonPagedPool, sizeof(KTHREAD), (PVOID *)&IdleThread);
|
||||
RTL::Memory::ZeroMemory(IdleThread, sizeof(KTHREAD));
|
||||
|
||||
/* Initialize Idle thread */
|
||||
IdleProcess = KE::KProcess::GetIdleProcess();
|
||||
ControlBlock->CurrentThread = IdleThread;
|
||||
KE::KThread::InitializeIdleThread(IdleProcess, IdleThread, ControlBlock, StartBlock->Stack);
|
||||
|
||||
/* Register DISPATCH interrupt handler */
|
||||
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt);
|
||||
|
||||
@@ -106,30 +117,18 @@ KE::KernelInit::BootstrapKernel(VOID)
|
||||
/* Initialize XTOS kernel */
|
||||
InitializeKernel();
|
||||
|
||||
/* Initialize Idle process */
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KE::KProcess::InitializeProcess(CurrentProcess, 0, MAXULONG_PTR, PageDirectory, FALSE);
|
||||
CurrentProcess->Quantum = MAXCHAR;
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KE::KThread::InitializeThread(CurrentProcess, CurrentThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, AR::ProcessorSupport::GetBootStack(), TRUE);
|
||||
CurrentThread->NextProcessor = Prcb->CpuNumber;
|
||||
CurrentThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
CurrentThread->State = Running;
|
||||
CurrentThread->Affinity.Count = 1;
|
||||
CurrentThread->Affinity.Size = 1;
|
||||
CurrentThread->Affinity.Bitmap[0] = (KAFFINITY)1 << Prcb->CpuNumber;
|
||||
CurrentThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||
CurrentProcess->ActiveProcessors.Bitmap[0] |= (KAFFINITY)1 << Prcb->CpuNumber;
|
||||
|
||||
/* Initialize Memory Manager */
|
||||
MM::Manager::InitializeMemoryManager();
|
||||
|
||||
/* Enable shadow buffer for framebuffer */
|
||||
HL::FrameBuffer::EnableShadowBuffer();
|
||||
|
||||
/* Initialize Idle process and Idle thread */
|
||||
PageDirectory[0] = 0;
|
||||
PageDirectory[1] = 0;
|
||||
KE::KProcess::InitializeIdleProcess(CurrentProcess, PageDirectory);
|
||||
KE::KThread::InitializeIdleThread(CurrentProcess, CurrentThread, Prcb, AR::ProcessorSupport::GetBootStack());
|
||||
|
||||
/* Start all application processors */
|
||||
KE::Processor::InitializeProcessorBlocks();
|
||||
HL::Cpu::StartAllProcessors();
|
||||
|
||||
@@ -9,6 +9,21 @@
|
||||
#include <xtos.hh>
|
||||
|
||||
|
||||
/**
|
||||
* Retrieves the pointer to the global Idle process.
|
||||
*
|
||||
* @return Returns a pointer to the Idle process.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
PKPROCESS
|
||||
KE::KProcess::GetIdleProcess(VOID)
|
||||
{
|
||||
/* Return pointer to the idle process */
|
||||
return &InitialProcess.ProcessControlBlock;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a pointer to the system's initial executive process object.
|
||||
*
|
||||
@@ -23,6 +38,55 @@ KE::KProcess::GetInitialProcess(VOID)
|
||||
return &InitialProcess;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the system-wide Idle Process.
|
||||
*
|
||||
* @param Process
|
||||
* Supplies a pointer to the KPROCESS structure representing the idle process.
|
||||
*
|
||||
* @param DirectoryTable
|
||||
* Supplies a pointer to the initial hardware page directory table for the process.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KE::KProcess::InitializeIdleProcess(IN OUT PKPROCESS Process,
|
||||
IN PULONG_PTR DirectoryTable)
|
||||
{
|
||||
ULONG AffinitySize, MapSize;
|
||||
PACPI_SYSTEM_INFO SysInfo;
|
||||
|
||||
/* Retrieve hardware topology from ACPI */
|
||||
HL::Acpi::GetSystemInformation(&SysInfo);
|
||||
|
||||
/* Calculate the required size for KAFFINITY_MAP structures */
|
||||
AffinitySize = (SysInfo->CpuCount + 63) / 64;
|
||||
MapSize = sizeof(KAFFINITY_MAP) + (AffinitySize * sizeof(KAFFINITY));
|
||||
|
||||
/* Align size to the 8-byte boundary */
|
||||
MapSize = (MapSize + 7) & ~7;
|
||||
|
||||
/* Allocate the process-level affinity structures */
|
||||
MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&Process->Affinity);
|
||||
MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&Process->ActiveProcessors);
|
||||
|
||||
/* Zero the process-level affinity structures */
|
||||
RTL::Memory::ZeroMemory(Process->Affinity, MapSize);
|
||||
RTL::Memory::ZeroMemory(Process->ActiveProcessors, MapSize);
|
||||
|
||||
/* Initialize size metadata */
|
||||
Process->Affinity->Count = (USHORT)AffinitySize;
|
||||
Process->Affinity->Size = (USHORT)AffinitySize;
|
||||
Process->ActiveProcessors->Size = (USHORT)AffinitySize;
|
||||
|
||||
/* Initialize Idle process */
|
||||
KE::KProcess::InitializeProcess(Process, 0, DirectoryTable, FALSE);
|
||||
Process->Quantum = MAXCHAR;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the process.
|
||||
*
|
||||
@@ -49,7 +113,6 @@ XTAPI
|
||||
VOID
|
||||
KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process,
|
||||
IN KPRIORITY Priority,
|
||||
IN KAFFINITY Affinity,
|
||||
IN PULONG_PTR DirectoryTable,
|
||||
IN BOOLEAN Alignment)
|
||||
{
|
||||
@@ -68,11 +131,6 @@ KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process,
|
||||
Process->BasePriority = Priority;
|
||||
Process->AutoAlignment = Alignment;
|
||||
|
||||
/* Initialize KAFFINITY_MAP for single-group affinity */
|
||||
Process->Affinity.Count = 1;
|
||||
Process->Affinity.Size = 1;
|
||||
Process->Affinity.Bitmap[0] = Affinity;
|
||||
|
||||
/* Set directory tables */
|
||||
Process->DirectoryTable[0] = DirectoryTable[0];
|
||||
Process->DirectoryTable[1] = DirectoryTable[1];
|
||||
|
||||
@@ -23,6 +23,81 @@ KE::KThread::GetInitialThread(VOID)
|
||||
return &InitialThread;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes an Idle Thread.
|
||||
*
|
||||
* @param IdleProcess
|
||||
* Supplies a pointer to the global Idle Process container.
|
||||
*
|
||||
* @param IdleThread
|
||||
* Supplies a pointer to the KTHREAD structure being initialized.
|
||||
*
|
||||
* @param Prcb
|
||||
* Supplies a pointer to the Processor Control Block of the target CPU.
|
||||
*
|
||||
* @param Stack
|
||||
* Supplies a pointer to the pre-allocated kernel stack for this thread.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
* @since XT 1.0
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
KE::KThread::InitializeIdleThread(IN PKPROCESS IdleProcess,
|
||||
IN OUT PKTHREAD IdleThread,
|
||||
IN PKPROCESSOR_CONTROL_BLOCK Prcb,
|
||||
IN PVOID Stack)
|
||||
{
|
||||
ULONG AffinitySize, CpuIndex, CpuTargetBit, MapSize;
|
||||
PACPI_SYSTEM_INFO SysInfo;
|
||||
|
||||
/* Retrieve hardware topology from ACPI */
|
||||
HL::Acpi::GetSystemInformation(&SysInfo);
|
||||
|
||||
/* Calculate the required size for KAFFINITY_MAP structures */
|
||||
AffinitySize = (SysInfo->CpuCount + 63) / 64;
|
||||
MapSize = sizeof(KAFFINITY_MAP) + (AffinitySize * sizeof(KAFFINITY));
|
||||
|
||||
/* Align size to the 8-byte boundary */
|
||||
MapSize = (MapSize + 7) & ~7;
|
||||
|
||||
/* Allocate the thread-level affinity structures */
|
||||
MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&IdleThread->Affinity);
|
||||
MM::Allocator::AllocatePool(NonPagedPool, MapSize, (PVOID*)&IdleThread->UserAffinity);
|
||||
|
||||
/* Zero the thread-level affinity structures */
|
||||
RTL::Memory::ZeroMemory(IdleThread->Affinity, MapSize);
|
||||
RTL::Memory::ZeroMemory(IdleThread->UserAffinity, MapSize);
|
||||
|
||||
/* Initialize Idle thread */
|
||||
KE::KThread::InitializeThread(IdleProcess, IdleThread, NULLPTR, NULLPTR, NULLPTR,
|
||||
NULLPTR, NULLPTR, Stack, TRUE);
|
||||
|
||||
/* Configure Idle thread scheduling parameters */
|
||||
IdleThread->NextProcessor = Prcb->CpuNumber;
|
||||
IdleThread->Priority = THREAD_HIGH_PRIORITY;
|
||||
IdleThread->State = Running;
|
||||
IdleThread->WaitRunLevel = DISPATCH_LEVEL;
|
||||
|
||||
/* Calculate exact block array index and bit offset for this specific CPU */
|
||||
CpuIndex = Prcb->CpuNumber / 64;
|
||||
CpuTargetBit = Prcb->CpuNumber % 64;
|
||||
|
||||
/* Configure Idle thread affinity */
|
||||
IdleThread->Affinity->Bitmap[CpuIndex] = ((KAFFINITY)1 << CpuTargetBit);
|
||||
IdleThread->Affinity->Count = (USHORT)(CpuIndex + 1);
|
||||
IdleThread->Affinity->Size = (USHORT)AffinitySize;
|
||||
|
||||
/* Configure Idle thread user affinity */
|
||||
IdleThread->UserAffinity->Bitmap[CpuIndex] = ((KAFFINITY)1 << CpuTargetBit);
|
||||
IdleThread->UserAffinity->Count = (USHORT)(CpuIndex + 1);
|
||||
IdleThread->UserAffinity->Size = (USHORT)AffinitySize;
|
||||
|
||||
/* Register this CPU as active in the Idle Process */
|
||||
IdleProcess->ActiveProcessors->Bitmap[CpuIndex] |= ((KAFFINITY)1 << CpuTargetBit);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the thread.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user