*BSD News Article 36696


Return to BSD News archive

Path: sserve!newshost.anu.edu.au!harbinger.cc.monash.edu.au!bunyip.cc.uq.oz.au!munnari.oz.au!spool.mu.edu!howland.reston.ans.net!cs.utexas.edu!uunet!promus.com!informix.com!barrnet.net!oz.cdrom.com!oz.cdrom.com!jkh
From: jkh@freefall.cdrom.com (Jordan K. Hubbard)
Newsgroups: comp.os.386bsd.questions
Subject: Re: Problems with M3
Date: 07 Oct 1994 22:15:23 GMT
Organization: Walnut Creek CD-ROM
Lines: 56
Message-ID: <JKH.94Oct7151524@freefall.cdrom.com>
NNTP-Posting-Host: freefall.cdrom.com

The following is forwarded from Bruce Evans:

>As with most ports, it seems, the problem is in the thread interface.
>The threads are running, and I am quite sure I have got the size of 
>the jump_buf right, the values in Target.m3 are correct for FreeBSD
>and the signal interface is ok. The last vexing problem that I haven't
>been able to track down during the last few days is that threads preempted 
>by SIGVTALARM will raise floating point exceptions now and then. It seems
>as if the delivery of the signal during the execution of a floating point
>operation will cause this operation to fail. ...

You probably need a version of setjmp+longjmp that preserves the floating
point state.  The standard version doesn't do this because it would
waste time and space and isn't necessary for standard operations (those
specified by ANSI C).  setjmp() saves only the control word and longjmp()
reinitializes the FPU and then loads the control word.  This allows
certain undefined operations to work (essentially those where the
setjmp() was done _not_ in a signal handler and the longjmp() was done
anywhere).  sigsetjmp()/siglongjmp() don't work if the siglongjmp() is
done in a signal handler and the FPU state being used when the signal
is delivered.  Note that implementation of threads using SIGVTALARM
depends on the kernel not changing the FPU state before delivering the
signal used for time slicing.  FreeBSD doesn't change the FPU state
before delivering any signal, so signal handlers cannot use the FPU
unless they save, initialize and restore its state.  On 386+387 systems,
it isn't easy to save, initialize and restore the state transparently
because the save and restore may generate a SIGFPU.

Bruce
>As with most ports, it seems, the problem is in the thread interface.
>The threads are running, and I am quite sure I have got the size of 
>the jump_buf right, the values in Target.m3 are correct for FreeBSD
>and the signal interface is ok. The last vexing problem that I haven't
>been able to track down during the last few days is that threads preempted 
>by SIGVTALARM will raise floating point exceptions now and then. It seems
>as if the delivery of the signal during the execution of a floating point
>operation will cause this operation to fail. ...

You probably need a version of setjmp+longjmp that preserves the floating
point state.  The standard version doesn't do this because it would
waste time and space and isn't necessary for standard operations (those
specified by ANSI C).  setjmp() saves only the control word and longjmp()
reinitializes the FPU and then loads the control word.  This allows
certain undefined operations to work (essentially those where the
setjmp() was done _not_ in a signal handler and the longjmp() was done
anywhere).  sigsetjmp()/siglongjmp() don't work if the siglongjmp() is
done in a signal handler and the FPU state being used when the signal
is delivered.  Note that implementation of threads using SIGVTALARM
depends on the kernel not changing the FPU state before delivering the
signal used for time slicing.  FreeBSD doesn't change the FPU state
before delivering any signal, so signal handlers cannot use the FPU
unless they save, initialize and restore its state.  On 386+387 systems,
it isn't easy to save, initialize and restore the state transparently
because the save and restore may generate a SIGFPU.

Bruce