Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Fri, 25 Jul 2014 18:19:50 -0400
From: Rich Felker <dalias@...c.org>
To: musl@...ts.openwall.com
Subject: Re: C11 threads

On Fri, Jul 25, 2014 at 07:10:02PM +0200, Jens Gustedt wrote:
> > > > if glibc does the same then it's ok
> > > 
> > > At least from the project description it seems that they prospect an
> > > incremental implementation.
> > 
> > Yes, that was their decision and they were generally uninterested in
> > discussing whether it was the best decision. I tend to agree that it's
> > the right choice, but thought it could use more discussion before a
> > decision was made.
> 
> Ideally, yes. For the time being we can mark this feature as
> "experimental", I could even maintain this separately, if you
> want. But honestly I don't expect much reaction from anywhere.

Since glibc is going that way, I think we should keep the type sizes
the same but leave it explicitly undefined to mix calls to C11 and
POSIX functions on the same synchronization objects.

> > > C11 requires that the namespace not be polluted.
> > > 
> > > That conflict could be solved conveniently and easily by
> > > 
> > >  (1) compiling the same files twice and replacing the pthread symbol
> > >      by the other in the second compilation
> > > 
> > >  (2) copy the .o file and to some ld magic
> > > 
> > > Which one to choose?
> > 
> > Neither of these is very reasonable. Probably the best is to
> > namespace-protect (i.e. prefix with __ and add the external name as a
> > weak alias) all of the pthread functions which need to be used for
> > implementing C11 functions, then add either second weak aliases (if
> > the equal function pointer issue is not a problem and the signature is
> > identical) or thin wrappers (probably my preference anyway) for the
> > C11 functions to call the __pthread ones.
> 
> Basically what I had from the start is the variant with two sets of
> weak aliases.

OK. I didn't see that in your first email but perhaps I read it wrong.

> > The latter also allows us to add alternative implementations for the
> > C11 ones later on an incremental basis, if we want to.
> 
> I don't think that the weak alias approach inhibits this in any way.

It doesn't; I just meant that having the separate file/function
already in place makes the change smaller if we add an independent
implementation. But I agree it's a small difference and probably was
pointless to mention.

> > I generally
> > don't like the whole C11 threads mess, but the one potential advantage
> > they have is having weaker semantics which may allow better
> > performance,
> 
> The weaker semantic is effectively too weak, and there are ongoing
> efforts to amend that.

Could you elaborate? Perhaps we're thinking of different things.

One aspect is that all POSIX synchronization functions are full
barriers, whereas presumably the C11 ones are proper acquire/release
barriers as appropriate for the operation being performed.

Another is Austin Group issue #755, which I'm hoping the WG14 will not
rule the same way on. The Austin Group's resolution for POSIX mutexes
makes recursive and error-checking mutexes very expensive and requires
threads to maintain a record of all such mutexes they own. I have not
yet implemented this in musl but I plan to do so soon (BTW this needs
to be added to the roadmap).

> The advantages that I see that this doesn't need all that attr stuff
> and has no concept of cancellation.

Cancellation is rather irrelevant to the synchronization primitives.
Obviously C11's lack of cancellation makes C11 threads much easier to
implement if you're not also doing POSIX threads, but if you're doing
both, the fact that C11 lacks a cancellation function makes almost no
difference (just one simple cleanup function in condvar wait).

> > and definitely allows smaller size if the application
> > only uses them (but of course makes libc.a and libc.so larger).
> 
> If we use weak aliases, this basically blows up the symbol table a
> bit.
> 
> When I strip my test executable, it is impressively small.

Yes, this is one reason I don't want __-prefixed symbols for
everything, just functions that really _need_ namespace-safe versions.
We should probably do some linking tests against all the C11 functions
to make sure they're not pulling in functions outside the C11
namespace and add __-prefixed versions of those functions only, rather
than preemptively trying to guess what needs protection.

> > > For the types this should be easy to have them typedef'ed to some
> > > opaque struct.
> > 
> > For the types that vary per-arch, I don't see any way around having
> > them in the alltypes.h.in bits.
> 
> The only types that seem to be in bits are mutex and condition. All
> others seem to be arch independent.

Ah yes the others are probably not needed for C11.

> On the long we should probably have __pthread names in the alltypes.h
> files and typedef these in pthread.h and threads.h respectively.

That doesn't work because both sys/types.h and pthread.h have to
expose the pthread names.

> > As for the constants, which ones are
> > you talking about?
> 
> the mtx_ constants are the critical ones.
> 
> thrd_error and friends can easily be mapped to EXXX error codes from
> errno.h. Since these names are all reserved anyway, including errno.h
> shouldn't do much harm.

I don't think including errno.h implicitly is permitted. E* is only
reserved when errno.h is included. Anyway this is somewhere we wasnt
to agree with glibc on the values; I suspect they'll just use values
1,2,... rather than errno codes. If so, that means we really need a
wrapper function rather than just an alias.

> > I don't think it's so easy to directly use the
> > POSIX ones for C11 since they have some different semantics (flag bits
> > vs enumeration-style) for a few.
> 
> the mtx_ ones are basically flags, just as the PTHREAD_MUTEX_ ones.
> This fits well with the actual values of these in musl.

The PTHREAD_MUTEX_* ones are not flags; each corresponds to a single
type and they are not combinable. The C11 ones are combinable, but
mtx_timed is useless -- there's no need to care whether it will be
used for timed operations when it's initialized.

BTW n1570 only has 4 possible values to pass to mtx_init, but reads
(7.26.4.2 p2):

"The mtx_init function creates a mutex object with properties
indicated by type, which must have one of the six values:"

Any idea if six is just a mistake or if there are some values missing
from the list?

> And then there is TSS_DTOR_ITERATIONS versus
> PTHREAD_DESTRUCTOR_ITERATIONS, not a big deal. We just have to agree
> on something.
> 
> > Also this is one area where we still
> > need to be careful to match the glibc ABI.
> 
> Sure. In particular we shouldn't change any existing ABI.

Beyond not changing any existing ABI, I want to aim for making any new
ABIs added compatible.

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.