Compare commits
2 Commits
48fe2d4b04
...
6cd25fb9b1
Author | SHA1 | Date | |
---|---|---|---|
6cd25fb9b1 | |||
021ea1063b |
@ -43,7 +43,7 @@ void Thread::set_arguments(u64 arg1, u64 arg2, u64 arg3, u64 arg4)
|
|||||||
|
|
||||||
void switch_context(Thread* old_thread, Thread* new_thread, Registers* regs)
|
void switch_context(Thread* old_thread, Thread* new_thread, Registers* regs)
|
||||||
{
|
{
|
||||||
if (!old_thread->is_idle) memcpy(&old_thread->regs, regs, sizeof(Registers));
|
if (!old_thread->is_idle()) memcpy(&old_thread->regs, regs, sizeof(Registers));
|
||||||
|
|
||||||
memcpy(regs, &new_thread->regs, sizeof(Registers));
|
memcpy(regs, &new_thread->regs, sizeof(Registers));
|
||||||
}
|
}
|
@ -18,7 +18,7 @@ namespace Scheduler
|
|||||||
g_idle.id = 0;
|
g_idle.id = 0;
|
||||||
g_idle.init_regs_kernel();
|
g_idle.init_regs_kernel();
|
||||||
g_idle.set_ip((u64)CPU::idle_loop);
|
g_idle.set_ip((u64)CPU::idle_loop);
|
||||||
g_idle.is_idle = true;
|
g_idle.state = ThreadState::Idle;
|
||||||
|
|
||||||
g_idle.ticks_left = 1;
|
g_idle.ticks_left = 1;
|
||||||
|
|
||||||
@ -86,24 +86,31 @@ namespace Scheduler
|
|||||||
Thread* pick_task()
|
Thread* pick_task()
|
||||||
{
|
{
|
||||||
Thread* old = g_current;
|
Thread* old = g_current;
|
||||||
if (old->is_idle)
|
if (old->is_idle())
|
||||||
{
|
{
|
||||||
auto maybe_first = g_threads.last();
|
auto maybe_last = g_threads.last();
|
||||||
if (maybe_first.has_error()) // No threads!!
|
if (maybe_last.has_error()) // No threads!!
|
||||||
return &g_idle;
|
return &g_idle;
|
||||||
g_current = old = maybe_first.value();
|
g_current = old = maybe_last.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_found_thread = false;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
auto maybe_next = g_threads.next(g_current);
|
auto maybe_next = g_threads.next(g_current);
|
||||||
if (maybe_next.has_error()) g_current = g_threads.first().value();
|
if (maybe_next.has_error()) g_current = g_threads.first().value();
|
||||||
else
|
else
|
||||||
g_current = maybe_next.value();
|
g_current = maybe_next.value();
|
||||||
|
|
||||||
if (true) // FIXME: Check if the current task is runnable.
|
if (g_current->state == ThreadState::Runnable)
|
||||||
|
{
|
||||||
|
has_found_thread = true;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
} while (g_current != old);
|
} while (g_current != old);
|
||||||
|
|
||||||
|
if (!has_found_thread) g_current = &g_idle;
|
||||||
|
|
||||||
return g_current;
|
return g_current;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,7 +118,7 @@ namespace Scheduler
|
|||||||
{
|
{
|
||||||
if (old_thread != new_thread) switch_context(old_thread, new_thread, regs);
|
if (old_thread != new_thread) switch_context(old_thread, new_thread, regs);
|
||||||
|
|
||||||
if (new_thread->is_idle)
|
if (new_thread->is_idle())
|
||||||
{
|
{
|
||||||
new_thread->ticks_left = 1; // The idle task only runs for 1 tick so we can check for new runnable tasks
|
new_thread->ticks_left = 1; // The idle task only runs for 1 tick so we can check for new runnable tasks
|
||||||
// as fast as possible.
|
// as fast as possible.
|
||||||
|
@ -10,6 +10,13 @@
|
|||||||
#error "Unknown architecture."
|
#error "Unknown architecture."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum class ThreadState
|
||||||
|
{
|
||||||
|
Idle,
|
||||||
|
Runnable,
|
||||||
|
Sleeping
|
||||||
|
};
|
||||||
|
|
||||||
struct Thread : public DoublyLinkedListNode<Thread>
|
struct Thread : public DoublyLinkedListNode<Thread>
|
||||||
{
|
{
|
||||||
Registers regs;
|
Registers regs;
|
||||||
@ -22,7 +29,12 @@ struct Thread : public DoublyLinkedListNode<Thread>
|
|||||||
|
|
||||||
u64 ticks_left;
|
u64 ticks_left;
|
||||||
|
|
||||||
bool is_idle = false;
|
ThreadState state = ThreadState::Runnable;
|
||||||
|
|
||||||
|
bool is_idle()
|
||||||
|
{
|
||||||
|
return state == ThreadState::Idle;
|
||||||
|
}
|
||||||
|
|
||||||
void init_regs_kernel();
|
void init_regs_kernel();
|
||||||
void init_regs_user();
|
void init_regs_user();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user