Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 20 Nov 1995 13:24:24 +1100
From:      Bruce Evans <bde@zeta.org.au>
To:        bde@zeta.org.au, cimaxp1!jb@werple.net.au
Cc:        hackers@FreeBSD.org, jb@cimlogic.com.au
Subject:   Re: int type in jmpbuf
Message-ID:  <199511200224.NAA25799@godzilla.zeta.org.au>

next in thread | raw e-mail | index | archive | help
>>>typedef struct {
>>> 	char _jb0[_THE_FULL_SIZEOF_JMP_BUF];
>>>} jmp_buf[1];
>>
>>The latter is only guaranteed to be aligned on 1-byte boundaries.

>And it needs to be aligned so that the asm code can access it?

Only so that it can be accessed fast.  Unless the process enables
alignment checking by setting PSL_AC in %ef.

>>It's supposed to be opaque to stop that :-).

>Or was it opaque 'cause the only thing that accessed it was asm code which
>couldn't use a structure anyway?

I originally made it opaque to detect (at compile time) anything that
was accessing it directly so that such things could be updated to match
some changes to the asm code.  No such things were found.

>Would it be evil if it were _not_ opaque under FreeBSD?

It would require more support (something like sys/i386/i386/genassym.c
to keep the asm offsets in sync with the C offsets).

>>You should copy setjmp.S
>>and adapt it.  Note that it isn't possible to do preemptive context
>>switching for threads using only setjmp() - setjmp() doesn't preserve
>>all of the floating point state in FreeBSD.

>I don't agree with this. gcc under FreeBSD appears to re-load floating point
>"registers" after a function call (like setjmp). This means that setjmp/longjmp
>don't need to save the floating point state.

gcc only guarantees/requires that the floating point stack is empty
before and after function calls (except for functions that return
double, the value is returned on the FP stack) and that the FP control
word is preserved across function calls.  FreeBSD's setjmp/longjmp does
the minimum amount of work required to preserve just this much of the FP
state.

>When a signal occurs, though, the floating point state is not saved. [We think
>it should be saved. Is there anything that says that floating point 
>calculations in a signal handler can ruin your whole day?! 8-)]. This is
>true of FreeBSD and NetBSD/i386, but it is _not_ true of NetBSD/Alpha which
>saves floating point registers routinely.

POSIX.1 (3.3.1.3(3)(b)) seems to require saving the FP state although
ANSI C doesn't.  Saving the state would mainly slow down signal
handling.  The original state would have to be saved in `struct
sigcontext' for _all_ signals and restored after each sigreturn().
SIGFPE and context-swiitching SIG*ALRM handlers would have to do a
little more work to get at the original state.  longjmp() would still
have to restore the FP control word on the i386 (the kernel can't
resonably know what the process's normal FP control word is so it would
have to supply a fixed default for signal handlers (the same one that it
provided at exec time).  longjmp() can't just accept this default
because the process might have changed the control word).

>Preemptive context switching in user-space threads under FreeBSD needs to
>save the floating point state when entering the scheduler from the signal
>handler. Before calling sigreturn to re-start an interrupted thread (as 
>opposed to one that was simply context switched using setjmp), the floating
>point state is restored. This means that the behavio[u]r of a signal handler
>under a threaded program will not corrupt the floating point state of a 
>program as it will with a non-threaded program.

You'll have to worry about the i387 (separate) coprocessor bug as in the
kernel: fnsave/frstor may trigger an FPU trap that is not supposed to
occur until the next _non control_ FPU instruction.  The kernel protects
itself by masking the traps until user mode is resumed, but the
transparency of the context switch is lost.

Bruce



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199511200224.NAA25799>