Skip site navigation (1)Skip section navigation (2)
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>