Dedicated Idle process and thread initialization with dynamic affinity allocation

This commit is contained in:
2026-06-04 11:23:47 +02:00
parent 34aba8c7c7
commit 1d2d66fc83
7 changed files with 184 additions and 47 deletions

View File

@@ -478,8 +478,8 @@ typedef struct _KPROCESS
ULONG_PTR DirectoryTable[2]; ULONG_PTR DirectoryTable[2];
USHORT IopmOffset; USHORT IopmOffset;
UCHAR Iopl; UCHAR Iopl;
KAFFINITY_MAP Affinity; PKAFFINITY_MAP Affinity;
VOLATILE KAFFINITY_MAP ActiveProcessors; PKAFFINITY_MAP ActiveProcessors;
ULONG KernelTime; ULONG KernelTime;
ULONG UserTime; ULONG UserTime;
LIST_ENTRY ReadyListHead; LIST_ENTRY ReadyListHead;
@@ -603,9 +603,9 @@ typedef struct _KTHREAD
CHAR PreviousMode; CHAR PreviousMode;
UCHAR ResourceIndex; UCHAR ResourceIndex;
UCHAR DisableBoost; UCHAR DisableBoost;
KAFFINITY_MAP UserAffinity; PKAFFINITY_MAP UserAffinity;
PKPROCESS Process; PKPROCESS Process;
KAFFINITY_MAP Affinity; PKAFFINITY_MAP Affinity;
PVOID ServiceTable; PVOID ServiceTable;
PKAPC_STATE ApcStatePointer[2]; PKAPC_STATE ApcStatePointer[2];
KAPC_STATE SavedApcState; KAPC_STATE SavedApcState;

View File

@@ -21,10 +21,12 @@ namespace KE
STATIC EPROCESS InitialProcess; STATIC EPROCESS InitialProcess;
public: public:
STATIC XTAPI PKPROCESS GetIdleProcess(VOID);
STATIC XTAPI PEPROCESS GetInitialProcess(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, STATIC XTAPI VOID InitializeProcess(IN OUT PKPROCESS Process,
IN KPRIORITY Priority, IN KPRIORITY Priority,
IN KAFFINITY Affinity,
IN PULONG_PTR DirectoryTable, IN PULONG_PTR DirectoryTable,
IN BOOLEAN Alignment); IN BOOLEAN Alignment);
}; };

View File

@@ -22,6 +22,10 @@ namespace KE
public: public:
STATIC XTAPI PETHREAD GetInitialThread(VOID); 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, STATIC XTAPI XTSTATUS InitializeThread(IN PKPROCESS Process,
IN OUT PKTHREAD Thread, IN OUT PKTHREAD Thread,
IN PKSYSTEM_ROUTINE SystemRoutine, IN PKSYSTEM_ROUTINE SystemRoutine,

View File

@@ -26,6 +26,8 @@ VOID
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
{ {
PKPROCESSOR_CONTROL_BLOCK ControlBlock; PKPROCESSOR_CONTROL_BLOCK ControlBlock;
PKPROCESS IdleProcess;
PKTHREAD IdleThread;
/* Initialize application CPU */ /* Initialize application CPU */
AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures); AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
@@ -57,6 +59,15 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
/* Initialize local clock for this CPU */ /* Initialize local clock for this CPU */
HL::Timer::InitializeLocalClock(); 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 */ /* Register DISPATCH interrupt handler */
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt); HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt);
@@ -106,30 +117,18 @@ KE::KernelInit::BootstrapKernel(VOID)
/* Initialize XTOS kernel */ /* Initialize XTOS kernel */
InitializeKernel(); 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 */ /* Initialize Memory Manager */
MM::Manager::InitializeMemoryManager(); MM::Manager::InitializeMemoryManager();
/* Enable shadow buffer for framebuffer */ /* Enable shadow buffer for framebuffer */
HL::FrameBuffer::EnableShadowBuffer(); 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 */ /* Start all application processors */
KE::Processor::InitializeProcessorBlocks(); KE::Processor::InitializeProcessorBlocks();
HL::Cpu::StartAllProcessors(); HL::Cpu::StartAllProcessors();

View File

@@ -26,6 +26,8 @@ VOID
KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock) KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlock)
{ {
PKPROCESSOR_CONTROL_BLOCK ControlBlock; PKPROCESSOR_CONTROL_BLOCK ControlBlock;
PKPROCESS IdleProcess;
PKTHREAD IdleThread;
/* Initialize application CPU */ /* Initialize application CPU */
AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures); AR::ProcessorSupport::InitializeProcessor(StartBlock->ProcessorStructures);
@@ -57,6 +59,15 @@ KE::KernelInit::BootstrapApplicationProcessor(IN PPROCESSOR_START_BLOCK StartBlo
/* Initialize local clock for this CPU */ /* Initialize local clock for this CPU */
HL::Timer::InitializeLocalClock(); 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 */ /* Register DISPATCH interrupt handler */
HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt); HL::Irq::RegisterSystemInterruptHandler(APIC_VECTOR_DPC, KE::Dispatcher::HandleDispatchInterrupt);
@@ -106,30 +117,18 @@ KE::KernelInit::BootstrapKernel(VOID)
/* Initialize XTOS kernel */ /* Initialize XTOS kernel */
InitializeKernel(); 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 */ /* Initialize Memory Manager */
MM::Manager::InitializeMemoryManager(); MM::Manager::InitializeMemoryManager();
/* Enable shadow buffer for framebuffer */ /* Enable shadow buffer for framebuffer */
HL::FrameBuffer::EnableShadowBuffer(); 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 */ /* Start all application processors */
KE::Processor::InitializeProcessorBlocks(); KE::Processor::InitializeProcessorBlocks();
HL::Cpu::StartAllProcessors(); HL::Cpu::StartAllProcessors();

View File

@@ -9,6 +9,21 @@
#include <xtos.hh> #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. * Retrieves a pointer to the system's initial executive process object.
* *
@@ -23,6 +38,55 @@ KE::KProcess::GetInitialProcess(VOID)
return &InitialProcess; 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. * Initializes the process.
* *
@@ -49,7 +113,6 @@ XTAPI
VOID VOID
KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process, KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process,
IN KPRIORITY Priority, IN KPRIORITY Priority,
IN KAFFINITY Affinity,
IN PULONG_PTR DirectoryTable, IN PULONG_PTR DirectoryTable,
IN BOOLEAN Alignment) IN BOOLEAN Alignment)
{ {
@@ -68,11 +131,6 @@ KE::KProcess::InitializeProcess(IN OUT PKPROCESS Process,
Process->BasePriority = Priority; Process->BasePriority = Priority;
Process->AutoAlignment = Alignment; 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 */ /* Set directory tables */
Process->DirectoryTable[0] = DirectoryTable[0]; Process->DirectoryTable[0] = DirectoryTable[0];
Process->DirectoryTable[1] = DirectoryTable[1]; Process->DirectoryTable[1] = DirectoryTable[1];

View File

@@ -23,6 +23,81 @@ KE::KThread::GetInitialThread(VOID)
return &InitialThread; 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. * Initializes the thread.
* *