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:
@@ -108,6 +108,8 @@ void i386_fnsave(void *fpu_state);
|
|||||||
void i386_fxsave(void *fpu_state);
|
void i386_fxsave(void *fpu_state);
|
||||||
void i386_frstor(const void *fpu_state);
|
void i386_frstor(const void *fpu_state);
|
||||||
void i386_fxrstor(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_ebp();
|
||||||
uint32 x86_read_cr0();
|
uint32 x86_read_cr0();
|
||||||
void x86_write_cr0(uint32 value);
|
void x86_write_cr0(uint32 value);
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <smp.h>
|
#include <smp.h>
|
||||||
#include <thread.h>
|
|
||||||
#include <timer.h>
|
#include <timer.h>
|
||||||
#include <boot/kernel_args.h>
|
#include <boot/kernel_args.h>
|
||||||
|
|
||||||
@@ -25,9 +24,6 @@ typedef union cpu_ent {
|
|||||||
int preempted;
|
int preempted;
|
||||||
timer quantum_timer;
|
timer quantum_timer;
|
||||||
|
|
||||||
// tells which thread's fpu state we hold
|
|
||||||
struct thread *fpu_state_thread;
|
|
||||||
|
|
||||||
// keeping track of CPU activity
|
// keeping track of CPU activity
|
||||||
bigtime_t active_time;
|
bigtime_t active_time;
|
||||||
bigtime_t last_kernel_time;
|
bigtime_t last_kernel_time;
|
||||||
|
|||||||
@@ -139,7 +139,6 @@ struct thread {
|
|||||||
int32 state;
|
int32 state;
|
||||||
int32 next_state;
|
int32 next_state;
|
||||||
union cpu_ent *cpu;
|
union cpu_ent *cpu;
|
||||||
union cpu_ent *fpu_cpu; /* this cpu holds our fpu state */
|
|
||||||
|
|
||||||
sigset_t sig_pending;
|
sigset_t sig_pending;
|
||||||
sigset_t sig_block_mask;
|
sigset_t sig_block_mask;
|
||||||
|
|||||||
@@ -43,8 +43,7 @@ struct set_mtrr_parameter {
|
|||||||
extern void reboot(void);
|
extern void reboot(void);
|
||||||
// from arch_x86.S
|
// from arch_x86.S
|
||||||
|
|
||||||
void (*gX86SaveFPUFunc)(void *state);
|
void (*gX86SwapFPUFunc)(void *oldState, const void *newState);
|
||||||
void (*gX86RestoreFPUFunc)(const void *state);
|
|
||||||
bool gHasSSE = false;
|
bool gHasSSE = false;
|
||||||
|
|
||||||
static struct tss **sTSS;
|
static struct tss **sTSS;
|
||||||
@@ -184,9 +183,9 @@ init_sse(void)
|
|||||||
|
|
||||||
// enable OS support for SSE
|
// enable OS support for SSE
|
||||||
x86_write_cr4(x86_read_cr4() | CR4_OS_FXSR | CR4_OS_XMM_EXCEPTION);
|
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;
|
gX86SwapFPUFunc = i386_fxsave_swap;
|
||||||
gX86RestoreFPUFunc = i386_fxrstor;
|
|
||||||
gHasSSE = true;
|
gHasSSE = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -237,8 +236,9 @@ status_t
|
|||||||
arch_cpu_preboot_init(kernel_args *args)
|
arch_cpu_preboot_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
write_dr3(0);
|
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;
|
return B_OK;
|
||||||
}
|
}
|
||||||
@@ -333,9 +333,6 @@ arch_cpu_init_post_vm(kernel_args *args)
|
|||||||
DT_DATA_WRITEABLE, DPL_USER);
|
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
|
// setup SSE2/3 support
|
||||||
init_sse();
|
init_sse();
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,6 @@
|
|||||||
* Distributed under the terms of the NewOS License.
|
* Distributed under the terms of the NewOS License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cpu.h>
|
|
||||||
#include <int.h>
|
#include <int.h>
|
||||||
#include <kscheduler.h>
|
#include <kscheduler.h>
|
||||||
#include <ksyscalls.h>
|
#include <ksyscalls.h>
|
||||||
@@ -37,10 +36,6 @@
|
|||||||
# define TRACE(x) ;
|
# define TRACE(x) ;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// from arch_cpu.c
|
|
||||||
extern void (*gX86SaveFPUFunc)(void *state);
|
|
||||||
extern void (*gX86RestoreFPUFunc)(const void *state);
|
|
||||||
|
|
||||||
// Definitions for the PIC 8259 controller
|
// Definitions for the PIC 8259 controller
|
||||||
// (this is not a complete list, only what we're actually using)
|
// (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 2: // NMI Interrupt
|
||||||
case 9: // Coprocessor Segment Overrun
|
case 9: // Coprocessor Segment Overrun
|
||||||
|
case 7: // Device Not Available Exception (#NM)
|
||||||
case 10: // Invalid TSS Exception (#TS)
|
case 10: // Invalid TSS Exception (#TS)
|
||||||
case 11: // Segment Not Present (#NP)
|
case 11: // Segment Not Present (#NP)
|
||||||
case 12: // Stack Fault Exception (#SS)
|
case 12: // Stack Fault Exception (#SS)
|
||||||
@@ -367,25 +363,6 @@ i386_handle_trap(struct iframe frame)
|
|||||||
fatal_exception(&frame);
|
fatal_exception(&frame);
|
||||||
break;
|
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)
|
case 8: // Double Fault Exception (#DF)
|
||||||
{
|
{
|
||||||
struct tss *tss = x86_get_main_tss();
|
struct tss *tss = x86_get_main_tss();
|
||||||
|
|||||||
@@ -28,13 +28,12 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define CR0_TASK_SWITCHED (1UL << 3)
|
|
||||||
|
|
||||||
// from arch_interrupts.S
|
// from arch_interrupts.S
|
||||||
extern void i386_stack_init(struct farcall *interrupt_stack_offset);
|
extern void i386_stack_init(struct farcall *interrupt_stack_offset);
|
||||||
extern void i386_restore_frame_from_syscall(struct iframe frame);
|
extern void i386_restore_frame_from_syscall(struct iframe frame);
|
||||||
|
|
||||||
// from arch_cpu.c
|
// from arch_cpu.c
|
||||||
|
extern void (*gX86SwapFPUFunc)(void *oldState, const void *newState);
|
||||||
extern bool gHasSSE;
|
extern bool gHasSSE;
|
||||||
|
|
||||||
static struct arch_thread sInitialState _ALIGNED(16);
|
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)
|
if (to->team->address_space != NULL)
|
||||||
i386_reinit_user_debug_after_context_switch(to);
|
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);
|
i386_context_switch(&from->arch_info, &to->arch_info, newPageDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,22 @@ FUNCTION(i386_fxrstor):
|
|||||||
fxrstor (%eax)
|
fxrstor (%eax)
|
||||||
ret
|
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(); */
|
/* uint32 x86_read_ebp(); */
|
||||||
FUNCTION(x86_read_ebp):
|
FUNCTION(x86_read_ebp):
|
||||||
movl %ebp, %eax
|
movl %ebp, %eax
|
||||||
|
|||||||
@@ -872,12 +872,6 @@ thread_exit2(void *_args)
|
|||||||
user_debug_thread_deleted(args.original_team_id, args.thread->id);
|
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
|
// return the death stack and reschedule one last time
|
||||||
put_death_stack_and_reschedule(args.death_stack);
|
put_death_stack_and_reschedule(args.death_stack);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user