Date: Mon, 7 Jan 2002 13:16:06 -0700 From: Nate Williams <nate@yogotech.com> To: Daniel Eischen <eischen@pcnet1.pcnet.com> Cc: Nate Williams <nate@yogotech.com>, Dan Eischen <eischen@vigrid.com>, Peter Wemm <peter@wemm.org>, Archie Cobbs <archie@dellroad.org>, Alfred Perlstein <bright@mu.org>, arch@FreeBSD.ORG Subject: Re: Request for review: getcontext, setcontext, etc Message-ID: <15418.518.723982.571226@caddis.yogotech.com> In-Reply-To: <Pine.SUN.3.91.1020107144700.10060A-100000@pcnet1.pcnet.com> References: <15417.64110.441186.451573@caddis.yogotech.com> <Pine.SUN.3.91.1020107144700.10060A-100000@pcnet1.pcnet.com>
next in thread | previous in thread | raw e-mail | index | archive | help
> > > > Nope, but you need to be able to get the FPU context saved in setcontext.
> > >
> > > Well, that's what I mean. If somewhere else in the application
> > > there was a setcontext that returned to the getcontext above...
> >
> > I think I understand what you are asking. Are you asking if there is
> > application specific context that needs to be saved, such as GC state or
> > somesuch? Or, am I truly confused?
> >
> > > What I'm asking is, is there any FP state (other than the FP
> > > control word which does get saved/restored), from before the
> > > getcontext call that needs to be reloaded after the call, or
> > > does the compiler assume that state may have been changed
> > > by the call itself?
>
> Thread 1:
> ---------
> /* munch some FP stuff */
> pthread_yield(); /* allow thread 2 to run */
> /* munch some more FP stuff */
>
> Assume that pthread_yield only saves the FP control word (which
> is what it does currently in libc_r).
>
> Thread 2:
> ---------
> /* FP munchy munchy */
> pthread_yield(); /* allow thread 1 to run */
> /* FP munchy munch munch */
>
>
> What FP state exists in registers across the call to
> pthread_yield().
*NOW* I understand. Thanks for being patient with me.
Here is some code snippets on that note. (It's been a *LONG* time since
I looked at this, so be nice to me. :)
Basically, we do a 'fsave' on an 108 byte array (which is the amount of
space required to save a complete processor state of the FPU unit on a
387), and then later restore the same state.
typedef struct lj_ucontext {
sigjmp_buf jmpbuf;
char floatbuf[108];
} lj_ucontext_t;
typedef struct {
unsigned int unix_errno;
lj_ucontext_t lj_ucontext;
} context_t;
#define yieldContext(contextp) { \
char * fdata = (char *)contextp->lj_ucontext.floatbuf; \
__asm__ ("fsave %0"::"m" (*fdata)); \
__asm__ ("fwait"); \
if (!sigsetjmp(contextp->lj_ucontext.jmpbuf,-1)) { \
(contextp)->unix_errno = errno; \
reschedule(); \
} else { \
/* \
* FreeBSD's siglongjmp resets the FPU with 'fninit', \
* so restore it. \
*/ \
__asm__ ("frstor %0"::"m" (*fdata)); \
} \
}
Nate
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?15418.518.723982.571226>
