mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 15:34:33 +00:00
Improved tasking
This commit is contained in:
parent
99606bed00
commit
0f16d63553
218
Tasking/Task.cpp
218
Tasking/Task.cpp
@ -1,7 +1,6 @@
|
|||||||
#include <task.hpp>
|
#include <task.hpp>
|
||||||
|
|
||||||
#include <lock.hpp>
|
#include <lock.hpp>
|
||||||
#include <debug.h>
|
|
||||||
#include <smp.hpp>
|
#include <smp.hpp>
|
||||||
|
|
||||||
#include "../kernel.h"
|
#include "../kernel.h"
|
||||||
@ -22,7 +21,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NewLock(TaskingLock);
|
NewLock(TaskingLock);
|
||||||
NewLock(TaskingGetCurrentLock);
|
NewLock(SchedulerLock);
|
||||||
|
|
||||||
namespace Tasking
|
namespace Tasking
|
||||||
{
|
{
|
||||||
@ -41,7 +40,6 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#if defined(__amd64__) || defined(__i386__)
|
||||||
asmv("IdleLoop:\n"
|
asmv("IdleLoop:\n"
|
||||||
"call OneShot\n"
|
|
||||||
"hlt\n"
|
"hlt\n"
|
||||||
"jmp IdleLoop\n");
|
"jmp IdleLoop\n");
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
@ -51,6 +49,87 @@ namespace Tasking
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((no_stack_protector)) void Task::RemoveThread(TCB *Thread)
|
||||||
|
{
|
||||||
|
for (uint64_t i = 0; i < Thread->Parent->Threads.size(); i++)
|
||||||
|
if (Thread->Parent->Threads[i] == Thread)
|
||||||
|
{
|
||||||
|
trace("Thread \"%s\"(%d) removed from process \"%s\"(%d)",
|
||||||
|
Thread->Name, Thread->ID, Thread->Parent->Name, Thread->Parent->ID);
|
||||||
|
// Free memory
|
||||||
|
KernelAllocator.FreePages((void *)((uint64_t)Thread->Stack - STACK_SIZE), TO_PAGES(STACK_SIZE));
|
||||||
|
SecurityManager.DestroyToken(Thread->Security.UniqueToken);
|
||||||
|
delete Thread->Parent->Threads[i];
|
||||||
|
// Remove from the list
|
||||||
|
Thread->Parent->Threads.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((no_stack_protector)) void Task::RemoveProcess(PCB *Process)
|
||||||
|
{
|
||||||
|
if (Process == nullptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Process->Status == Terminated)
|
||||||
|
{
|
||||||
|
foreach (TCB *thread in Process->Threads)
|
||||||
|
RemoveThread(thread);
|
||||||
|
|
||||||
|
foreach (PCB *process in Process->Children)
|
||||||
|
RemoveProcess(process);
|
||||||
|
|
||||||
|
for (uint64_t i = 0; i < ListProcess.size(); i++)
|
||||||
|
{
|
||||||
|
if (ListProcess[i] == Process)
|
||||||
|
{
|
||||||
|
trace("Process \"%s\"(%d) removed from the list", Process->Name, Process->ID);
|
||||||
|
// Free memory
|
||||||
|
delete ListProcess[i]->IPCHandles;
|
||||||
|
SecurityManager.DestroyToken(ListProcess[i]->Security.UniqueToken);
|
||||||
|
KernelAllocator.FreePages((void *)ListProcess[i]->PageTable, TO_PAGES(PAGE_SIZE));
|
||||||
|
delete ListProcess[i];
|
||||||
|
// Remove from the list
|
||||||
|
ListProcess.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (TCB *thread in Process->Threads)
|
||||||
|
if (thread->Status == Terminated)
|
||||||
|
RemoveThread(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((no_stack_protector)) void Task::UpdateInfo(TaskInfo *Info, int Core)
|
||||||
|
{
|
||||||
|
if (Info->Affinity[Core] == true)
|
||||||
|
{
|
||||||
|
// TODO: Not working
|
||||||
|
uint64_t CounterNow = CPU::Counter();
|
||||||
|
|
||||||
|
Info->OldUserTime = Info->CurrentUserTime;
|
||||||
|
Info->OldKernelTime = Info->CurrentKernelTime;
|
||||||
|
|
||||||
|
Info->CurrentUserTime = Info->UserTime;
|
||||||
|
Info->CurrentKernelTime = Info->KernelTime;
|
||||||
|
|
||||||
|
Info->UserTime = 0;
|
||||||
|
Info->KernelTime = 0;
|
||||||
|
|
||||||
|
Info->Usage[Core] = (Info->CurrentUserTime - Info->OldUserTime) + (Info->CurrentKernelTime - Info->OldKernelTime);
|
||||||
|
Info->Usage[Core] = (Info->Usage[Core] * 100) / (CounterNow - Info->SpawnTime);
|
||||||
|
|
||||||
|
Info->OldUserTime = Info->CurrentUserTime;
|
||||||
|
Info->OldKernelTime = Info->CurrentKernelTime;
|
||||||
|
|
||||||
|
Info->CurrentUserTime = Info->UserTime;
|
||||||
|
Info->CurrentKernelTime = Info->KernelTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
__attribute__((no_stack_protector)) bool Task::FindNewProcess(void *CPUDataPointer)
|
__attribute__((no_stack_protector)) bool Task::FindNewProcess(void *CPUDataPointer)
|
||||||
{
|
{
|
||||||
@ -75,8 +154,8 @@ namespace Tasking
|
|||||||
schedbg("Ready process (%s)%d", pcb->Name, pcb->ID);
|
schedbg("Ready process (%s)%d", pcb->Name, pcb->ID);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
schedbg("Process %s(%d) status %d", pcb->Name, pcb->ID, pcb->Status);
|
schedbg("Process \"%s\"(%d) status %d", pcb->Name, pcb->ID, pcb->Status);
|
||||||
// RemoveProcess(pcb); // ignore for now
|
RemoveProcess(pcb);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,9 +182,10 @@ namespace Tasking
|
|||||||
|
|
||||||
__attribute__((no_stack_protector)) void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
|
__attribute__((no_stack_protector)) void Task::OnInterruptReceived(CPU::x64::TrapFrame *Frame)
|
||||||
{
|
{
|
||||||
SmartCriticalSection(TaskingLock);
|
SmartCriticalSection(SchedulerLock);
|
||||||
CPUData *CurrentCPU = GetCurrentCPU();
|
CPUData *CurrentCPU = GetCurrentCPU();
|
||||||
// debug("Scheduler called on CPU %d.", CurrentCPU->ID);
|
// debug("Scheduler called on CPU %d.", CurrentCPU->ID);
|
||||||
|
// debug("%d: %ld%%", CurrentCPU->ID, GetUsage(CurrentCPU->ID));
|
||||||
|
|
||||||
schedbg("================================================================");
|
schedbg("================================================================");
|
||||||
schedbg("Status: 0-ukn | 1-rdy | 2-run | 3-wait | 4-term");
|
schedbg("Status: 0-ukn | 1-rdy | 2-run | 3-wait | 4-term");
|
||||||
@ -163,7 +243,7 @@ namespace Tasking
|
|||||||
goto RetryAnotherThread;
|
goto RetryAnotherThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
schedbg("%s(%d) and next thread is %s(%d)", CurrentCPU->CurrentProcess->Threads[i]->Name, CurrentCPU->CurrentProcess->Threads[i]->ID, thread->Name, thread->ID);
|
schedbg("\"%s\"(%d) and next thread is \"%s\"(%d)", CurrentCPU->CurrentProcess->Threads[i]->Name, CurrentCPU->CurrentProcess->Threads[i]->ID, thread->Name, thread->ID);
|
||||||
|
|
||||||
// Check if the thread is ready to be executed.
|
// Check if the thread is ready to be executed.
|
||||||
if (thread->Status != TaskStatus::Ready)
|
if (thread->Status != TaskStatus::Ready)
|
||||||
@ -223,7 +303,7 @@ namespace Tasking
|
|||||||
{
|
{
|
||||||
if (InvalidPCB(pcb))
|
if (InvalidPCB(pcb))
|
||||||
continue;
|
continue;
|
||||||
// RemoveProcess(pcb); // comment this until i will find a way to handle properly vectors, the memory need to be 0ed after removing.
|
RemoveProcess(pcb);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we didn't find anything, we check from the start of the list. This is the last chance to find something or we go to idle.
|
// If we didn't find anything, we check from the start of the list. This is the last chance to find something or we go to idle.
|
||||||
@ -249,37 +329,27 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
goto UnwantedReach; // This should never happen.
|
||||||
|
|
||||||
Idle:
|
Idle:
|
||||||
{
|
{
|
||||||
// Should I remove processes that are no longer have any threads? Remove only from userspace?
|
|
||||||
if (IdleProcess == nullptr)
|
|
||||||
{
|
|
||||||
schedbg("Idle process created");
|
|
||||||
IdleProcess = CreateProcess(nullptr, (char *)"idle", TaskTrustLevel::Idle);
|
|
||||||
IdleThread = CreateThread(IdleProcess, reinterpret_cast<uint64_t>(IdleProcessLoop), 0);
|
|
||||||
}
|
|
||||||
CurrentCPU->CurrentProcess = IdleProcess;
|
CurrentCPU->CurrentProcess = IdleProcess;
|
||||||
CurrentCPU->CurrentThread = IdleThread;
|
CurrentCPU->CurrentThread = IdleThread;
|
||||||
|
goto Success;
|
||||||
*Frame = CurrentCPU->CurrentThread->Registers;
|
|
||||||
CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable});
|
|
||||||
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);
|
|
||||||
goto End;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Success:
|
Success:
|
||||||
{
|
{
|
||||||
schedbg("Success Prc:%s(%d) Thd:%s(%d)->RIP:%#lx-RSP:%#lx(STACK: %#lx)",
|
schedbg("Process \"%s\"(%d) Thread \"%s\"(%d) is now running on CPU %d",
|
||||||
CurrentCPU->CurrentProcess->Name, CurrentCPU->CurrentProcess->ID,
|
CurrentCPU->CurrentProcess->Name, CurrentCPU->CurrentProcess->ID,
|
||||||
CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID,
|
CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID, CurrentCPU->ID);
|
||||||
CurrentCPU->CurrentThread->Registers.rip, CurrentCPU->CurrentThread->Registers.rsp, CurrentCPU->CurrentThread->Stack);
|
|
||||||
|
|
||||||
CurrentCPU->CurrentProcess->Status = TaskStatus::Running;
|
CurrentCPU->CurrentProcess->Status = TaskStatus::Running;
|
||||||
CurrentCPU->CurrentThread->Status = TaskStatus::Running;
|
CurrentCPU->CurrentThread->Status = TaskStatus::Running;
|
||||||
|
|
||||||
*Frame = CurrentCPU->CurrentThread->Registers;
|
*Frame = CurrentCPU->CurrentThread->Registers;
|
||||||
CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable});
|
CPU::x64::writecr3({.raw = (uint64_t)CurrentCPU->CurrentProcess->PageTable});
|
||||||
|
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);
|
||||||
|
|
||||||
switch (CurrentCPU->CurrentProcess->Security.TrustLevel)
|
switch (CurrentCPU->CurrentProcess->Security.TrustLevel)
|
||||||
{
|
{
|
||||||
@ -295,16 +365,19 @@ namespace Tasking
|
|||||||
error("Unknown trust level %d.", CurrentCPU->CurrentProcess->Security.TrustLevel);
|
error("Unknown trust level %d.", CurrentCPU->CurrentProcess->Security.TrustLevel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CPU::x64::fxrstor(CurrentCPU->CurrentThread->FXRegion);
|
goto End;
|
||||||
|
}
|
||||||
|
UnwantedReach:
|
||||||
|
{
|
||||||
|
warn("Unwanted reach!");
|
||||||
|
OneShot(100);
|
||||||
|
goto RealEnd;
|
||||||
}
|
}
|
||||||
End:
|
End:
|
||||||
{
|
{
|
||||||
// UpdateTimeUsed(&CurrentCPU->CurrentProcess->Info);
|
UpdateInfo(&CurrentCPU->CurrentProcess->Info, CurrentCPU->ID);
|
||||||
// UpdateTimeUsed(&CurrentCPU->CurrentThread->Info);
|
UpdateInfo(&CurrentCPU->CurrentThread->Info, CurrentCPU->ID);
|
||||||
// UpdateCPUUsage(&CurrentCPU->CurrentProcess->Info);
|
|
||||||
// UpdateCPUUsage(&CurrentCPU->CurrentThread->Info);
|
|
||||||
OneShot(CurrentCPU->CurrentThread->Info.Priority);
|
OneShot(CurrentCPU->CurrentThread->Info.Priority);
|
||||||
schedbg("Scheduler end");
|
|
||||||
}
|
}
|
||||||
schedbg("================================================================");
|
schedbg("================================================================");
|
||||||
schedbg("Technical Informations on Thread %s[%ld]:", CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID);
|
schedbg("Technical Informations on Thread %s[%ld]:", CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID);
|
||||||
@ -322,6 +395,10 @@ namespace Tasking
|
|||||||
schedbg("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx",
|
schedbg("RIP=%#lx RFL=%#lx INT=%#lx ERR=%#lx",
|
||||||
Frame->rip, Frame->rflags, Frame->InterruptNumber, Frame->ErrorCode);
|
Frame->rip, Frame->rflags, Frame->InterruptNumber, Frame->ErrorCode);
|
||||||
schedbg("================================================================");
|
schedbg("================================================================");
|
||||||
|
RealEnd:
|
||||||
|
{
|
||||||
|
schedbg("Scheduler end");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
@ -347,32 +424,45 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void ThreadDoExit(int Code)
|
void ThreadDoExit()
|
||||||
{
|
{
|
||||||
SmartCriticalSection(TaskingLock);
|
// TODO: How I can lock the scheduler without causing a deadlock?
|
||||||
CPUData *CPUData = GetCurrentCPU();
|
CPUData *CPUData = GetCurrentCPU();
|
||||||
CPUData->CurrentThread->Status = TaskStatus::Terminated;
|
CPUData->CurrentThread->Status = TaskStatus::Terminated;
|
||||||
CPUData->CurrentThread->ExitCode = Code;
|
debug("\"%s\"(%d) exited with code: %#lx", CPUData->CurrentThread->Name, CPUData->CurrentThread->ID, CPUData->CurrentThread->ExitCode);
|
||||||
debug("parent:%s tid:%d, code:%016p", CPUData->CurrentProcess->Name, CPUData->CurrentThread->ID, Code);
|
|
||||||
trace("Exiting thread %d(%s)...", CPUData->CurrentThread->ID, CPUData->CurrentThread->Name);
|
|
||||||
OneShot(CPUData->CurrentThread->Info.Priority);
|
|
||||||
CPU::Halt(true);
|
CPU::Halt(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
PCB *Task::GetCurrentProcess()
|
PCB *Task::GetCurrentProcess()
|
||||||
{
|
{
|
||||||
SmartCriticalSection(TaskingGetCurrentLock);
|
SmartCriticalSection(TaskingLock);
|
||||||
return GetCurrentCPU()->CurrentProcess;
|
return GetCurrentCPU()->CurrentProcess;
|
||||||
}
|
}
|
||||||
|
|
||||||
TCB *Task::GetCurrentThread()
|
TCB *Task::GetCurrentThread()
|
||||||
{
|
{
|
||||||
SmartCriticalSection(TaskingGetCurrentLock);
|
SmartCriticalSection(TaskingLock);
|
||||||
return GetCurrentCPU()->CurrentThread;
|
return GetCurrentCPU()->CurrentThread;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Task::WaitForProcess(PCB *pcb)
|
||||||
|
{
|
||||||
|
debug("Waiting for process \"%s\"(%d)", pcb->Name, pcb->ID);
|
||||||
|
while (pcb->Status != TaskStatus::Terminated)
|
||||||
|
CPU::Halt();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Task::WaitForThread(TCB *tcb)
|
||||||
|
{
|
||||||
|
debug("Waiting for thread \"%s\"(%d)", tcb->Name, tcb->ID);
|
||||||
|
while (tcb->Status != TaskStatus::Terminated)
|
||||||
|
CPU::Halt();
|
||||||
|
}
|
||||||
|
|
||||||
TCB *Task::CreateThread(PCB *Parent,
|
TCB *Task::CreateThread(PCB *Parent,
|
||||||
IP EntryPoint,
|
IP EntryPoint,
|
||||||
|
Arg Argument0,
|
||||||
|
Arg Argument1,
|
||||||
IPOffset Offset,
|
IPOffset Offset,
|
||||||
TaskArchitecture Architecture,
|
TaskArchitecture Architecture,
|
||||||
TaskCompatibility Compatibility)
|
TaskCompatibility Compatibility)
|
||||||
@ -380,7 +470,11 @@ namespace Tasking
|
|||||||
SmartCriticalSection(TaskingLock);
|
SmartCriticalSection(TaskingLock);
|
||||||
TCB *Thread = new TCB;
|
TCB *Thread = new TCB;
|
||||||
if (Parent == nullptr)
|
if (Parent == nullptr)
|
||||||
|
{
|
||||||
|
TaskingLock.Unlock();
|
||||||
Thread->Parent = this->GetCurrentProcess();
|
Thread->Parent = this->GetCurrentProcess();
|
||||||
|
TaskingLock.Lock(__FUNCTION__);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Thread->Parent = Parent;
|
Thread->Parent = Parent;
|
||||||
|
|
||||||
@ -395,13 +489,17 @@ namespace Tasking
|
|||||||
strcpy(Thread->Name, Parent->Name);
|
strcpy(Thread->Name, Parent->Name);
|
||||||
Thread->EntryPoint = EntryPoint;
|
Thread->EntryPoint = EntryPoint;
|
||||||
Thread->Offset = Offset;
|
Thread->Offset = Offset;
|
||||||
Thread->ExitCode = 0xdeadbeef;
|
Thread->Argument0 = Argument0;
|
||||||
|
Thread->Argument1 = Argument1;
|
||||||
|
Thread->ExitCode = 0xdead;
|
||||||
Thread->Stack = (void *)((uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE);
|
Thread->Stack = (void *)((uint64_t)KernelAllocator.RequestPages(TO_PAGES(STACK_SIZE)) + STACK_SIZE);
|
||||||
Thread->Status = TaskStatus::Ready;
|
Thread->Status = TaskStatus::Ready;
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
memset(&Thread->Registers, 0, sizeof(CPU::x64::TrapFrame)); // Just in case
|
memset(&Thread->Registers, 0, sizeof(CPU::x64::TrapFrame)); // Just in case
|
||||||
Thread->Registers.rip = (EntryPoint + Offset);
|
Thread->Registers.rip = (EntryPoint + Offset);
|
||||||
|
Thread->Registers.rdi = Argument0;
|
||||||
|
Thread->Registers.rsi = Argument1;
|
||||||
#elif defined(__i386__)
|
#elif defined(__i386__)
|
||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
#endif
|
#endif
|
||||||
@ -462,11 +560,8 @@ namespace Tasking
|
|||||||
Thread->Security.TrustLevel = Parent->Security.TrustLevel;
|
Thread->Security.TrustLevel = Parent->Security.TrustLevel;
|
||||||
// Thread->Security.UniqueToken = SecurityManager.CreateToken();
|
// Thread->Security.UniqueToken = SecurityManager.CreateToken();
|
||||||
|
|
||||||
Thread->Info.SpawnTime = 0;
|
Thread->Info = {};
|
||||||
Thread->Info.UsedTime = 0;
|
Thread->Info.SpawnTime = CPU::Counter();
|
||||||
Thread->Info.OldUsedTime = 0;
|
|
||||||
Thread->Info.OldSystemTime = 0;
|
|
||||||
Thread->Info.CurrentSystemTime = 0;
|
|
||||||
Thread->Info.Year = 0;
|
Thread->Info.Year = 0;
|
||||||
Thread->Info.Month = 0;
|
Thread->Info.Month = 0;
|
||||||
Thread->Info.Day = 0;
|
Thread->Info.Day = 0;
|
||||||
@ -476,13 +571,15 @@ namespace Tasking
|
|||||||
for (int i = 0; i < MAX_CPU; i++)
|
for (int i = 0; i < MAX_CPU; i++)
|
||||||
{
|
{
|
||||||
Thread->Info.Usage[i] = 0;
|
Thread->Info.Usage[i] = 0;
|
||||||
Thread->Info.Affinity[i] = 0;
|
Thread->Info.Affinity[i] = true;
|
||||||
}
|
}
|
||||||
Thread->Info.Priority = 0;
|
Thread->Info.Priority = 10;
|
||||||
Thread->Info.Architecture = Architecture;
|
Thread->Info.Architecture = Architecture;
|
||||||
Thread->Info.Compatibility = Compatibility;
|
Thread->Info.Compatibility = Compatibility;
|
||||||
|
|
||||||
debug("Created thread %d(%s) in process %d(%s)", Thread->ID, Thread->Name, Thread->Parent->ID, Thread->Parent->Name);
|
debug("Created thread \"%s\"(%d) in process \"%s\"(%d)",
|
||||||
|
Thread->Name, Thread->ID,
|
||||||
|
Thread->Parent->Name, Thread->Parent->ID);
|
||||||
|
|
||||||
Parent->Threads.push_back(Thread);
|
Parent->Threads.push_back(Thread);
|
||||||
return Thread;
|
return Thread;
|
||||||
@ -497,10 +594,14 @@ namespace Tasking
|
|||||||
Process->ID = this->NextPID++;
|
Process->ID = this->NextPID++;
|
||||||
strcpy(Process->Name, Name);
|
strcpy(Process->Name, Name);
|
||||||
if (Parent == nullptr)
|
if (Parent == nullptr)
|
||||||
|
{
|
||||||
|
TaskingLock.Unlock();
|
||||||
Process->Parent = this->GetCurrentProcess();
|
Process->Parent = this->GetCurrentProcess();
|
||||||
|
TaskingLock.Lock(__FUNCTION__);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
Process->Parent = Parent;
|
Process->Parent = Parent;
|
||||||
Process->ExitCode = 0xdeadbeef;
|
Process->ExitCode = 0xdead;
|
||||||
Process->Status = TaskStatus::Ready;
|
Process->Status = TaskStatus::Ready;
|
||||||
|
|
||||||
Process->Security.TrustLevel = TrustLevel;
|
Process->Security.TrustLevel = TrustLevel;
|
||||||
@ -548,11 +649,8 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Process->Info.SpawnTime = 0;
|
Process->Info = {};
|
||||||
Process->Info.UsedTime = 0;
|
Process->Info.SpawnTime = CPU::Counter();
|
||||||
Process->Info.OldUsedTime = 0;
|
|
||||||
Process->Info.OldSystemTime = 0;
|
|
||||||
Process->Info.CurrentSystemTime = 0;
|
|
||||||
Process->Info.Year = 0;
|
Process->Info.Year = 0;
|
||||||
Process->Info.Month = 0;
|
Process->Info.Month = 0;
|
||||||
Process->Info.Day = 0;
|
Process->Info.Day = 0;
|
||||||
@ -562,11 +660,14 @@ namespace Tasking
|
|||||||
for (int i = 0; i < MAX_CPU; i++)
|
for (int i = 0; i < MAX_CPU; i++)
|
||||||
{
|
{
|
||||||
Process->Info.Usage[i] = 0;
|
Process->Info.Usage[i] = 0;
|
||||||
Process->Info.Affinity[i] = 0;
|
Process->Info.Affinity[i] = true;
|
||||||
}
|
}
|
||||||
Process->Info.Priority = 0;
|
Process->Info.Priority = 10;
|
||||||
|
|
||||||
debug("Created process %d(%s) in process %d(%s)", Process->ID, Process->Name, Parent ? Process->Parent->ID : 0, Parent ? Process->Parent->Name : "None");
|
debug("Created process \"%s\"(%d) in process \"%s\"(%d)",
|
||||||
|
Process->Name, Process->ID,
|
||||||
|
Parent ? Process->Parent->Name : "None",
|
||||||
|
Parent ? Process->Parent->ID : 0);
|
||||||
|
|
||||||
if (Parent)
|
if (Parent)
|
||||||
Parent->Children.push_back(Process);
|
Parent->Children.push_back(Process);
|
||||||
@ -594,9 +695,8 @@ namespace Tasking
|
|||||||
#elif defined(__aarch64__)
|
#elif defined(__aarch64__)
|
||||||
TaskArchitecture Arch = TaskArchitecture::ARM64;
|
TaskArchitecture Arch = TaskArchitecture::ARM64;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
PCB *kproc = CreateProcess(nullptr, "Kernel", TaskTrustLevel::Kernel);
|
PCB *kproc = CreateProcess(nullptr, "Kernel", TaskTrustLevel::Kernel);
|
||||||
TCB *kthrd = CreateThread(kproc, EntryPoint, 0, Arch);
|
TCB *kthrd = CreateThread(kproc, EntryPoint, 0, 0, 0, Arch);
|
||||||
kthrd->Rename("Main Thread");
|
kthrd->Rename("Main Thread");
|
||||||
debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name);
|
debug("Created Kernel Process: %s and Thread: %s", kproc->Name, kthrd->Name);
|
||||||
TaskingLock.Lock(__FUNCTION__);
|
TaskingLock.Lock(__FUNCTION__);
|
||||||
@ -624,6 +724,10 @@ namespace Tasking
|
|||||||
#endif
|
#endif
|
||||||
TaskingLock.Unlock();
|
TaskingLock.Unlock();
|
||||||
this->IPCManager = new InterProcessCommunication::IPC;
|
this->IPCManager = new InterProcessCommunication::IPC;
|
||||||
|
IdleProcess = CreateProcess(nullptr, (char *)"Idle", TaskTrustLevel::Idle);
|
||||||
|
IdleThread = CreateThread(IdleProcess, reinterpret_cast<uint64_t>(IdleProcessLoop));
|
||||||
|
IdleThread->Rename("Idle Thread");
|
||||||
|
IdleThread->SetPriority(1);
|
||||||
TaskingLock.Lock(__FUNCTION__);
|
TaskingLock.Lock(__FUNCTION__);
|
||||||
debug("Tasking Started");
|
debug("Tasking Started");
|
||||||
}
|
}
|
||||||
|
@ -8,10 +8,12 @@
|
|||||||
#include <memory.hpp>
|
#include <memory.hpp>
|
||||||
#include <hashmap.hpp>
|
#include <hashmap.hpp>
|
||||||
#include <ipc.hpp>
|
#include <ipc.hpp>
|
||||||
|
#include <debug.h>
|
||||||
|
|
||||||
namespace Tasking
|
namespace Tasking
|
||||||
{
|
{
|
||||||
typedef unsigned long IP;
|
typedef unsigned long IP;
|
||||||
|
typedef unsigned long Arg;
|
||||||
typedef unsigned long IPOffset;
|
typedef unsigned long IPOffset;
|
||||||
typedef unsigned long UPID;
|
typedef unsigned long UPID;
|
||||||
typedef unsigned long UTID;
|
typedef unsigned long UTID;
|
||||||
@ -62,8 +64,10 @@ namespace Tasking
|
|||||||
|
|
||||||
struct TaskInfo
|
struct TaskInfo
|
||||||
{
|
{
|
||||||
uint64_t SpawnTime = 0, UsedTime = 0, OldUsedTime = 0;
|
uint64_t SpawnTime = 0;
|
||||||
uint64_t OldSystemTime = 0, CurrentSystemTime = 0;
|
uint64_t OldUserTime = 0, CurrentUserTime = 0;
|
||||||
|
uint64_t OldKernelTime = 0, CurrentKernelTime = 0;
|
||||||
|
uint64_t KernelTime = 0, UserTime = 0;
|
||||||
uint64_t Year, Month, Day, Hour, Minute, Second;
|
uint64_t Year, Month, Day, Hour, Minute, Second;
|
||||||
uint64_t Usage[256]; // MAX_CPU
|
uint64_t Usage[256]; // MAX_CPU
|
||||||
bool Affinity[256]; // MAX_CPU
|
bool Affinity[256]; // MAX_CPU
|
||||||
@ -79,6 +83,8 @@ namespace Tasking
|
|||||||
struct PCB *Parent;
|
struct PCB *Parent;
|
||||||
IP EntryPoint;
|
IP EntryPoint;
|
||||||
IPOffset Offset;
|
IPOffset Offset;
|
||||||
|
Arg Argument0;
|
||||||
|
Arg Argument1;
|
||||||
int ExitCode;
|
int ExitCode;
|
||||||
void *Stack;
|
void *Stack;
|
||||||
TaskStatus Status;
|
TaskStatus Status;
|
||||||
@ -95,6 +101,7 @@ namespace Tasking
|
|||||||
|
|
||||||
void Rename(const char *name)
|
void Rename(const char *name)
|
||||||
{
|
{
|
||||||
|
trace("Renaming thread %s to %s", Name, name);
|
||||||
for (int i = 0; i < 256; i++)
|
for (int i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
Name[i] = name[i];
|
Name[i] = name[i];
|
||||||
@ -105,6 +112,7 @@ namespace Tasking
|
|||||||
|
|
||||||
void SetPriority(int priority)
|
void SetPriority(int priority)
|
||||||
{
|
{
|
||||||
|
trace("Setting priority of thread %s to %d", Name, priority);
|
||||||
Info.Priority = priority;
|
Info.Priority = priority;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -174,6 +182,11 @@ namespace Tasking
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void RemoveThread(TCB *tcb);
|
||||||
|
void RemoveProcess(PCB *pcb);
|
||||||
|
|
||||||
|
void UpdateInfo(TaskInfo *Info, int Core);
|
||||||
|
|
||||||
bool FindNewProcess(void *CPUDataPointer);
|
bool FindNewProcess(void *CPUDataPointer);
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
@ -185,6 +198,8 @@ namespace Tasking
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
long GetUsage(int Core) { return 100 - IdleProcess->Info.Usage[Core]; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Get the Current Process object
|
* @brief Get the Current Process object
|
||||||
* @return PCB*
|
* @return PCB*
|
||||||
@ -197,12 +212,20 @@ namespace Tasking
|
|||||||
*/
|
*/
|
||||||
TCB *GetCurrentThread();
|
TCB *GetCurrentThread();
|
||||||
|
|
||||||
|
/** @brief Wait for process to terminate */
|
||||||
|
void WaitForProcess(PCB *pcb);
|
||||||
|
|
||||||
|
/** @brief Wait for thread to terminate */
|
||||||
|
void WaitForThread(TCB *tcb);
|
||||||
|
|
||||||
PCB *CreateProcess(PCB *Parent,
|
PCB *CreateProcess(PCB *Parent,
|
||||||
const char *Name,
|
const char *Name,
|
||||||
TaskTrustLevel TrustLevel);
|
TaskTrustLevel TrustLevel);
|
||||||
|
|
||||||
TCB *CreateThread(PCB *Parent,
|
TCB *CreateThread(PCB *Parent,
|
||||||
IP EntryPoint,
|
IP EntryPoint,
|
||||||
|
Arg Argument0 = 0,
|
||||||
|
Arg Argument1 = 0,
|
||||||
IPOffset Offset = 0,
|
IPOffset Offset = 0,
|
||||||
TaskArchitecture Architecture = TaskArchitecture::x64,
|
TaskArchitecture Architecture = TaskArchitecture::x64,
|
||||||
TaskCompatibility Compatibility = TaskCompatibility::Native);
|
TaskCompatibility Compatibility = TaskCompatibility::Native);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user