Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Wed, 6 Jul 2011 22:56:29 -0400
From: Rich Felker <dalias@...ifal.cx>
To: musl@...ts.openwall.com
Subject: Re: errno (was: Weekly reports - B)

On Wed, Jul 06, 2011 at 03:35:08PM +0400, Solar Designer wrote:
> Rich,
> 
> On Mon, Jun 13, 2011 at 12:54:18AM -0400, Rich Felker wrote:
> > ... errno is a macro and has been for a
> > long time (ever since threads) on most systems. It's required by the
> > standard to be an lvalue macro.
> 
> Any idea why glibc has __set_errno() internally instead of assigning to
> its errno directly, then?  The implementation for __set_errno() does a
> direct assignment anyway.  What did the glibc developers need
> __set_errno() for if errno is required to be an lvalue, and do they
> still need __set_errno() or is it legacy?

While this doesn't necessarily answer the historical question of
whether or why it may have been needed, I think part of the reason for
__set_errno (especiall in uclibc which uses a similar approach) might
be keeping down code size or improving performance. Simple assignment
to errno requires saving the value to be stored to errno in a
non-call-clobbered register or on the stack, making a call to
__errno_location, then reading back the saved error value and storing
it at the address returned by __errno_location. On the other hand,
with __set_errno, the process is just a single function call and the
error value does not need to be saved for use after the call returns.

Further, with NPTL's TLS model, it's possible to make __set_errno more
efficient than using __errno_location would be. The latter is
basically:

mov %gs:0,%eax
add $ERRNO_OFFSET,%eax
ret

while __set_errno can be purely:

mov 4(%esp),%eax
mov %eax,%gs:ERRNO_OFFSET
ret

And if you declare it regparm, you could even throw away the first
instruction... Or you could just make it an inline function and get
even bigger benefits (no actual call, on register spills, etc.)

Personally, in musl I've avoided doing things like this in favor of
simplicity. Presumably errno getting set should be a fairly uncommon
occurrance anyway, so speed isn't all that important, and I like code
that reads as plain C that could just as well be part of any
implementation of the standard library rather than being full of
implementation-specific tricks...

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.