/* This file is part of Fennix Kernel. Fennix Kernel is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Fennix Kernel is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Fennix Kernel. If not, see . */ #ifdef DEBUG #include "t.h" #include "../kernel.h" const char *Statuses[] = { "FF0000", /* Unknown */ "AAFF00", /* Ready */ "00AA00", /* Running */ "FFAA11", /* Sleeping */ "FFAA0F", /* Blocked */ "FFAA0F", /* Stopped */ "FFAA5F", /* Waiting */ "FF0088", /* Zombie */ "FF0000", /* Terminated */ "FF8800", /* Frozen */ }; const char *StatusesSign[] = { "Unknown", "Ready", "Run", "Sleep", "Block", "Stop", "Wait", "Core", "Zombie", "Terminated", "Frozen", }; const char *SuccessSourceStrings[] = { "Unknown", "GetNextAvailableThread", "GetNextAvailableProcess", "SchedulerSearchProcessThread", }; 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; } static int ShowTaskManager = 0; void TaskMgr() { thisThread->Rename("Debug Task Manager"); thisThread->SetPriority(Tasking::Idle); while (ShowTaskManager == 0) CPU::Pause(); thisThread->SetPriority(Tasking::High); TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy100Usage))->Rename("Dummy 100% Usage"); TaskManager->CreateThread(thisProcess, Tasking::IP(TaskMgr_Dummy0Usage))->Rename("Dummy 0% Usage"); while (true) { while (ShowTaskManager == 0) CPU::Pause(); static int sanity = 0; for (short i = 0; i < 1000; i++) { for (short j = 0; j < 500; j++) { Video::Pixel *p = (Video::Pixel *)((uintptr_t)Display->GetBuffer + (j * Display->GetWidth + i) * (bInfo.Framebuffer[0].BitsPerPixel / 8)); *p = {0xFF, 0x22, 0x22, 0x22}; } } uint32_t tmpX, tmpY; fixme("cursor 127-128; 179"); // Display->GetBufferCursor(&tmpX, &tmpY); // Display->SetBufferCursor(0, 0); printf("\eF02C21Task Manager\n"); static uint64_t OldSystemTime = 0; foreach (auto Proc in TaskManager->GetProcessList()) { if (!Proc) continue; int State = Proc->State.load(); uint64_t ProcessCpuUsage = GetUsage(OldSystemTime, &Proc->Info); #if defined(a64) printf("\e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld)\n", Statuses[State], Proc->Name, StatusesSign[State], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime); #elif defined(a32) printf("\e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld)\n", Statuses[State], Proc->Name, StatusesSign[State], ProcessCpuUsage, Proc->Info.KernelTime, Proc->Info.UserTime); #elif defined(aa64) #endif foreach (auto Thd in Proc->Threads) { if (!Thd) continue; State = Thd->State.load(); uint64_t ThreadCpuUsage = GetUsage(OldSystemTime, &Thd->Info); #if defined(a64) printf(" \e%s-> \eAABBCC%s \e00AAAA%s %ld%% (KT: %ld UT: %ld, IP: \e24FF2B%#lx \eEDFF24%s\e00AAAA)\n\eAABBCC", Statuses[State], Thd->Name, StatusesSign[State], ThreadCpuUsage, Thd->Info.KernelTime, Thd->Info.UserTime, Thd->Registers.rip, "unknown"); #elif defined(a32) printf(" \e%s-> \eAABBCC%s \e00AAAA%s %lld%% (KT: %lld UT: %lld, IP: \e24FF2B%#x \eEDFF24%s\e00AAAA)\n\eAABBCC", Statuses[State], Thd->Name, StatusesSign[State], ThreadCpuUsage, Thd->Info.KernelTime, Thd->Info.UserTime, Thd->Registers.eip, "unknown"); #elif defined(aa64) #endif } } OldSystemTime = TimeManager->GetCounter(); #if defined(a64) register uintptr_t CurrentStackAddress asm("rsp"); printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); #elif defined(a32) register uintptr_t CurrentStackAddress asm("esp"); printf("Sanity: %d, Stack: %#x", sanity++, CurrentStackAddress); #elif defined(aa64) register uintptr_t CurrentStackAddress asm("sp"); printf("Sanity: %d, Stack: %#lx", sanity++, CurrentStackAddress); #endif if (sanity > 1000) sanity = 0; // Display->SetBufferCursor(tmpX, tmpY); if (!Config.Quiet) Display->UpdateBuffer(); TaskManager->Sleep(100); } } #endif // DEBUG