forked from Bananymous/banan-os
Kernel: Scheduler sleeping is working
We have to disable optimization for one function, but I'm working on a fix
This commit is contained in:
parent
b8ee77eb78
commit
0b62729887
|
@ -24,11 +24,11 @@
|
||||||
namespace PIT
|
namespace PIT
|
||||||
{
|
{
|
||||||
|
|
||||||
static uint64_t s_system_time = 0;
|
static volatile uint64_t s_system_time = 0;
|
||||||
|
|
||||||
void irq_handler()
|
void irq_handler()
|
||||||
{
|
{
|
||||||
s_system_time++;
|
s_system_time = s_system_time + 1;
|
||||||
Kernel::Scheduler::get().reschedule();
|
Kernel::Scheduler::get().reschedule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,7 +55,10 @@ namespace PIT
|
||||||
{
|
{
|
||||||
if (ms == 0)
|
if (ms == 0)
|
||||||
return;
|
return;
|
||||||
Kernel::Scheduler::get().set_current_thread_sleeping(ms);
|
uint64_t wake_time = s_system_time + ms;
|
||||||
|
Kernel::Scheduler::get().set_current_thread_sleeping(wake_time);
|
||||||
|
if (s_system_time < wake_time)
|
||||||
|
dwarnln("sleep woke {} ms too soon", wake_time - s_system_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,9 +54,9 @@ namespace Kernel
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
BAN::RefCounted<Thread> Scheduler::current_thread()
|
Thread& Scheduler::current_thread()
|
||||||
{
|
{
|
||||||
return m_current_thread ? m_current_thread->thread : m_idle_thread;
|
return m_current_thread ? *m_current_thread->thread : *m_idle_thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::reschedule()
|
void Scheduler::reschedule()
|
||||||
|
@ -68,13 +68,11 @@ namespace Kernel
|
||||||
return;
|
return;
|
||||||
m_last_reschedule = PIT::ms_since_boot();
|
m_last_reschedule = PIT::ms_since_boot();
|
||||||
|
|
||||||
if (!m_sleeping_threads.empty())
|
|
||||||
m_sleeping_threads.front().wake_delta--;
|
|
||||||
wake_threads();
|
wake_threads();
|
||||||
|
|
||||||
if (save_current_thread())
|
if (save_current_thread())
|
||||||
return;
|
return;
|
||||||
get_next_thread();
|
advance_current_thread();
|
||||||
execute_current_thread();
|
execute_current_thread();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -83,7 +81,8 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
VERIFY_CLI();
|
VERIFY_CLI();
|
||||||
|
|
||||||
while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_delta == 0)
|
uint64_t current_time = PIT::ms_since_boot();
|
||||||
|
while (!m_sleeping_threads.empty() && m_sleeping_threads.front().wake_time <= current_time)
|
||||||
{
|
{
|
||||||
auto thread = m_sleeping_threads.front().thread;
|
auto thread = m_sleeping_threads.front().thread;
|
||||||
m_sleeping_threads.remove(m_sleeping_threads.begin());
|
m_sleeping_threads.remove(m_sleeping_threads.begin());
|
||||||
|
@ -109,7 +108,7 @@ namespace Kernel
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::get_next_thread()
|
void Scheduler::advance_current_thread()
|
||||||
{
|
{
|
||||||
VERIFY_CLI();
|
VERIFY_CLI();
|
||||||
|
|
||||||
|
@ -118,11 +117,29 @@ namespace Kernel
|
||||||
m_current_thread = {};
|
m_current_thread = {};
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_current_thread || ++m_current_thread == m_active_threads.end())
|
if (!m_current_thread || ++m_current_thread == m_active_threads.end())
|
||||||
m_current_thread = m_active_threads.begin();
|
m_current_thread = m_active_threads.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Scheduler::remove_and_advance_current_thread()
|
||||||
|
{
|
||||||
|
VERIFY_CLI();
|
||||||
|
|
||||||
|
ASSERT(m_current_thread);
|
||||||
|
|
||||||
|
if (m_active_threads.size() == 1)
|
||||||
|
{
|
||||||
|
m_active_threads.remove(m_current_thread);
|
||||||
|
m_current_thread = {};
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
auto temp = m_current_thread;
|
||||||
|
advance_current_thread();
|
||||||
|
m_active_threads.remove(temp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// NOTE: this is declared always inline, so we don't corrupt the stack
|
// NOTE: this is declared always inline, so we don't corrupt the stack
|
||||||
// after getting the rsp
|
// after getting the rsp
|
||||||
ALWAYS_INLINE bool Scheduler::save_current_thread()
|
ALWAYS_INLINE bool Scheduler::save_current_thread()
|
||||||
|
@ -138,9 +155,9 @@ namespace Kernel
|
||||||
}
|
}
|
||||||
read_rsp(rsp);
|
read_rsp(rsp);
|
||||||
|
|
||||||
auto current = current_thread();
|
auto& current = current_thread();
|
||||||
current->set_rip(rip);
|
current.set_rip(rip);
|
||||||
current->set_rsp(rsp);
|
current.set_rsp(rsp);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,64 +165,56 @@ namespace Kernel
|
||||||
{
|
{
|
||||||
VERIFY_CLI();
|
VERIFY_CLI();
|
||||||
|
|
||||||
auto current = current_thread();
|
auto& current = current_thread();
|
||||||
|
|
||||||
if (current->started())
|
if (current.started())
|
||||||
{
|
{
|
||||||
continue_thread(current->rsp(), current->rip());
|
continue_thread(current.rsp(), current.rip());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
current->set_started();
|
current.set_started();
|
||||||
start_thread(current->function(), current->rsp(), current->rip());
|
start_thread(current.function(), current.rsp(), current.rip());
|
||||||
}
|
}
|
||||||
|
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Scheduler::set_current_thread_sleeping(uint64_t wake_delta)
|
#pragma GCC push_options
|
||||||
|
#pragma GCC optimize("O0")
|
||||||
|
void Scheduler::set_current_thread_sleeping(uint64_t wake_time)
|
||||||
{
|
{
|
||||||
DISABLE_INTERRUPTS();
|
DISABLE_INTERRUPTS();
|
||||||
|
|
||||||
ASSERT(m_current_thread);
|
ASSERT(m_current_thread);
|
||||||
|
|
||||||
auto current = m_current_thread->thread;
|
auto sleeping = m_current_thread->thread;
|
||||||
|
|
||||||
auto temp = m_current_thread;
|
|
||||||
if (save_current_thread())
|
if (save_current_thread())
|
||||||
return;
|
return;
|
||||||
get_next_thread();
|
remove_and_advance_current_thread();
|
||||||
m_active_threads.remove(temp);
|
|
||||||
|
|
||||||
auto it = m_sleeping_threads.begin();
|
auto it = m_sleeping_threads.begin();
|
||||||
|
|
||||||
for (; it != m_sleeping_threads.end(); it++)
|
for (; it != m_sleeping_threads.end(); it++)
|
||||||
{
|
if (wake_time <= it->wake_time)
|
||||||
if (wake_delta <= it->wake_delta)
|
|
||||||
break;
|
break;
|
||||||
wake_delta -= it->wake_delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (it != m_sleeping_threads.end())
|
|
||||||
it->wake_delta -= wake_delta;
|
|
||||||
|
|
||||||
// This should work as we released enough memory from active thread
|
// This should work as we released enough memory from active thread
|
||||||
static_assert(sizeof(ActiveThread) == sizeof(SleepingThread));
|
static_assert(sizeof(ActiveThread) == sizeof(SleepingThread));
|
||||||
MUST(m_sleeping_threads.insert(it, { current, wake_delta }));
|
MUST(m_sleeping_threads.emplace(it, sleeping, wake_time));
|
||||||
|
sleeping.clear();
|
||||||
|
|
||||||
execute_current_thread();
|
execute_current_thread();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
#pragma GCC pop_options
|
||||||
|
|
||||||
void Scheduler::set_current_thread_done()
|
void Scheduler::set_current_thread_done()
|
||||||
{
|
{
|
||||||
DISABLE_INTERRUPTS();
|
DISABLE_INTERRUPTS();
|
||||||
|
|
||||||
ASSERT(m_current_thread);
|
ASSERT(m_current_thread);
|
||||||
|
remove_and_advance_current_thread();
|
||||||
auto temp = m_current_thread;
|
|
||||||
get_next_thread();
|
|
||||||
m_active_threads.remove(temp);
|
|
||||||
|
|
||||||
execute_current_thread();
|
execute_current_thread();
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
|
|
|
@ -59,8 +59,7 @@ namespace Kernel
|
||||||
TTY_PRINT("{}", m_prompt);
|
TTY_PRINT("{}", m_prompt);
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
//PIT::sleep(1); // sleep until next reschedule
|
PIT::sleep(1); // sleep until next reschedule
|
||||||
asm volatile("hlt");
|
|
||||||
Input::update();
|
Input::update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue