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:
parent
4da35ea940
commit
2a03240eb1
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user