summaryrefslogtreecommitdiffstats
path: root/sys/ia64/ia64/machdep.c
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2009-10-31 22:27:31 +0000
committermarcel <marcel@FreeBSD.org>2009-10-31 22:27:31 +0000
commit943e1b107a9100189f9c88ee1313ce81a7ed1ba5 (patch)
treecbe2460180af94e36765a193aa0c297777924c50 /sys/ia64/ia64/machdep.c
parent113d2ed8a6d71af32a5432b6d3892b57eaf4f0cc (diff)
downloadFreeBSD-src-943e1b107a9100189f9c88ee1313ce81a7ed1ba5.zip
FreeBSD-src-943e1b107a9100189f9c88ee1313ce81a7ed1ba5.tar.gz
Reimplement the lazy FP context switching:
o Move all code into a single file for easier maintenance. o Use a single global lock to avoid having to handle either multiple locks or race conditions. o Make sure to disable the high FP registers after saving or dropping them. o use msleep() to wait for the other CPU to save the high FP registers. This change fixes the high FP inconsistency panics. A single global lock typically serializes too much, which may be noticable when a lot of threads use the high FP registers, but in that case it's probably better to switch the high FP context synchronuously. Put differently: cpu_switch() should switch the high FP registers if the incoming and outgoing threads both use the high FP registers.
Diffstat (limited to 'sys/ia64/ia64/machdep.c')
-rw-r--r--sys/ia64/ia64/machdep.c75
1 files changed, 0 insertions, 75 deletions
diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c
index 299c9ec..e578e8b 100644
--- a/sys/ia64/ia64/machdep.c
+++ b/sys/ia64/ia64/machdep.c
@@ -1461,81 +1461,6 @@ set_fpregs(struct thread *td, struct fpreg *fpregs)
return (0);
}
-/*
- * High FP register functions.
- */
-
-int
-ia64_highfp_drop(struct thread *td)
-{
- struct pcb *pcb;
- struct pcpu *cpu;
- struct thread *thr;
-
- mtx_lock_spin(&td->td_md.md_highfp_mtx);
- pcb = td->td_pcb;
- cpu = pcb->pcb_fpcpu;
- if (cpu == NULL) {
- mtx_unlock_spin(&td->td_md.md_highfp_mtx);
- return (0);
- }
- pcb->pcb_fpcpu = NULL;
- thr = cpu->pc_fpcurthread;
- cpu->pc_fpcurthread = NULL;
- mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-
- /* Post-mortem sanity checking. */
- KASSERT(thr == td, ("Inconsistent high FP state"));
- return (1);
-}
-
-int
-ia64_highfp_save(struct thread *td)
-{
- struct pcb *pcb;
- struct pcpu *cpu;
- struct thread *thr;
-
- /* Don't save if the high FP registers weren't modified. */
- if ((td->td_frame->tf_special.psr & IA64_PSR_MFH) == 0)
- return (ia64_highfp_drop(td));
-
- mtx_lock_spin(&td->td_md.md_highfp_mtx);
- pcb = td->td_pcb;
- cpu = pcb->pcb_fpcpu;
- if (cpu == NULL) {
- mtx_unlock_spin(&td->td_md.md_highfp_mtx);
- return (0);
- }
-#ifdef SMP
- if (td == curthread)
- sched_pin();
- if (cpu != pcpup) {
- mtx_unlock_spin(&td->td_md.md_highfp_mtx);
- ipi_send(cpu, IPI_HIGH_FP);
- if (td == curthread)
- sched_unpin();
- while (pcb->pcb_fpcpu == cpu)
- DELAY(100);
- return (1);
- } else {
- save_high_fp(&pcb->pcb_high_fp);
- if (td == curthread)
- sched_unpin();
- }
-#else
- save_high_fp(&pcb->pcb_high_fp);
-#endif
- pcb->pcb_fpcpu = NULL;
- thr = cpu->pc_fpcurthread;
- cpu->pc_fpcurthread = NULL;
- mtx_unlock_spin(&td->td_md.md_highfp_mtx);
-
- /* Post-mortem sanity cxhecking. */
- KASSERT(thr == td, ("Inconsistent high FP state"));
- return (1);
-}
-
void
ia64_sync_icache(vm_offset_t va, vm_offset_t sz)
{
OpenPOWER on IntegriCloud