mirror of
https://github.com/Fennix-Project/Kernel.git
synced 2025-05-28 07:24:37 +00:00
Implemented sleep for threads🎉🎉🎉🎉🎉🎉🎉🎉🎉🎉
This commit is contained in:
parent
690191b927
commit
0942fb4cd3
@ -15,7 +15,7 @@ namespace Time
|
||||
void time::Sleep(uint64_t Milliseconds)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
uintptr_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
|
||||
uint64_t Target = mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
|
||||
#ifdef DEBUG
|
||||
uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue);
|
||||
while (Counter < Target)
|
||||
@ -31,6 +31,22 @@ namespace Time
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t time::GetCounter()
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
return mminq(&((HPET *)hpet)->MainCounterValue);
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
}
|
||||
|
||||
uint64_t time::CalculateTarget(uint64_t Milliseconds)
|
||||
{
|
||||
#if defined(__amd64__) || defined(__i386__)
|
||||
return mminq(&((HPET *)hpet)->MainCounterValue) + (Milliseconds * 1000000000000) / clk;
|
||||
#elif defined(__aarch64__)
|
||||
#endif
|
||||
}
|
||||
|
||||
time::time(void *_acpi)
|
||||
{
|
||||
if (_acpi)
|
||||
|
@ -349,6 +349,47 @@ namespace Tasking
|
||||
return false;
|
||||
}
|
||||
|
||||
SafeFunction __no_instrument_function void Task::WakeUpThreads(void *CPUDataPointer)
|
||||
{
|
||||
CPUData *CurrentCPU = (CPUData *)CPUDataPointer;
|
||||
// Loop through all the processes.
|
||||
foreach (PCB *pcb in ListProcess)
|
||||
{
|
||||
if (InvalidPCB(pcb))
|
||||
continue;
|
||||
|
||||
// Check process status.
|
||||
switch (pcb->Status)
|
||||
{
|
||||
case TaskStatus::Ready:
|
||||
schedbg("Ready process (%s)%d", pcb->Name, pcb->ID);
|
||||
break;
|
||||
default:
|
||||
schedbg("Process \"%s\"(%d) status %d", pcb->Name, pcb->ID, pcb->Status);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Loop through all the threads.
|
||||
foreach (TCB *tcb in pcb->Threads)
|
||||
{
|
||||
if (InvalidTCB(tcb))
|
||||
continue;
|
||||
|
||||
// Check if the thread is sleeping.
|
||||
if (tcb->Status != TaskStatus::Sleeping)
|
||||
continue;
|
||||
|
||||
// Check if the thread is ready to wake up.
|
||||
if (tcb->Info.SleepUntil < TimeManager->GetCounter())
|
||||
{
|
||||
tcb->Status = TaskStatus::Ready;
|
||||
tcb->Info.SleepUntil = 0;
|
||||
schedbg("Thread \"%s\"(%d) woke up.", tcb->Name, tcb->ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SafeFunction __no_instrument_function void Task::Schedule(CPU::x64::TrapFrame *Frame)
|
||||
{
|
||||
SmartCriticalSection(SchedulerLock);
|
||||
@ -409,6 +450,9 @@ namespace Tasking
|
||||
if (CurrentCPU->CurrentThread->Status == TaskStatus::Running)
|
||||
CurrentCPU->CurrentThread->Status = TaskStatus::Ready;
|
||||
|
||||
// Loop through all threads and find which one is ready.
|
||||
WakeUpThreads(CurrentCPU);
|
||||
|
||||
// Get next available thread from the list.
|
||||
if (this->GetNextAvailableThread(CurrentCPU))
|
||||
goto Success;
|
||||
@ -690,6 +734,15 @@ namespace Tasking
|
||||
CPU::Halt();
|
||||
}
|
||||
|
||||
void Task::Sleep(uint64_t Milliseconds)
|
||||
{
|
||||
SmartCriticalSection(SchedulerLock);
|
||||
TCB *thread = this->GetCurrentThread();
|
||||
thread->Status = TaskStatus::Sleeping;
|
||||
thread->Info.SleepUntil = TimeManager->CalculateTarget(Milliseconds);
|
||||
OneShot(1);
|
||||
}
|
||||
|
||||
TCB *Task::CreateThread(PCB *Parent,
|
||||
IP EntryPoint,
|
||||
const char **argv,
|
||||
|
@ -68,6 +68,7 @@ namespace Tasking
|
||||
|
||||
struct TaskInfo
|
||||
{
|
||||
uint64_t SleepUntil = 0;
|
||||
uint64_t SpawnTime = 0;
|
||||
uint64_t OldUserTime = 0, CurrentUserTime = 0;
|
||||
uint64_t OldKernelTime = 0, CurrentKernelTime = 0;
|
||||
@ -216,6 +217,7 @@ namespace Tasking
|
||||
bool GetNextAvailableProcess(void *CPUDataPointer);
|
||||
void SchedulerCleanupProcesses();
|
||||
bool SchedulerSearchProcessThread(void *CPUDataPointer);
|
||||
void WakeUpThreads(void *CPUDataPointer);
|
||||
|
||||
#if defined(__amd64__)
|
||||
void Schedule(CPU::x64::TrapFrame *Frame);
|
||||
@ -276,6 +278,13 @@ namespace Tasking
|
||||
/** @brief Wait for thread to terminate */
|
||||
void WaitForThread(TCB *tcb);
|
||||
|
||||
/**
|
||||
* @brief Sleep for a given amount of milliseconds
|
||||
*
|
||||
* @param Milliseconds Amount of milliseconds to sleep
|
||||
*/
|
||||
void Sleep(uint64_t Milliseconds);
|
||||
|
||||
PCB *CreateProcess(PCB *Parent,
|
||||
const char *Name,
|
||||
TaskTrustLevel TrustLevel, void *Image = nullptr);
|
||||
|
@ -35,6 +35,8 @@ namespace Time
|
||||
|
||||
public:
|
||||
void Sleep(uint64_t Milliseconds);
|
||||
uint64_t GetCounter();
|
||||
uint64_t CalculateTarget(uint64_t Milliseconds);
|
||||
time(void *acpi);
|
||||
~time();
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user