Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 16 Jan 2003 00:20:29 +1100 (EST)
From:      Bruce Evans <bde@zeta.org.au>
To:        Marcel Moolenaar <marcel@xcllnt.net>
Cc:        Terry Lambert <tlambert2@mindspring.com>, Jake Burkholder <jake@locore.ca>, <sparc@FreeBSD.ORG>, <current@FreeBSD.ORG>
Subject:   Re: [PATCH] Re: fpsetmask on sparc64
Message-ID:  <20030115233615.Y23066-100000@gamplex.bde.org>
In-Reply-To: <20030113204505.GA798@dhcp01.pn.xcllnt.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Mon, 13 Jan 2003, Marcel Moolenaar wrote:

> On Mon, Jan 13, 2003 at 10:21:59PM +1100, Bruce Evans wrote:
> > >
> > > This part is what makes me opt for moving the prototypes to the
> > > MD header. These functions are trivial most of the time that
> > > inlining them makes sense. I don't see why other platforms can't
> > > or won't inline in the future.
> >
> > Hand-inlining things rarely makes sense, especially for little-used
> > compatibility-cruft functions like these.
>
> Aahh.. But by hand-inlining compatibility cruft, you remove them
> from the ABI! You only have them in the API, which is the lesser
> evil of the two when you want to remove the compatibility cruft
> completely.

Good point.

I had intended to implement the compatibility cruft as calls to the new
(extern) interfaces or possibly as just weak aliases.

> > A technical reason for not inlining some of them is that they may need
> > to interact with signal handling.
>
> I don't see how this is related. The only advantage of not inlining
> is the ability to declare the functions as weak so that they can be
> overridden. In all other cases it's just an implementation detail
> that should not affect the functionality.
>
> > We currently avoid most signal-handling
> > problems related to changing the FP environment by switching the critical
> > part of the environment in setjmp/longjmp, at least on i386's, but C99
> > seems to forbid this.  I think the functions that change the FP environment
> > need to save their setting somehwere so that longjmp() can restore the
> > default FP environment (not necessarily the one when setjmp() was called).
> > I don't know how to do this properly reentrantly.
>
> On ia64 the FP environment is callee saved and thus put in jmpbuf.

This may be a bug.  Putting things in jmpbuf results in the local
environment being restored by longjmp(), but some readings of the C
standard require feset*() to alter a global environment which must
not be affected by setjmp()/longjump().

> The general modus operandi seems that functions either use the
> settings as inherited, or otherwise explicitly set them. This also
> applies to signal handlers. Thus when the FP environment is changed
> at function entry, the only action required is to restore the FP
> environment at function exit.

Restoring the FP environment on function exit would clearly be wrong
for normal functions, since the function might have called feset*().
longmp() is different because it is specified to restore the environment
saved by setjmp().  The C standard also specifies that functions do not
change the FP modes or flags unless the function is documented to change
them and the issue is whether restoring the environment saved by setjmp()
includes the FP environment.

I don't see how longjmp() can work right unless it restores either the
local environment saved by setjmp() or a at least a global environment
saved by feset*() later.  E.g., gcc implements float-to-int conversions
by temporarily switching the rounding mode.  longjmp() from a signal
handler that interrupts the conversion must restore the mode to a
default since the inline code that restores it will not be reached.
This seems to be still broken in glibc-2.2.5 on i386's.  Most arches
hopefully don't have this problem because the rounding mode can be
set for individual instructions and/or there are special instructions
for doing the conversions.

FreeBSD on i386's restores only the control word in longjmp().  It
clobbers the status word.  Not touching at least the exception flags
in the status word seems to be right.  The exception flags are
supposed to be sticky and clearing them in longjmp() breaks this.

> > > Also, it appears to me that we always have to provide non-inlined
> > > versions in libc for when inlining is disabled. See ctype.h.
> > > I may misinterpret the comment though...
> >
> > Non-inline versions are needed for at least calling functions through
> > function pointers if this is supported, and C requires it to be supported
> > for most functions including the ctype 1's.  This requirement causes
> > some of the implementation complications in <ctype.h>.
>
> I see. Using static inline functions rather than macros should mostly
> solve this. Function pointer comparison will not work though, but I
> don't know if it has to.

I think it doesn't in C90+gcc at least, but having lots of static
copies of the same function bloats the code and is painful to debug.

C99's inline functions are a little different from gcc's.  I don't
remember many details.  In theory, "extern inline" is more suitable
here, but C99 doesn't have it and "static inline" is easier to use.


Bruce


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-current" in the body of the message




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