From 2a03240eb11841854880b11dc5e522823f2ecef2 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Sat, 29 Apr 2006 22:10:04 +0000 Subject: [PATCH] Reverted my last change as it turned out that the lazy FPU state handling was not SMP safe afterall and the performance gain is questionable. Maybe it'll be implemented correctly in the future. Sorry for any inconvenience this may have cost. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17272 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/arch/x86/arch_cpu.h | 2 ++ headers/private/kernel/cpu.h | 4 ---- headers/private/kernel/thread_types.h | 1 - src/system/kernel/arch/x86/arch_cpu.c | 15 ++++++------- src/system/kernel/arch/x86/arch_int.c | 25 +--------------------- src/system/kernel/arch/x86/arch_thread.c | 5 ++--- src/system/kernel/arch/x86/arch_x86.S | 16 ++++++++++++++ src/system/kernel/thread.c | 6 ------ 8 files changed, 27 insertions(+), 47 deletions(-) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index cf178c977d..46fd99b4fe 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -108,6 +108,8 @@ void i386_fnsave(void *fpu_state); void i386_fxsave(void *fpu_state); void i386_frstor(const void *fpu_state); void i386_fxrstor(const void *fpu_state); +void i386_fnsave_swap(void *old_fpu_state, const void *new_fpu_state); +void i386_fxsave_swap(void *old_fpu_state, const void *new_fpu_state); uint32 x86_read_ebp(); uint32 x86_read_cr0(); void x86_write_cr0(uint32 value); diff --git a/headers/private/kernel/cpu.h b/headers/private/kernel/cpu.h index 8a5802b6a5..19cd41e5a2 100644 --- a/headers/private/kernel/cpu.h +++ b/headers/private/kernel/cpu.h @@ -10,7 +10,6 @@ #include -#include #include #include @@ -25,9 +24,6 @@ typedef union cpu_ent { int preempted; timer quantum_timer; - // tells which thread's fpu state we hold - struct thread *fpu_state_thread; - // keeping track of CPU activity bigtime_t active_time; bigtime_t last_kernel_time; diff --git a/headers/private/kernel/thread_types.h b/headers/private/kernel/thread_types.h index 5c9c8d006e..b7dd401425 100644 --- a/headers/private/kernel/thread_types.h +++ b/headers/private/kernel/thread_types.h @@ -139,7 +139,6 @@ struct thread { int32 state; int32 next_state; union cpu_ent *cpu; - union cpu_ent *fpu_cpu; /* this cpu holds our fpu state */ sigset_t sig_pending; sigset_t sig_block_mask; diff --git a/src/system/kernel/arch/x86/arch_cpu.c b/src/system/kernel/arch/x86/arch_cpu.c index 1ffb9ada23..b4aab754f5 100644 --- a/src/system/kernel/arch/x86/arch_cpu.c +++ b/src/system/kernel/arch/x86/arch_cpu.c @@ -43,8 +43,7 @@ struct set_mtrr_parameter { extern void reboot(void); // from arch_x86.S -void (*gX86SaveFPUFunc)(void *state); -void (*gX86RestoreFPUFunc)(const void *state); +void (*gX86SwapFPUFunc)(void *oldState, const void *newState); bool gHasSSE = false; static struct tss **sTSS; @@ -184,9 +183,9 @@ init_sse(void) // enable OS support for SSE x86_write_cr4(x86_read_cr4() | CR4_OS_FXSR | CR4_OS_XMM_EXCEPTION); + x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU)); - gX86SaveFPUFunc = i386_fxsave; - gX86RestoreFPUFunc = i386_fxrstor; + gX86SwapFPUFunc = i386_fxsave_swap; gHasSSE = true; } @@ -237,8 +236,9 @@ status_t arch_cpu_preboot_init(kernel_args *args) { write_dr3(0); - gX86SaveFPUFunc = i386_fnsave; - gX86RestoreFPUFunc = i386_frstor; + + x86_write_cr0(x86_read_cr0() & ~(CR0_FPU_EMULATION | CR0_MONITOR_FPU)); + gX86SwapFPUFunc = i386_fnsave_swap; return B_OK; } @@ -333,9 +333,6 @@ arch_cpu_init_post_vm(kernel_args *args) DT_DATA_WRITEABLE, DPL_USER); } - // enable lazy FPU state - x86_write_cr0((x86_read_cr0() & ~CR0_FPU_EMULATION) | CR0_MONITOR_FPU); - // setup SSE2/3 support init_sse(); diff --git a/src/system/kernel/arch/x86/arch_int.c b/src/system/kernel/arch/x86/arch_int.c index 2b4180afcd..3ce42e4115 100644 --- a/src/system/kernel/arch/x86/arch_int.c +++ b/src/system/kernel/arch/x86/arch_int.c @@ -6,7 +6,6 @@ * Distributed under the terms of the NewOS License. */ -#include #include #include #include @@ -37,10 +36,6 @@ # define TRACE(x) ; #endif -// from arch_cpu.c -extern void (*gX86SaveFPUFunc)(void *state); -extern void (*gX86RestoreFPUFunc)(const void *state); - // Definitions for the PIC 8259 controller // (this is not a complete list, only what we're actually using) @@ -360,6 +355,7 @@ i386_handle_trap(struct iframe frame) case 2: // NMI Interrupt case 9: // Coprocessor Segment Overrun + case 7: // Device Not Available Exception (#NM) case 10: // Invalid TSS Exception (#TS) case 11: // Segment Not Present (#NP) case 12: // Stack Fault Exception (#SS) @@ -367,25 +363,6 @@ i386_handle_trap(struct iframe frame) fatal_exception(&frame); break; - case 7: // Device Not Available Exception (#NM) - { - // raised to lazily save and restore FPU states - cpu_ent *cpu = get_cpu_struct(); - - asm volatile ("clts;"); - if (cpu->info.fpu_state_thread != thread) { - if (cpu->info.fpu_state_thread) { - gX86SaveFPUFunc(cpu->info.fpu_state_thread->arch_info.fpu_state); - cpu->info.fpu_state_thread->fpu_cpu = NULL; - } - - gX86RestoreFPUFunc(thread->arch_info.fpu_state); - cpu->info.fpu_state_thread = thread; - thread->fpu_cpu = cpu; - } - break; - } - case 8: // Double Fault Exception (#DF) { struct tss *tss = x86_get_main_tss(); diff --git a/src/system/kernel/arch/x86/arch_thread.c b/src/system/kernel/arch/x86/arch_thread.c index 7f1f78345c..d66f5b8b42 100644 --- a/src/system/kernel/arch/x86/arch_thread.c +++ b/src/system/kernel/arch/x86/arch_thread.c @@ -28,13 +28,12 @@ #endif -#define CR0_TASK_SWITCHED (1UL << 3) - // from arch_interrupts.S extern void i386_stack_init(struct farcall *interrupt_stack_offset); extern void i386_restore_frame_from_syscall(struct iframe frame); // from arch_cpu.c +extern void (*gX86SwapFPUFunc)(void *oldState, const void *newState); extern bool gHasSSE; static struct arch_thread sInitialState _ALIGNED(16); @@ -286,7 +285,7 @@ arch_thread_context_switch(struct thread *from, struct thread *to) if (to->team->address_space != NULL) i386_reinit_user_debug_after_context_switch(to); - x86_write_cr0(x86_read_cr0() | CR0_TASK_SWITCHED); + gX86SwapFPUFunc(from->arch_info.fpu_state, to->arch_info.fpu_state); i386_context_switch(&from->arch_info, &to->arch_info, newPageDirectory); } diff --git a/src/system/kernel/arch/x86/arch_x86.S b/src/system/kernel/arch/x86/arch_x86.S index 8ae47882c4..af5688f0bf 100644 --- a/src/system/kernel/arch/x86/arch_x86.S +++ b/src/system/kernel/arch/x86/arch_x86.S @@ -45,6 +45,22 @@ FUNCTION(i386_fxrstor): fxrstor (%eax) ret +/* void i386_fsave_swap(void *old_fpu_state, const void *new_fpu_state); */ +FUNCTION(i386_fnsave_swap): + movl 4(%esp),%eax + fnsave (%eax) + movl 8(%esp),%eax + frstor (%eax) + ret + +/* void i386_fxsave_swap(void *old_fpu_state, const void *new_fpu_state); */ +FUNCTION(i386_fxsave_swap): + movl 4(%esp),%eax + fxsave (%eax) + movl 8(%esp),%eax + fxrstor (%eax) + ret + /* uint32 x86_read_ebp(); */ FUNCTION(x86_read_ebp): movl %ebp, %eax diff --git a/src/system/kernel/thread.c b/src/system/kernel/thread.c index d590da6f34..ee68543538 100644 --- a/src/system/kernel/thread.c +++ b/src/system/kernel/thread.c @@ -872,12 +872,6 @@ thread_exit2(void *_args) user_debug_thread_deleted(args.original_team_id, args.thread->id); } - // remove us as the fpu state owner if we are one - if (args.thread->fpu_cpu) { - args.thread->fpu_cpu->info.fpu_state_thread = NULL; - args.thread->fpu_cpu = NULL; - } - // return the death stack and reschedule one last time put_death_stack_and_reschedule(args.death_stack);