[comp.unix.i386] floating point exception status not inherited by exec

amull@Morgan.COM (Andrew P. Mullhaupt) (03/24/90)

	On SCO UNIX System V/386 R3.2:

I need to preserve the state of the floating point exception mask
across an exec(). Experiments show that the exception mask and the
sticky bit status seems to be preserved across fork() (i.e. is
inherited by a child) but when exec is invoked, the exceptions may
change. This has ummm - 'unpleasant' consequences. Note that it
is not sufficient to work at the level of SIGFPE, but it is actually
required to specify the floating point exception mask and sticky bit
status to different values than the (otherwise sensible) defaults.

Any ideas?

Later,
Andrew Mullhaupt

jsalter@slo.uucp (James Salter) (03/25/90)

In article <795@s7.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:
>
>	On SCO UNIX System V/386 R3.2:
>
>I need to preserve the state of the floating point exception mask
>across an exec(). Experiments show that the exception mask and the
>sticky bit status seems to be preserved across fork() (i.e. is
>inherited by a child) but when exec is invoked, the exceptions may
>change. This has ummm - 'unpleasant' consequences. Note that it
>is not sufficient to work at the level of SIGFPE, but it is actually
>required to specify the floating point exception mask and sticky bit
>status to different values than the (otherwise sensible) defaults.

You mean apart from rewriting the exec() function?  :-)

Realistically, the only way you could preserve the state is through a
save mechanism before the exec() and a restore after the exec().

In the System V/386 3.2 programmer's reference manual I have, it lists
some routines under FPGETROUND(3C).  Including the functions:
	fpgetmask(), fpsetmask(), fpgetsticky(), fpsetsticky()
and the include file:
	#include <ieeefp.h>

I don't know what SCO version does...

To do your own such routines, it would require some machine coding and
use of at least a short int to save just the status word.  If you require
the status AND the control word to be saved, just store it into a long int
and do some byte shifting.  Or use two shorts if you're lazy...

>Andrew Mullhaupt

jim/jsalter   IBM AWD   T465/(415)855-4427    VNET: JSALTER at PALOALTO
UUCP: ..!uunet!ibmsupt!jsalter               Disc: Any opinions are mine.
IP: ibmsupt!jsalter@uunet.uu.net                 "PS/2 it, or DIE!"

jeff@samna.UUCP (jeff) (03/27/90)

In article <795@s7.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:
>I need to preserve the state of the floating point exception mask
>across an exec(). Experiments show that the exception mask and the
>sticky bit status seems to be preserved across fork() (i.e. is
>inherited by a child) but when exec is invoked, the exceptions may
>change. This has ummm - 'unpleasant' consequences. Note that it
>is not sufficient to work at the level of SIGFPE, but it is actually
>required to specify the floating point exception mask and sticky bit
>status to different values than the (otherwise sensible) defaults.

Hmm, I'm fairly sure that the "sticky bit" ordinarily refers to the bit in
the file permissions which causes an executable to hang around in
the swap space even when it's not in use.  I don't think anyone would
want this inherited across an exec (Imagine putting the sticky bit on
your shell and having it inherited across exec's - pretty soon you'd
run out of swap as every single program in /bin, /usr/bin, /usr/ucb, etc.
gets sucked into swap).  I think you're referring to something other
than the sticky bit.

As for the exception mask, I think it's only fair to a process being
exec'd that it know that the floating point chip is in some reasonably
well-defined state when it begins execution - I'd suspect that's why
it's being re-initialized.  If you really need the exception mask to
be set a certain way, why not pass the state to the new process as
an argument and let the new process set the exception mask to the
desired value.

Jeff

amull@Morgan.COM (Andrew P. Mullhaupt) (03/29/90)

There are two separate things called 'sticky bits'. One is, as you
point out, a file permission UNIX creature, whereas the other,
having no essential connection to UNIX that I know of, is part of
the IEEE floating point standard. This second one is the one I need
to preserve across execs.

Some people have suggested having the child read the floating point
status from the environment. The hope was not to have to modify the
child source.

Later,
Andrew Mullhaupt

guy@auspex.auspex.com (Guy Harris) (03/29/90)

>Hmm, I'm fairly sure that the "sticky bit" ordinarily refers to the bit in
>the file permissions which causes an executable to hang around in
>the swap space even when it's not in use.

I suspect he's referring to some other "sticky bit" (I seem to remember
that some schemes for doing floating-point arithmetic have something
called a "sticky bit").

jsalter@slo.uucp (James Salter) (03/29/90)

In article <240@samna.UUCP> jeff@samna.UUCP () writes:
>In article <795@s7.Morgan.COM> amull@Morgan.COM (Andrew P. Mullhaupt) writes:
>>I need to preserve the state of the floating point exception mask
>>across an exec(). Experiments show that the exception mask and the
>>sticky bit status seems to be preserved across fork() (i.e. is
>>inherited by a child) but when exec is invoked, the exceptions may
>>change. This has ummm - 'unpleasant' consequences. Note that it
>>is not sufficient to work at the level of SIGFPE, but it is actually
>>required to specify the floating point exception mask and sticky bit
>>status to different values than the (otherwise sensible) defaults.
>
>Hmm, I'm fairly sure that the "sticky bit" ordinarily refers to the bit in
>the file permissions which causes an executable to hang around in
>the swap space even when it's not in use.  I don't think anyone would
>want this inherited across an exec (Imagine putting the sticky bit on
>your shell and having it inherited across exec's - pretty soon you'd
>run out of swap as every single program in /bin, /usr/bin, /usr/ucb, etc.
>gets sucked into swap).  I think you're referring to something other
>than the sticky bit.

No, he was right in what he said.  The exception status on the 387 (or
emulated 387) is a 16-bit register which contains the status of various
attributes of the 387, including (in the low 6 bits) the status of
floating-point exceptions.  This 6 bits are "sticky" and refer to the fact
that they are not cleared upon the next floating-point instruction unless
that instruction is one of (FINIT, FCLES, FLDENV, FSAVE, and FRSTOR).

This sticky-ness allows one to check for floating-point operations which
cause exceptional conditions to occur (Divide-by-zero, NaNs, etc...).  It
can be difficult to determine the exact instruction if there are many
floating-point operations occuring, but it's a good start.

The sticky-ness he is referring to has nothing to do with keeping files
in swap space.

>As for the exception mask, I think it's only fair to a process being
>exec'd that it know that the floating point chip is in some reasonably
>well-defined state when it begins execution - I'd suspect that's why
>it's being re-initialized.

True.  Though more likely whatever is being execed is just screwing up
the status without caring what's in it.

>If you really need the exception mask to
>be set a certain way, why not pass the state to the new process as
>an argument and let the new process set the exception mask to the
>desired value.

No.  He wanted the exception saved "across" the exec(), not within the
exec().  There is no reason to pass any new parameters in.  Code such
as the following will suffice (assuming I haven't misinterpreted something):

	save_status = fp_get_status();
	....
	.. code involving exec() ..
	....
	(void) fp_restore_status(save_status);

where fp_get_status, and fp_restore_status are small machine language
routines.

>Jeff

jim/jsalter   IBM AWD   T465/(415)855-4427    VNET: JSALTER at PALOALTO
UUCP: ..!uunet!ibmsupt!jsalter               Disc: Any opinions are mine.
IP: ibmsupt!jsalter@uunet.uu.net                 "PS/2 it, or DIE!"

jkenton@pinocchio.encore.com (Jeff Kenton) (03/29/90)

From article <3089@auspex.auspex.com>, by guy@auspex.auspex.com (Guy Harris):
>>Hmm, I'm fairly sure that the "sticky bit" ordinarily refers to the bit in
>>the file permissions which causes an executable to hang around in
>>the swap space even when it's not in use.
> 
> I suspect he's referring to some other "sticky bit" (I seem to remember
> that some schemes for doing floating-point arithmetic have something
> called a "sticky bit").

Actually, I think there are 3 different "sticky bits".

	One is in the file protections, as described above.

	Another is used in rounding floating results, and is useful
	only internally to the FP unit during a single operation
	(or during FP exception processing on some machines, e.g., the 88000).

	The third is the accumulated set of FP exception bits which are sticky
	in the sense that they are set by the system hardware (or software)
	but usually not cleared except by the application program.

This last is probably what the original poster had problems with when he said
they were not preserved across exec() calls.  And, most likely, this is what
you should expect the kernel to do -- provide each new process with a clean
set of exception bits.  If you need to preserve these bits across process
creation you should pass them to the newly created process as an argument,
as someone else suggested.




- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      jeff kenton  ---	temporarily at jkenton@pinocchio.encore.com	 
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -