Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 11 Jan 2002 10:59:59 -0700
From:      Nate Williams <nate@yogotech.com>
To:        Bruce Evans <bde@zeta.org.au>
Cc:        Nate Williams <nate@yogotech.com>, Daniel Eischen <eischen@pcnet1.pcnet.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:  <15423.10271.161919.615825@caddis.yogotech.com>
In-Reply-To: <20020111174631.E485-100000@gamplex.bde.org>
References:  <15421.49628.630456.688977@caddis.yogotech.com> <20020111174631.E485-100000@gamplex.bde.org>

next in thread | previous in thread | raw e-mail | index | archive | help
> > > > Why is reporting a SIGFPE considered broken?  This is a valid exception,
> > > > and it should be reported.
> > >
> > > Because the SIGFPE is for the broken context-switching code and not for
> > > the program.
> >
> > Ok, let's try again.  How can I make sure that a SIGFPE that occur due
> > to a FPU operation is properly reported using fsave/frestor?
> 
> The set of such proper reports is null, so it is easily generated by not
> using fsave (sic) or frstor.

Huh?  Are you saying that there are *NO* floating-point exceptions that
should be reported to a process?  Doesn't posix require that exceptions
be thrown.

(FWIW, I notice that FreeBSD 2.2.8 throws an exception, while FreeBSD
4.5-PRE no longer causes an exception to be thrown.)

> > (I've asked this before, but apparently not in a way that made sense.)
> >
> > Here's a snippet again.
> >
> >  	fldz
> >  	fld1
> >  	fdiv %st,%st(1)		# 1.0 / 0.0 (should cause a SIGFPE exception)
> >  	fsave #fooLocation
> >         // Mumble mumble other code to choose a new thread
> >  	frstor #barLocation
> >
> > Questions
> >
> > * Would 'thread 1' get a SIGFPE before the fsave instruction?  (Yes, No, maybe)
> 
> Only in broken cases.

Please define broken with more detail than 'broken', since now you're
being very obtuse (perhaps intentionally).

> > * If above is maybe, would it get the SIGFPE after a frstor #fooLocation?
> 
> No, because the frstor would never be reached (unless the SIGFPE handler
> is much smarter than the above code).  The above code uses fsave to shoot
> itself in the foot.  A SIGFPE occurs on the `wait' instruction which is
> part of fsave.
> 
> If the fsave is corrected to fnsave, then the frstor will be reached in
> non-broken cases, and the frstor will complete in all cases and will
> not cause a SIGFPE in non-broken cases.

But, I *WANT* SIGFPE to be thrown, causing the thread that caused the
floating point exception to receive said exception.  Not throwing an
exception is broken.  (I believe I've stated this before, and you state
that this is broken, without details as to why you believe that properly
reporting FPE's is broken.)

> > * If answer to both is NO, how do I make sure that the context of the
> >   fdiv receives a SIGFPE?  Can I use a different operation?  Can I add
> >   instructions to cause this to work correctly?
> 
> Switch back to the context of the fdiv and let it execute instructions
> in the normal way. 

That's what the frstor does, but you claim that it won't work, even if
we change fsave to fnsave.

> The SIGFPE will be delivered (if the division by
> zero exception is not masked) on the next non-control FPU instruction
> or wait instruction.

Ahh, now we're starting to make some sense.

How about the following code bits.

  	fldz
  	fld1
  	fdiv %st,%st(1)		# 1.0 / 0.0 (should cause a SIGFPE exception)
-->  	fnsave #fooLocation

        #
        # Context switching code
        #
  	frstor #barLocation

        # 'Bar' context code doing something really important.

  	fnsave #barLocation

        #
        # Context switching code
        #
-->	frstor #fooLocation
-->  	fwait			# Force the FPE to be signalled in the
                                # correct context

> (This is for the non-broken case; in the broken
> case you normally get a SIGFPE some fairly unpredictable time later,
> e,g., while another thread or the kernel is executing; the SIGFPE must
> somehow be ignored if it occurs for another context.  Don't worry about
> this, since 386's are now rare.)

Note, I didn't stick fwait after the first frstor above (although maybe
it should be), simply because I want to focus on the three pointed two
lines.

Comment/clarification:

I understand that if I use fsave, the exception *may* be thrown in the
context of the task switcher, instead of the context of the thread that
caused the FPE.

Is this correct?

I understand that by using frestor, the exception will be triggered
whenever the next fwait and/or FPU instruction occurs.

Did I restate this correctly?

Assuming the above statement is correctly, this implies that the
exception could happen alot further down the instructiuon stack if the
FPE happened at the tail end of a number of FPU instructions, a context
swtich happened, was restored at some point, and then a number of non
FPU instructions occurred before the next FPU instruction.

Again, is this valid?

Could this happen in reality, since in almost all cases, it would
require an FPU instruction to get the results of the FPU operation, and
hence the exception would be triggered whenever the program accessed the
FPU?

There is certain 'broken' hardware that never get this right (386/387)
which don't cause the exception to be triggered at any 'expected'
location, but instead report it whenever it darn well gets around to
it.  (In whatever context happens at the time.)

For all modern processors (486 and above), fnsave/frestor is all that's
required to save/restore the complete FPU state and guarantee that
exceptions will be properly reported at the correct context.  (Assuming
that exceptions are configured to be reported.)

Finally, the last question is only somewhat related.  Why does FreeBSD
4.4 no longer report DIVBYZERO exceptions, while 2.2 did?  Was this a
POSIX requirement, or a modification to the default control word to make
the ports folks happier so that badly written programs didn't fail in
FreeBSD?




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?15423.10271.161919.615825>