diff options
author | 2006-04-06 15:27:08 +0000 | |
---|---|---|
committer | 2006-04-06 15:27:08 +0000 | |
commit | 43b8121b05ab2897c36c942c06903ff43f2b0e47 (patch) | |
tree | fa5ab579c854888f0df57aae7cecb9d44e82127b /lib/libpthread/arch | |
parent | Add missing break. Now bgpctl show rib det source-as 8271 shows all announced (diff) | |
download | wireguard-openbsd-43b8121b05ab2897c36c942c06903ff43f2b0e47.tar.xz wireguard-openbsd-43b8121b05ab2897c36c942c06903ff43f2b0e47.zip |
- due to the fninit() in _thread_machdep_save_float_state() all calls to
it need to be matched with a call to _thread_machdep_restore_float_state(),
so add missing one in _thread_machdep_init().
- 16-byte align fp frame
- call fwait() before save and and after restoring fp state.
lots of guidance and ok mickey@
Diffstat (limited to 'lib/libpthread/arch')
-rw-r--r-- | lib/libpthread/arch/i386/uthread_machdep.c | 21 |
1 files changed, 16 insertions, 5 deletions
diff --git a/lib/libpthread/arch/i386/uthread_machdep.c b/lib/libpthread/arch/i386/uthread_machdep.c index c8d55941300..42c8f52774a 100644 --- a/lib/libpthread/arch/i386/uthread_machdep.c +++ b/lib/libpthread/arch/i386/uthread_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uthread_machdep.c,v 1.4 2004/02/21 22:55:20 deraadt Exp $ */ +/* $OpenBSD: uthread_machdep.c,v 1.5 2006/04/06 15:27:08 kurt Exp $ */ /* David Leonard, <d@csee.uq.edu.au>. Public domain. */ /* @@ -66,7 +66,7 @@ _thread_machdep_init(struct _machdep_state* statep, void *base, int len, struct frame *f; /* Locate the initial frame, aligned at the top of the stack */ - f = (struct frame *)(((int)base + len - sizeof *f) & ~ALIGNBYTES); + f = (struct frame *)(((int)base + len - sizeof *f) & ~15); /* Set up initial frame */ f->fr_esp = (int)&f->fr_edi; @@ -81,6 +81,15 @@ _thread_machdep_init(struct _machdep_state* statep, void *base, int len, statep->esp = (int)f; _thread_machdep_save_float_state(statep); + /* + * The current thread float state is saved into the new thread stack. + * Later pthread_create calls _thread_kern_sched which saves the current + * thread float state again into its own stack. However all float state + * saves must be balanced with a restore on i386 due to the fninit(). + * Restore the current thread float state here so that the next save + * gets the correct state. + */ + _thread_machdep_restore_float_state(statep); } /* @@ -101,6 +110,7 @@ _thread_machdep_save_float_state(struct _machdep_state *ms) union savefpu *addr = &ms->fpreg; if (_thread_machdep_osfxsr()) { + fwait(); fxsave(&addr->sv_xmm); fninit(); } else @@ -113,9 +123,10 @@ _thread_machdep_restore_float_state(struct _machdep_state *ms) { union savefpu *addr = &ms->fpreg; - if (_thread_machdep_osfxsr()) + if (_thread_machdep_osfxsr()) { fxrstor(&addr->sv_xmm); - else + fwait(); + } else frstor(&addr->sv_87); - + } |