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)
|
void time::Sleep(uint64_t Milliseconds)
|
||||||
{
|
{
|
||||||
#if defined(__amd64__) || defined(__i386__)
|
#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
|
#ifdef DEBUG
|
||||||
uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue);
|
uint64_t Counter = mminq(&((HPET *)hpet)->MainCounterValue);
|
||||||
while (Counter < Target)
|
while (Counter < Target)
|
||||||
@ -31,6 +31,22 @@ namespace Time
|
|||||||
#endif
|
#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)
|
time::time(void *_acpi)
|
||||||
{
|
{
|
||||||
if (_acpi)
|
if (_acpi)
|
||||||
|
@ -349,6 +349,47 @@ namespace Tasking
|
|||||||
return false;
|
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)
|
SafeFunction __no_instrument_function void Task::Schedule(CPU::x64::TrapFrame *Frame)
|
||||||
{
|
{
|
||||||
SmartCriticalSection(SchedulerLock);
|
SmartCriticalSection(SchedulerLock);
|
||||||
@ -409,6 +450,9 @@ namespace Tasking
|
|||||||
if (CurrentCPU->CurrentThread->Status == TaskStatus::Running)
|
if (CurrentCPU->CurrentThread->Status == TaskStatus::Running)
|
||||||
CurrentCPU->CurrentThread->Status = TaskStatus::Ready;
|
CurrentCPU->CurrentThread->Status = TaskStatus::Ready;
|
||||||
|
|
||||||
|
// Loop through all threads and find which one is ready.
|
||||||
|
WakeUpThreads(CurrentCPU);
|
||||||
|
|
||||||
// Get next available thread from the list.
|
// Get next available thread from the list.
|
||||||
if (this->GetNextAvailableThread(CurrentCPU))
|
if (this->GetNextAvailableThread(CurrentCPU))
|
||||||
goto Success;
|
goto Success;
|
||||||
@ -690,6 +734,15 @@ namespace Tasking
|
|||||||
CPU::Halt();
|
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,
|
TCB *Task::CreateThread(PCB *Parent,
|
||||||
IP EntryPoint,
|
IP EntryPoint,
|
||||||
const char **argv,
|
const char **argv,
|
||||||
|
@ -68,6 +68,7 @@ namespace Tasking
|
|||||||
|
|
||||||
struct TaskInfo
|
struct TaskInfo
|
||||||
{
|
{
|
||||||
|
uint64_t SleepUntil = 0;
|
||||||
uint64_t SpawnTime = 0;
|
uint64_t SpawnTime = 0;
|
||||||
uint64_t OldUserTime = 0, CurrentUserTime = 0;
|
uint64_t OldUserTime = 0, CurrentUserTime = 0;
|
||||||
uint64_t OldKernelTime = 0, CurrentKernelTime = 0;
|
uint64_t OldKernelTime = 0, CurrentKernelTime = 0;
|
||||||
@ -216,6 +217,7 @@ namespace Tasking
|
|||||||
bool GetNextAvailableProcess(void *CPUDataPointer);
|
bool GetNextAvailableProcess(void *CPUDataPointer);
|
||||||
void SchedulerCleanupProcesses();
|
void SchedulerCleanupProcesses();
|
||||||
bool SchedulerSearchProcessThread(void *CPUDataPointer);
|
bool SchedulerSearchProcessThread(void *CPUDataPointer);
|
||||||
|
void WakeUpThreads(void *CPUDataPointer);
|
||||||
|
|
||||||
#if defined(__amd64__)
|
#if defined(__amd64__)
|
||||||
void Schedule(CPU::x64::TrapFrame *Frame);
|
void Schedule(CPU::x64::TrapFrame *Frame);
|
||||||
@ -276,6 +278,13 @@ namespace Tasking
|
|||||||
/** @brief Wait for thread to terminate */
|
/** @brief Wait for thread to terminate */
|
||||||
void WaitForThread(TCB *tcb);
|
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,
|
PCB *CreateProcess(PCB *Parent,
|
||||||
const char *Name,
|
const char *Name,
|
||||||
TaskTrustLevel TrustLevel, void *Image = nullptr);
|
TaskTrustLevel TrustLevel, void *Image = nullptr);
|
||||||
|
@ -35,6 +35,8 @@ namespace Time
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
void Sleep(uint64_t Milliseconds);
|
void Sleep(uint64_t Milliseconds);
|
||||||
|
uint64_t GetCounter();
|
||||||
|
uint64_t CalculateTarget(uint64_t Milliseconds);
|
||||||
time(void *acpi);
|
time(void *acpi);
|
||||||
~time();
|
~time();
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user