forked from Bananymous/banan-os
Kernel: Optimize sse saving/loading
Only save and load sse when new thread is trying to execute sse instruction. There is no need to do that every time we enter kernel.
This commit is contained in:
parent
db0650cf10
commit
001e95f973
|
@ -218,6 +218,23 @@ namespace Kernel::IDT
|
|||
}
|
||||
}
|
||||
}
|
||||
#if __enable_sse
|
||||
else if (isr == ISR::DeviceNotAvailable)
|
||||
{
|
||||
asm volatile(
|
||||
"movq %cr0, %rax;"
|
||||
"andq $~(1 << 3), %rax;"
|
||||
"movq %rax, %cr0;"
|
||||
);
|
||||
if (auto* current = &Thread::current(); current != Thread::sse_thread())
|
||||
{
|
||||
if (auto* sse = Thread::sse_thread())
|
||||
sse->save_sse();
|
||||
current->load_sse();
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (PageTable::current().get_page_flags(interrupt_stack.rip & PAGE_ADDR_MASK) & PageTable::Flags::Present)
|
||||
|
@ -259,7 +276,6 @@ namespace Kernel::IDT
|
|||
int signal = 0;
|
||||
switch (isr)
|
||||
{
|
||||
case ISR::DeviceNotAvailable:
|
||||
case ISR::DivisionError:
|
||||
case ISR::SIMDFloatingPointException:
|
||||
case ISR::x87FloatingPointException:
|
||||
|
@ -290,22 +306,11 @@ namespace Kernel::IDT
|
|||
ASSERT(Thread::current().state() != Thread::State::Terminated);
|
||||
|
||||
done:
|
||||
#if __enable_sse
|
||||
if (from_userspace)
|
||||
{
|
||||
ASSERT(Thread::current().state() == Thread::State::Executing);
|
||||
Thread::current().load_sse();
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
extern "C" void cpp_irq_handler(uint64_t irq, InterruptStack& interrupt_stack)
|
||||
{
|
||||
#if __enable_sse
|
||||
Thread::current().save_sse();
|
||||
#endif
|
||||
|
||||
if (Scheduler::current_tid())
|
||||
{
|
||||
Thread::current().set_return_rsp(interrupt_stack.rsp);
|
||||
|
@ -326,10 +331,6 @@ done:
|
|||
Scheduler::get().reschedule_if_idling();
|
||||
|
||||
ASSERT(Thread::current().state() != Thread::State::Terminated);
|
||||
|
||||
#if __enable_sse
|
||||
Thread::current().load_sse();
|
||||
#endif
|
||||
}
|
||||
|
||||
static void flush_idt()
|
||||
|
|
|
@ -75,7 +75,7 @@ namespace Kernel
|
|||
vaddr_t interrupt_stack_base() const { return m_interrupt_stack ? m_interrupt_stack->vaddr() : 0; }
|
||||
size_t interrupt_stack_size() const { return m_interrupt_stack ? m_interrupt_stack->size() : 0; }
|
||||
|
||||
static Thread& current() ;
|
||||
static Thread& current();
|
||||
static pid_t current_tid();
|
||||
|
||||
Process& process();
|
||||
|
@ -87,8 +87,9 @@ namespace Kernel
|
|||
size_t physical_page_count() const { return virtual_page_count(); }
|
||||
|
||||
#if __enable_sse
|
||||
void save_sse() { asm volatile("fxsave %0" :: "m"(m_sse_storage)); }
|
||||
void load_sse() { asm volatile("fxrstor %0" :: "m"(m_sse_storage)); }
|
||||
void save_sse();
|
||||
void load_sse();
|
||||
static Thread* sse_thread();
|
||||
#endif
|
||||
|
||||
private:
|
||||
|
|
|
@ -231,6 +231,17 @@ namespace Kernel
|
|||
|
||||
Thread* current = ¤t_thread();
|
||||
|
||||
#if __enable_sse
|
||||
if (current != Thread::sse_thread())
|
||||
{
|
||||
asm volatile(
|
||||
"movq %cr0, %rax;"
|
||||
"orq $(1 << 3), %rax;"
|
||||
"movq %rax, %cr0"
|
||||
);
|
||||
}
|
||||
#endif
|
||||
|
||||
while (current->state() == Thread::State::Terminated)
|
||||
{
|
||||
Thread* thread = m_current_thread->thread;
|
||||
|
|
|
@ -26,10 +26,6 @@ namespace Kernel
|
|||
Thread::current().set_return_rsp(interrupt_stack.rsp);
|
||||
Thread::current().set_return_rip(interrupt_stack.rip);
|
||||
|
||||
#if __enable_sse
|
||||
Thread::current().save_sse();
|
||||
#endif
|
||||
|
||||
asm volatile("sti");
|
||||
|
||||
(void)arg1;
|
||||
|
@ -230,10 +226,6 @@ namespace Kernel
|
|||
|
||||
ASSERT(Kernel::Thread::current().state() == Kernel::Thread::State::Executing);
|
||||
|
||||
#if __enable_sse
|
||||
current_thread.load_sse();
|
||||
#endif
|
||||
|
||||
if (ret.is_error())
|
||||
return -ret.error().get_error_code();
|
||||
return ret.value();
|
||||
|
|
|
@ -101,7 +101,16 @@ namespace Kernel
|
|||
: m_tid(tid), m_process(process)
|
||||
{
|
||||
#if __enable_sse
|
||||
uintptr_t cr0;
|
||||
asm volatile(
|
||||
"movq %%cr0, %%rax;"
|
||||
"movq %%rax, %%rbx;"
|
||||
"andq $~(1 << 3), %%rax;"
|
||||
"movq %%rax, %%cr0;"
|
||||
: "=b"(cr0)
|
||||
);
|
||||
save_sse();
|
||||
asm volatile("movq %0, %%cr0" :: "r"(cr0));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -361,4 +370,24 @@ namespace Kernel
|
|||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
#if __enable_sse
|
||||
static Thread* s_sse_thread = nullptr;
|
||||
|
||||
void Thread::save_sse()
|
||||
{
|
||||
asm volatile("fxsave %0" :: "m"(m_sse_storage));
|
||||
}
|
||||
|
||||
void Thread::load_sse()
|
||||
{
|
||||
asm volatile("fxrstor %0" :: "m"(m_sse_storage));
|
||||
s_sse_thread = this;
|
||||
}
|
||||
|
||||
Thread* Thread::sse_thread()
|
||||
{
|
||||
return s_sse_thread;
|
||||
}
|
||||
#endif
|
||||
|
||||
}
|
Loading…
Reference in New Issue