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:
@@ -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
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user