[Bug 206146] fileno(3) should be implemented as a function; need to check other functions as well

Bruce Evans brde at optusnet.com.au
Tue Jan 12 14:42:56 UTC 2016


On Tue, 12 Jan 2016 bugzilla-noreply at freebsd.org wrote:

> https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=206146
>
> David Chisnall <theraven at FreeBSD.org> changed:
>
>           What    |Removed                     |Added
> ----------------------------------------------------------------------------
>                 CC|                            |theraven at FreeBSD.org
>
> --- Comment #2 from David Chisnall <theraven at FreeBSD.org> ---
> I think that's pretty clear.  It *must* be a function.  It *may* also be a

The mail unserver doesn't quote context for "that".

> macro.  It currently is a function and a macro, but the function is external
> and so if you #undef the macro you get worse performance.

This is correct.  The implementation using a macro is about as good as
possible.  It was a trivial macro before it had the __isthreaded test
and is still simple.

However, its implementation in the __isthreaded case is nonsense.  The
file must be locked by the caller to use fileno().  Locking for just
the read of of the number is useless without locking in the caller to
prevent it changing immiedately after it is read.  Locking in the
function just gives a more atomic memory access to up more up to date
garbage.

Don't #undef the macro unless you want worse performance or want to
take the function's address.  Don't #undef it at all.  Just avoid any
macro definition by parenthesizing the function name, like <stdio.h>
does to pessimize the threaded case for getc and putc.

> There are a number
> of cases like this, where we should be defining an inline function instead of a
> macro.
>
> This also makes building language bridges harder than it needs to be on
> FreeBSD.

This is mostly backwards.  The prototype for the function is required to
exist in <stdio.h>, and the function is required to exist in libc.  These
are harder to avoid than any macro.  Using inline functions doesn't
change this, but increases complications with namespaces for things
used in the implementation of the inline functions (the same things in
macros have no effect unless the macros are actually used).

Bruce


More information about the freebsd-standards mailing list