mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-29 07:47:59 +00:00
Add UserTime and KernelTime tracker
This commit is contained in:
parent
03b667f5c0
commit
299c919d1d
46
Kernel.cpp
46
Kernel.cpp
@ -81,6 +81,7 @@ LockClass mExtTrkLock;
|
|||||||
* - [?] Somewhere in the kernel, the memory is wrongly freed or memcpy/memset.
|
* - [?] Somewhere in the kernel, the memory is wrongly freed or memcpy/memset.
|
||||||
* - [ ] GlobalDescriptorTable::SetKernelStack() is not working properly.
|
* - [ ] GlobalDescriptorTable::SetKernelStack() is not working properly.
|
||||||
* - [ ] Sometimes while the kernel is inside BeforeShutdown(), we end up in a deadlock.
|
* - [ ] Sometimes while the kernel is inside BeforeShutdown(), we end up in a deadlock.
|
||||||
|
* - [ ] CPU usage is not working properly.
|
||||||
*
|
*
|
||||||
* CREDITS AND REFERENCES:
|
* CREDITS AND REFERENCES:
|
||||||
* - General:
|
* - General:
|
||||||
@ -200,8 +201,6 @@ Time::time *TimeManager = nullptr;
|
|||||||
VirtualFileSystem::Virtual *vfs = nullptr;
|
VirtualFileSystem::Virtual *vfs = nullptr;
|
||||||
VirtualFileSystem::Virtual *bootanim_vfs = nullptr;
|
VirtualFileSystem::Virtual *bootanim_vfs = nullptr;
|
||||||
|
|
||||||
Time::Clock BootClock;
|
|
||||||
|
|
||||||
KernelConfig Config = {
|
KernelConfig Config = {
|
||||||
.AllocatorType = Memory::MemoryAllocatorType::XallocV1,
|
.AllocatorType = Memory::MemoryAllocatorType::XallocV1,
|
||||||
.SchedulerType = 1,
|
.SchedulerType = 1,
|
||||||
@ -254,18 +253,23 @@ EXTERNC void KPrint(const char *Format, ...)
|
|||||||
|
|
||||||
EXTERNC NIF void Main(BootInfo *Info)
|
EXTERNC NIF void Main(BootInfo *Info)
|
||||||
{
|
{
|
||||||
BootClock = Time::ReadClock();
|
|
||||||
memcpy(&bInfo, Info, sizeof(BootInfo));
|
memcpy(&bInfo, Info, sizeof(BootInfo));
|
||||||
debug("BootInfo structure is at %p", bInfo);
|
debug("BootInfo structure is at %p", bInfo);
|
||||||
|
|
||||||
Display = new Video::Display(bInfo.Framebuffer[0]);
|
Display = new Video::Display(bInfo.Framebuffer[0]);
|
||||||
KPrint("%s - %s [\e058C19%s\eFFFFFF]", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT);
|
KPrint("%s - %s [\e058C19%s\eFFFFFF]", KERNEL_NAME, KERNEL_VERSION, GIT_COMMIT_SHORT);
|
||||||
/**************************************************************************************/
|
|
||||||
KPrint("CPU: \e058C19%s \e8822AA%s \e8888FF%s", CPU::Hypervisor(), CPU::Vendor(), CPU::Name());
|
KPrint("CPU: \e058C19%s \e8822AA%s \e8888FF%s", CPU::Hypervisor(), CPU::Vendor(), CPU::Name());
|
||||||
|
if (DebuggerIsAttached)
|
||||||
|
KPrint("\eFFA500Kernel debugger detected.");
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
|
||||||
KPrint("Initializing GDT and IDT");
|
KPrint("Initializing GDT and IDT");
|
||||||
Interrupts::Initialize(0);
|
Interrupts::Initialize(0);
|
||||||
|
|
||||||
|
KPrint("Loading Kernel Symbols");
|
||||||
|
KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase);
|
||||||
|
|
||||||
KPrint("Reading Kernel Parameters");
|
KPrint("Reading Kernel Parameters");
|
||||||
ParseConfig((char *)bInfo.Kernel.CommandLine, &Config);
|
ParseConfig((char *)bInfo.Kernel.CommandLine, &Config);
|
||||||
|
|
||||||
@ -286,15 +290,23 @@ EXTERNC NIF void Main(BootInfo *Info)
|
|||||||
KPrint("Initializing CPU Features");
|
KPrint("Initializing CPU Features");
|
||||||
CPU::InitializeFeatures(0);
|
CPU::InitializeFeatures(0);
|
||||||
|
|
||||||
if (DebuggerIsAttached)
|
|
||||||
KPrint("\eFFA500Kernel debugger detected.");
|
|
||||||
|
|
||||||
KPrint("Loading Kernel Symbols");
|
|
||||||
KernelSymbolTable = new SymbolResolver::Symbols((uintptr_t)Info->Kernel.FileBase);
|
|
||||||
|
|
||||||
KPrint("Initializing Power Manager");
|
KPrint("Initializing Power Manager");
|
||||||
PowerManager = new Power::Power;
|
PowerManager = new Power::Power;
|
||||||
|
|
||||||
|
#if defined(a64)
|
||||||
|
PowerManager->InitDSDT();
|
||||||
|
#elif defined(a32)
|
||||||
|
// FIXME: Add ACPI support for i386
|
||||||
|
#elif defined(aa64)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
KPrint("Enabling Interrupts on Bootstrap Processor");
|
||||||
|
Interrupts::Enable(0);
|
||||||
|
|
||||||
|
KPrint("Initializing Timers");
|
||||||
|
TimeManager = new Time::time;
|
||||||
|
TimeManager->FindTimers(PowerManager->GetACPI());
|
||||||
|
|
||||||
KPrint("Initializing PCI Manager");
|
KPrint("Initializing PCI Manager");
|
||||||
PCIManager = new PCI::PCI;
|
PCIManager = new PCI::PCI;
|
||||||
|
|
||||||
@ -308,20 +320,6 @@ EXTERNC NIF void Main(BootInfo *Info)
|
|||||||
PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF));
|
PCI::Descriptors::GetProgIFName(Device->Class, Device->Subclass, Device->ProgIF));
|
||||||
}
|
}
|
||||||
|
|
||||||
KPrint("Enabling Interrupts on Bootstrap Processor");
|
|
||||||
Interrupts::Enable(0);
|
|
||||||
|
|
||||||
#if defined(a64)
|
|
||||||
PowerManager->InitDSDT();
|
|
||||||
#elif defined(a32)
|
|
||||||
// FIXME: Add ACPI support for i386
|
|
||||||
#elif defined(aa64)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
KPrint("Initializing Timers");
|
|
||||||
TimeManager = new Time::time;
|
|
||||||
TimeManager->FindTimers(PowerManager->GetACPI());
|
|
||||||
|
|
||||||
KPrint("Initializing Bootstrap Processor Timer");
|
KPrint("Initializing Bootstrap Processor Timer");
|
||||||
Interrupts::InitializeTimer(0);
|
Interrupts::InitializeTimer(0);
|
||||||
|
|
||||||
|
@ -92,16 +92,53 @@ const char *SuccessSourceStrings[] = {
|
|||||||
"SchedulerSearchProcessThread",
|
"SchedulerSearchProcessThread",
|
||||||
};
|
};
|
||||||
|
|
||||||
void TaskMgr()
|
void TaskMgr_Dummy100Usage()
|
||||||
{
|
{
|
||||||
|
while (1)
|
||||||
|
;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskMgr_Dummy0Usage()
|
||||||
|
{
|
||||||
|
while (1)
|
||||||
|
TaskManager->Sleep(1000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t GetUsage(uint64_t OldSystemTime, Tasking::TaskInfo *Info)
|
||||||
|
{
|
||||||
|
/* https://github.com/reactos/reactos/blob/560671a784c1e0e0aa7590df5e0598c1e2f41f5a/base/applications/taskmgr/perfdata.c#L347 */
|
||||||
|
if (Info->OldKernelTime || Info->OldUserTime)
|
||||||
|
{
|
||||||
|
uint64_t SystemTime = TimeManager->GetCounter() - OldSystemTime;
|
||||||
|
uint64_t CurrentTime = Info->KernelTime + Info->UserTime;
|
||||||
|
uint64_t OldTime = Info->OldKernelTime + Info->OldUserTime;
|
||||||
|
uint64_t CpuUsage = (CurrentTime - OldTime) / SystemTime;
|
||||||
|
CpuUsage = CpuUsage * 100;
|
||||||
|
|
||||||
|
// debug("CurrentTime: %ld OldTime: %ld Time Diff: %ld Usage: %ld%%",
|
||||||
|
// CurrentTime, OldTime, SystemTime, CpuUsage);
|
||||||
|
|
||||||
|
Info->OldKernelTime = Info->KernelTime;
|
||||||
|
Info->OldUserTime = Info->UserTime;
|
||||||
|
return CpuUsage;
|
||||||
|
}
|
||||||
|
Info->OldKernelTime = Info->KernelTime;
|
||||||
|
Info->OldUserTime = Info->UserTime;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TaskMgr()
|
||||||
|
{
|
||||||
|
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)TaskMgr_Dummy100Usage)->Rename("Dummy 100% Usage");
|
||||||
|
TaskManager->CreateThread(TaskManager->GetCurrentProcess(), (Tasking::IP)TaskMgr_Dummy0Usage)->Rename("Dummy 0% Usage");
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
CPU::Interrupts(CPU::Disable);
|
|
||||||
static int sanity = 0;
|
static int sanity = 0;
|
||||||
Video::ScreenBuffer *sb = Display->GetBuffer(0);
|
Video::ScreenBuffer *sb = Display->GetBuffer(0);
|
||||||
for (short i = 0; i < 340; i++)
|
for (short i = 0; i < 500; i++)
|
||||||
{
|
{
|
||||||
for (short j = 0; j < 200; j++)
|
for (short j = 0; j < 500; j++)
|
||||||
{
|
{
|
||||||
uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8));
|
uint32_t *Pixel = (uint32_t *)((uintptr_t)sb->Buffer + (j * sb->Width + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8));
|
||||||
*Pixel = 0x222222;
|
*Pixel = 0x222222;
|
||||||
@ -112,19 +149,23 @@ void TaskMgr()
|
|||||||
Display->GetBufferCursor(0, &tmpX, &tmpY);
|
Display->GetBufferCursor(0, &tmpX, &tmpY);
|
||||||
Display->SetBufferCursor(0, 0, 0);
|
Display->SetBufferCursor(0, 0, 0);
|
||||||
printf("\eF02C21Task Manager\n");
|
printf("\eF02C21Task Manager\n");
|
||||||
|
static uint64_t OldSystemTime = 0;
|
||||||
foreach (auto Proc in TaskManager->GetProcessList())
|
foreach (auto Proc in TaskManager->GetProcessList())
|
||||||
{
|
{
|
||||||
int Status = Proc->Status;
|
int Status = Proc->Status;
|
||||||
printf("\e%s-> \eAABBCC%s \e00AAAA%s\n",
|
uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info);
|
||||||
Statuses[Status], Proc->Name, StatusesSign[Status]);
|
printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n",
|
||||||
|
Statuses[Status], Proc->Name, StatusesSign[Status], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime);
|
||||||
|
|
||||||
foreach (auto Thd in Proc->Threads)
|
foreach (auto Thd in Proc->Threads)
|
||||||
{
|
{
|
||||||
Status = Thd->Status;
|
Status = Thd->Status;
|
||||||
printf(" \e%s-> \eAABBCC%s \e00AAAA%s\n\eAABBCC",
|
uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info);
|
||||||
Statuses[Status], Thd->Name, StatusesSign[Status]);
|
printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n\eAABBCC",
|
||||||
|
Statuses[Status], Thd->Name, StatusesSign[Status], ThreadCpuUsage, Thd->Info.KernelTime, Thd->Info.UserTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
OldSystemTime = TimeManager->GetCounter();
|
||||||
#if defined(a64)
|
#if defined(a64)
|
||||||
register uintptr_t CurrentStackAddress asm("rsp");
|
register uintptr_t CurrentStackAddress asm("rsp");
|
||||||
#elif defined(a32)
|
#elif defined(a32)
|
||||||
@ -138,7 +179,8 @@ void TaskMgr()
|
|||||||
Display->SetBufferCursor(0, tmpX, tmpY);
|
Display->SetBufferCursor(0, tmpX, tmpY);
|
||||||
if (!Config.BootAnimation)
|
if (!Config.BootAnimation)
|
||||||
Display->SetBuffer(0);
|
Display->SetBuffer(0);
|
||||||
CPU::Interrupts(CPU::Enable);
|
|
||||||
|
TaskManager->Sleep(100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -315,7 +357,7 @@ void KernelMainThread()
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
/* TODO: This should not be enabled because it may cause a deadlock. Not sure where or how. */
|
/* TODO: This should not be enabled because it may cause a deadlock. Not sure where or how. */
|
||||||
// Tasking::PCB *tskMgr = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), "Debug Task Manager", Tasking::TaskTrustLevel::Kernel);
|
// Tasking::PCB *tskMgr = TaskManager->CreateProcess(TaskManager->GetCurrentProcess(), "Debug Task Manager", Tasking::TaskTrustLevel::Kernel);
|
||||||
// TaskManager->CreateThread(tskMgr, (Tasking::IP)TaskMgr)->SetPriority(Tasking::High);
|
// TaskManager->CreateThread(tskMgr, (Tasking::IP)TaskMgr)->SetPriority(Tasking::Low);
|
||||||
|
|
||||||
TreeFS(vfs->GetRootNode(), 0);
|
TreeFS(vfs->GetRootNode(), 0);
|
||||||
#endif
|
#endif
|
||||||
|
@ -28,13 +28,26 @@ extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
|
|||||||
CPU::Interrupts(CPU::Enable);
|
CPU::Interrupts(CPU::Enable);
|
||||||
SmartLock(SyscallsLock); /* TODO: This should be replaced or moved somewhere else. */
|
SmartLock(SyscallsLock); /* TODO: This should be replaced or moved somewhere else. */
|
||||||
|
|
||||||
#if defined(a64)
|
Tasking::TaskInfo *Ptinfo = &TaskManager->GetCurrentProcess()->Info;
|
||||||
switch (TaskManager->GetCurrentThread()->Info.Compatibility)
|
Tasking::TaskInfo *Ttinfo = &TaskManager->GetCurrentThread()->Info;
|
||||||
|
uint64_t TempTimeCalc = TimeManager->GetCounter();
|
||||||
|
|
||||||
|
switch (Ttinfo->Compatibility)
|
||||||
{
|
{
|
||||||
case Tasking::TaskCompatibility::Native:
|
case Tasking::TaskCompatibility::Native:
|
||||||
return HandleNativeSyscalls(Frame);
|
{
|
||||||
|
uintptr_t ret = HandleNativeSyscalls(Frame);
|
||||||
|
Ptinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc;
|
||||||
|
Ttinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case Tasking::TaskCompatibility::Linux:
|
case Tasking::TaskCompatibility::Linux:
|
||||||
return HandleLinuxSyscalls(Frame);
|
{
|
||||||
|
uintptr_t ret = HandleLinuxSyscalls(Frame);
|
||||||
|
Ptinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc;
|
||||||
|
Ttinfo->KernelTime += TimeManager->GetCounter() - TempTimeCalc;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
case Tasking::TaskCompatibility::Windows:
|
case Tasking::TaskCompatibility::Windows:
|
||||||
{
|
{
|
||||||
error("Windows compatibility not implemented yet.");
|
error("Windows compatibility not implemented yet.");
|
||||||
@ -47,10 +60,5 @@ extern "C" uintptr_t SystemCallsHandler(SyscallsFrame *Frame)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#elif defined(a32)
|
assert(false); /* Should never reach here. */
|
||||||
fixme("System call %lld", Frame->eax);
|
|
||||||
#elif defined(aa64)
|
|
||||||
fixme("System call");
|
|
||||||
#endif
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
@ -476,8 +476,9 @@ namespace Tasking
|
|||||||
warn("Scheduler stopped.");
|
warn("Scheduler stopped.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bool ProcessNotChanged = false;
|
||||||
CPU::x64::writecr3({.raw = (uint64_t)KernelPageTable}); /* Restore kernel page table for safety reasons. */
|
CPU::x64::writecr3({.raw = (uint64_t)KernelPageTable}); /* Restore kernel page table for safety reasons. */
|
||||||
uint64_t SchedTmpTicks = CPU::Counter();
|
uint64_t SchedTmpTicks = TimeManager->GetCounter();
|
||||||
this->LastTaskTicks.store(SchedTmpTicks - this->SchedulerTicks.load());
|
this->LastTaskTicks.store(SchedTmpTicks - this->SchedulerTicks.load());
|
||||||
CPUData *CurrentCPU = GetCurrentCPU();
|
CPUData *CurrentCPU = GetCurrentCPU();
|
||||||
schedbg("Scheduler called on CPU %d.", CurrentCPU->ID);
|
schedbg("Scheduler called on CPU %d.", CurrentCPU->ID);
|
||||||
@ -511,6 +512,7 @@ namespace Tasking
|
|||||||
if (unlikely(InvalidPCB(CurrentCPU->CurrentProcess.load()) || InvalidTCB(CurrentCPU->CurrentThread.load())))
|
if (unlikely(InvalidPCB(CurrentCPU->CurrentProcess.load()) || InvalidTCB(CurrentCPU->CurrentThread.load())))
|
||||||
{
|
{
|
||||||
schedbg("Invalid process or thread. Finding a new one.");
|
schedbg("Invalid process or thread. Finding a new one.");
|
||||||
|
ProcessNotChanged = true;
|
||||||
if (this->FindNewProcess(CurrentCPU))
|
if (this->FindNewProcess(CurrentCPU))
|
||||||
goto Success;
|
goto Success;
|
||||||
else
|
else
|
||||||
@ -539,6 +541,7 @@ namespace Tasking
|
|||||||
#ifdef ON_SCREEN_SCHEDULER_TASK_MANAGER
|
#ifdef ON_SCREEN_SCHEDULER_TASK_MANAGER
|
||||||
SuccessSource = 1;
|
SuccessSource = 1;
|
||||||
#endif
|
#endif
|
||||||
|
ProcessNotChanged = true;
|
||||||
goto Success;
|
goto Success;
|
||||||
}
|
}
|
||||||
schedbg("Passed GetNextAvailableThread");
|
schedbg("Passed GetNextAvailableThread");
|
||||||
@ -567,22 +570,24 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* [this]->RealEnd */
|
|
||||||
warn("Unwanted reach!");
|
warn("Unwanted reach!");
|
||||||
TaskingScheduler_OneShot(100);
|
TaskingScheduler_OneShot(100);
|
||||||
goto RealEnd;
|
goto End;
|
||||||
|
|
||||||
/* Idle-->Success */
|
|
||||||
Idle:
|
Idle:
|
||||||
|
ProcessNotChanged = true;
|
||||||
CurrentCPU->CurrentProcess = IdleProcess;
|
CurrentCPU->CurrentProcess = IdleProcess;
|
||||||
CurrentCPU->CurrentThread = IdleThread;
|
CurrentCPU->CurrentThread = IdleThread;
|
||||||
|
|
||||||
/* Success-->End */
|
|
||||||
Success:
|
Success:
|
||||||
schedbg("Process \"%s\"(%d) Thread \"%s\"(%d) is now running on CPU %d",
|
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->ID);
|
CurrentCPU->CurrentThread->Name, CurrentCPU->CurrentThread->ID, CurrentCPU->ID);
|
||||||
|
|
||||||
|
if (!ProcessNotChanged)
|
||||||
|
UpdateUsage(&CurrentCPU->CurrentProcess->Info, &CurrentCPU->CurrentProcess->Security, CurrentCPU->ID);
|
||||||
|
UpdateUsage(&CurrentCPU->CurrentThread->Info, &CurrentCPU->CurrentThread->Security, CurrentCPU->ID);
|
||||||
|
|
||||||
CurrentCPU->CurrentProcess->Status = TaskStatus::Running;
|
CurrentCPU->CurrentProcess->Status = TaskStatus::Running;
|
||||||
CurrentCPU->CurrentThread->Status = TaskStatus::Running;
|
CurrentCPU->CurrentThread->Status = TaskStatus::Running;
|
||||||
|
|
||||||
@ -621,21 +626,9 @@ namespace Tasking
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* End-->RealEnd */
|
if (!ProcessNotChanged)
|
||||||
// End:
|
(&CurrentCPU->CurrentProcess->Info)->LastUpdateTime = TimeManager->GetCounter();
|
||||||
/* TODO: This is not accurate. */
|
(&CurrentCPU->CurrentThread->Info)->LastUpdateTime = TimeManager->GetCounter();
|
||||||
if (CurrentCPU->CurrentProcess->Security.TrustLevel == TaskTrustLevel::User)
|
|
||||||
UpdateUserTime(&CurrentCPU->CurrentProcess->Info);
|
|
||||||
else
|
|
||||||
UpdateKernelTime(&CurrentCPU->CurrentProcess->Info);
|
|
||||||
|
|
||||||
if (CurrentCPU->CurrentThread->Security.TrustLevel == TaskTrustLevel::User)
|
|
||||||
UpdateUserTime(&CurrentCPU->CurrentThread->Info);
|
|
||||||
else
|
|
||||||
UpdateKernelTime(&CurrentCPU->CurrentThread->Info);
|
|
||||||
|
|
||||||
UpdateUsage(&CurrentCPU->CurrentProcess->Info, CurrentCPU->ID);
|
|
||||||
UpdateUsage(&CurrentCPU->CurrentThread->Info, CurrentCPU->ID);
|
|
||||||
TaskingScheduler_OneShot(CurrentCPU->CurrentThread->Info.Priority);
|
TaskingScheduler_OneShot(CurrentCPU->CurrentThread->Info.Priority);
|
||||||
|
|
||||||
if (CurrentCPU->CurrentThread->Security.IsDebugEnabled && CurrentCPU->CurrentThread->Security.IsKernelDebugEnabled)
|
if (CurrentCPU->CurrentThread->Security.IsDebugEnabled && CurrentCPU->CurrentThread->Security.IsKernelDebugEnabled)
|
||||||
@ -666,9 +659,8 @@ namespace Tasking
|
|||||||
Frame->rip, Frame->rflags, Frame->InterruptNumber, Frame->ErrorCode);
|
Frame->rip, Frame->rflags, Frame->InterruptNumber, Frame->ErrorCode);
|
||||||
schedbg("================================================================");
|
schedbg("================================================================");
|
||||||
|
|
||||||
/* RealEnd->[Function Exit] */
|
End:
|
||||||
RealEnd:
|
this->SchedulerTicks.store(TimeManager->GetCounter() - SchedTmpTicks);
|
||||||
this->SchedulerTicks.store(CPU::Counter() - SchedTmpTicks);
|
|
||||||
__sync; /* TODO: Is this really needed? */
|
__sync; /* TODO: Is this really needed? */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,40 +172,16 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SafeFunction NIF void Task::UpdateUserTime(TaskInfo *Info)
|
SafeFunction NIF void Task::UpdateUsage(TaskInfo *Info, TaskSecurity *Security, int Core)
|
||||||
{
|
{
|
||||||
// TODO
|
uint64_t CurrentTime = TimeManager->GetCounter();
|
||||||
Info->UserTime++;
|
uint64_t TimePassed = CurrentTime - Info->LastUpdateTime;
|
||||||
}
|
// Info->LastUpdateTime = CurrentTime;
|
||||||
|
|
||||||
SafeFunction NIF void Task::UpdateKernelTime(TaskInfo *Info)
|
if (Security->TrustLevel == TaskTrustLevel::User)
|
||||||
{
|
Info->UserTime += TimePassed;
|
||||||
// TODO
|
else
|
||||||
Info->KernelTime++;
|
Info->KernelTime += TimePassed;
|
||||||
}
|
|
||||||
|
|
||||||
SafeFunction NIF void Task::UpdateUsage(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->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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadDoExit()
|
void ThreadDoExit()
|
||||||
@ -635,7 +611,7 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
|
|
||||||
Thread->Info = {};
|
Thread->Info = {};
|
||||||
Thread->Info.SpawnTime = CPU::Counter();
|
Thread->Info.SpawnTime = TimeManager->GetCounter();
|
||||||
Thread->Info.Year = 0;
|
Thread->Info.Year = 0;
|
||||||
Thread->Info.Month = 0;
|
Thread->Info.Month = 0;
|
||||||
Thread->Info.Day = 0;
|
Thread->Info.Day = 0;
|
||||||
@ -644,7 +620,6 @@ namespace Tasking
|
|||||||
Thread->Info.Second = 0;
|
Thread->Info.Second = 0;
|
||||||
for (int i = 0; i < MAX_CPU; i++)
|
for (int i = 0; i < MAX_CPU; i++)
|
||||||
{
|
{
|
||||||
Thread->Info.Usage[i] = 0;
|
|
||||||
Thread->Info.Affinity[i] = true;
|
Thread->Info.Affinity[i] = true;
|
||||||
}
|
}
|
||||||
Thread->Info.Priority = TaskPriority::Normal;
|
Thread->Info.Priority = TaskPriority::Normal;
|
||||||
@ -741,7 +716,7 @@ namespace Tasking
|
|||||||
}
|
}
|
||||||
|
|
||||||
Process->Info = {};
|
Process->Info = {};
|
||||||
Process->Info.SpawnTime = CPU::Counter();
|
Process->Info.SpawnTime = TimeManager->GetCounter();
|
||||||
Process->Info.Year = 0;
|
Process->Info.Year = 0;
|
||||||
Process->Info.Month = 0;
|
Process->Info.Month = 0;
|
||||||
Process->Info.Day = 0;
|
Process->Info.Day = 0;
|
||||||
@ -750,7 +725,6 @@ namespace Tasking
|
|||||||
Process->Info.Second = 0;
|
Process->Info.Second = 0;
|
||||||
for (int i = 0; i < MAX_CPU; i++)
|
for (int i = 0; i < MAX_CPU; i++)
|
||||||
{
|
{
|
||||||
Process->Info.Usage[i] = 0;
|
|
||||||
Process->Info.Affinity[i] = true;
|
Process->Info.Affinity[i] = true;
|
||||||
}
|
}
|
||||||
Process->Info.Priority = TaskPriority::Normal;
|
Process->Info.Priority = TaskPriority::Normal;
|
||||||
|
@ -95,13 +95,12 @@ namespace Tasking
|
|||||||
|
|
||||||
struct TaskInfo
|
struct TaskInfo
|
||||||
{
|
{
|
||||||
|
uint64_t OldUserTime = 0;
|
||||||
|
uint64_t OldKernelTime = 0;
|
||||||
|
|
||||||
uint64_t SleepUntil = 0;
|
uint64_t SleepUntil = 0;
|
||||||
uint64_t SpawnTime = 0;
|
uint64_t KernelTime = 0, UserTime = 0, SpawnTime = 0, LastUpdateTime = 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
|
|
||||||
bool Affinity[256]; // MAX_CPU
|
bool Affinity[256]; // MAX_CPU
|
||||||
TaskPriority Priority;
|
TaskPriority Priority;
|
||||||
TaskArchitecture Architecture;
|
TaskArchitecture Architecture;
|
||||||
@ -252,9 +251,7 @@ namespace Tasking
|
|||||||
void RemoveThread(TCB *tcb);
|
void RemoveThread(TCB *tcb);
|
||||||
void RemoveProcess(PCB *pcb);
|
void RemoveProcess(PCB *pcb);
|
||||||
|
|
||||||
void UpdateUserTime(TaskInfo *Info);
|
void UpdateUsage(TaskInfo *Info, TaskSecurity *Security, int Core);
|
||||||
void UpdateKernelTime(TaskInfo *Info);
|
|
||||||
void UpdateUsage(TaskInfo *Info, int Core);
|
|
||||||
|
|
||||||
bool FindNewProcess(void *CPUDataPointer);
|
bool FindNewProcess(void *CPUDataPointer);
|
||||||
bool GetNextAvailableThread(void *CPUDataPointer);
|
bool GetNextAvailableThread(void *CPUDataPointer);
|
||||||
@ -287,14 +284,6 @@ namespace Tasking
|
|||||||
void RevertProcessCreation(PCB *Process);
|
void RevertProcessCreation(PCB *Process);
|
||||||
void RevertThreadCreation(TCB *Thread);
|
void RevertThreadCreation(TCB *Thread);
|
||||||
|
|
||||||
long GetUsage(int Core)
|
|
||||||
{
|
|
||||||
if (IdleProcess)
|
|
||||||
return 100 - IdleProcess->Info.Usage[Core];
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void KillThread(TCB *tcb, int Code)
|
void KillThread(TCB *tcb, int Code)
|
||||||
{
|
{
|
||||||
tcb->Status = TaskStatus::Terminated;
|
tcb->Status = TaskStatus::Terminated;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user