From 95a78ef939fe13e11d61ad4842a73d80542d3b7c Mon Sep 17 00:00:00 2001 From: Alex Date: Sat, 18 Feb 2023 04:10:41 +0200 Subject: [PATCH] CurrentThread/Process should be atomic --- KThread.cpp | 2 -- Tasking/Scheduler.cpp | 6 +++--- Tasking/Task.cpp | 30 +++++++++++++++--------------- include/smp.hpp | 7 ++++--- 4 files changed, 22 insertions(+), 23 deletions(-) diff --git a/KThread.cpp b/KThread.cpp index b4004e1..2053955 100644 --- a/KThread.cpp +++ b/KThread.cpp @@ -182,7 +182,6 @@ void KernelMainThread() Display->Print('.', 0); Display->SetBuffer(0); - CPU::Interrupts(CPU::Disable); ExecuteThread = TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)Execute::StartExecuteService); ExecuteThread->Rename("Library Manager"); ExecuteThread->SetCritical(true); @@ -206,7 +205,6 @@ void KernelMainThread() TaskManager->GetSecurityManager()->TrustToken(ret.Thread->Security.UniqueToken, Tasking::TTL::FullTrust); ret.Thread->SetCritical(true); KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath); - CPU::Interrupts(CPU::Enable); TaskManager->GetCurrentThread()->SetPriority(Tasking::Idle); TaskManager->WaitForThread(ret.Thread); ExitCode = ret.Thread->GetExitCode(); diff --git a/Tasking/Scheduler.cpp b/Tasking/Scheduler.cpp index 9358f97..6652560 100644 --- a/Tasking/Scheduler.cpp +++ b/Tasking/Scheduler.cpp @@ -155,7 +155,7 @@ namespace Tasking for (size_t i = 0; i < CurrentCPU->CurrentProcess->Threads.size(); i++) { - if (CurrentCPU->CurrentProcess->Threads[i] == CurrentCPU->CurrentThread) + if (CurrentCPU->CurrentProcess->Threads[i] == CurrentCPU->CurrentThread.Load()) { size_t TempIndex = i; RetryAnotherThread: @@ -199,7 +199,7 @@ namespace Tasking bool Skip = true; foreach (auto pcb in ListProcess) { - if (pcb == CurrentCPU->CurrentProcess) + if (pcb == CurrentCPU->CurrentProcess.Load()) { Skip = false; gnap_schedbg("Found current process %#lx", pcb); @@ -475,7 +475,7 @@ namespace Tasking } #endif - if (unlikely(InvalidPCB(CurrentCPU->CurrentProcess) || InvalidTCB(CurrentCPU->CurrentThread))) + if (unlikely(InvalidPCB(CurrentCPU->CurrentProcess.Load()) || InvalidTCB(CurrentCPU->CurrentThread.Load()))) { schedbg("Invalid process or thread. Finding a new one."); if (this->FindNewProcess(CurrentCPU)) diff --git a/Tasking/Task.cpp b/Tasking/Task.cpp index 2092ad6..3342c75 100644 --- a/Tasking/Task.cpp +++ b/Tasking/Task.cpp @@ -198,8 +198,8 @@ namespace Tasking CPU::Halt(true); } - PCB *Task::GetCurrentProcess() { return GetCurrentCPU()->CurrentProcess; } - TCB *Task::GetCurrentThread() { return GetCurrentCPU()->CurrentThread; } + PCB *Task::GetCurrentProcess() { return GetCurrentCPU()->CurrentProcess.Load(); } + TCB *Task::GetCurrentThread() { return GetCurrentCPU()->CurrentThread.Load(); } PCB *Task::GetProcessByID(UPID ID) { @@ -226,7 +226,7 @@ namespace Tasking return; debug("Waiting for process \"%s\"(%d)", pcb->Name, pcb->ID); while (pcb->Status != TaskStatus::Terminated) - CPU::Halt(); + CPU::Pause(); } void Task::WaitForThread(TCB *tcb) @@ -237,7 +237,7 @@ namespace Tasking return; debug("Waiting for thread \"%s\"(%d)", tcb->Name, tcb->ID); while (tcb->Status != TaskStatus::Terminated) - CPU::Halt(); + CPU::Pause(); } void Task::WaitForProcessStatus(PCB *pcb, TaskStatus status) @@ -248,7 +248,7 @@ namespace Tasking return; debug("Waiting for process \"%s\"(%d) to reach status: %d", pcb->Name, pcb->ID, status); while (pcb->Status != status) - CPU::Halt(); + CPU::Pause(); } void Task::WaitForThreadStatus(TCB *tcb, TaskStatus status) @@ -259,7 +259,7 @@ namespace Tasking return; debug("Waiting for thread \"%s\"(%d) to reach status: %d", tcb->Name, tcb->ID, status); while (tcb->Status != status) - CPU::Halt(); + CPU::Pause(); } void Task::Sleep(uint64_t Milliseconds) @@ -818,15 +818,15 @@ namespace Tasking #if defined(__amd64__) ((APIC::Timer *)Interrupts::apicTimer[0])->OneShot(CPU::x64::IRQ16, 100); - for (int i = 1; i < SMP::CPUCores; i++) - { - // ((APIC::Timer *)Interrupts::apicTimer[i])->OneShot(CPU::x64::IRQ16, 100); - // TODO: Lock was the fault here. Now crash handler should support SMP. - // APIC::InterruptCommandRegisterLow icr; - // icr.Vector = CPU::x64::IRQ16; - // icr.Level = APIC::APICLevel::Assert; - // ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); - } + /* FIXME: The kernel is not ready for multi-core tasking. */ + // for (int i = 1; i < SMP::CPUCores; i++) + // { + // ((APIC::Timer *)Interrupts::apicTimer[i])->OneShot(CPU::x64::IRQ16, 100); + // APIC::InterruptCommandRegisterLow icr; + // icr.Vector = CPU::x64::IRQ16; + // icr.Level = APIC::APICLevel::Assert; + // ((APIC::APIC *)Interrupts::apic[0])->IPI(i, icr); + // } #elif defined(__i386__) #elif defined(__aarch64__) #endif diff --git a/include/smp.hpp b/include/smp.hpp index a02f082..849f4f2 100644 --- a/include/smp.hpp +++ b/include/smp.hpp @@ -2,6 +2,7 @@ #define __FENNIX_KERNEL_SMP_H__ #include +#include #include /** @brief Maximum supported number of CPU cores by the kernel */ @@ -34,15 +35,15 @@ struct CPUData bool IsActive; /** @brief Current running process */ - Tasking::PCB *CurrentProcess; + Atomic CurrentProcess; /** @brief Current running thread */ - Tasking::TCB *CurrentThread; + Atomic CurrentThread; /** @brief Architecture-specific data. */ CPUArchData Data; /** @brief Checksum. Used to verify the integrity of the data. Must be equal to CPU_DATA_CHECKSUM (0xC0FFEE). */ int Checksum; -} __attribute__((packed)); +}; CPUData *GetCurrentCPU(); CPUData *GetCPU(long ID);