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
This commit is contained in:
Michael Lotz 2006-04-29 22:10:04 +00:00
parent 4da35ea940
commit 2a03240eb1
8 changed files with 27 additions and 47 deletions

View File

@ -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);

View File

@ -10,7 +10,6 @@
#include <smp.h>
#include <thread.h>
#include <timer.h>
#include <boot/kernel_args.h>
@ -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;

View File

@ -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;

View File

@ -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();

View File

@ -6,7 +6,6 @@
* Distributed under the terms of the NewOS License.
*/
#include <cpu.h>
#include <int.h>
#include <kscheduler.h>
#include <ksyscalls.h>
@ -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();

View File

@ -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);
}

View File

@ -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

View File

@ -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);