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>