static linking for pthreads in nptl branch?

Carmelo AMOROSO carmelo.amoroso at st.com
Tue Sep 2 14:06:28 UTC 2008


Chris Metcalf wrote:
> On 9/1/2008 11:29 AM, Carmelo Amoroso wrote:
>> Chris Metcalf wrote:
>>> It looks like my real problem was specific to some changes I made in our
>>> malloc.  We use the "mspace" malloc that is in later versions of Doug
>>> Lea's malloc, and one thing we do for performance is to give each thread
>>> its own mspace arena for allocation.  To make this fast for
>>> single-threaded programs we have a stub pthread_mspace() routine in libc
>>> and the real one in libpthread.  But if it's only referenced from libc
>>> (from malloc), then when a static link is done, we end up getting the
>>> single-threaded version from libc instead of the multi-threaded version
>>> in libpthread.  (Of course it works fine with shared objects.)
>>>
>>> For now I'm fixing this by adding a dummy reference to pthread_mspace
>>> from nptl/init.c so it always gets resolved early enough in the static
>>> link process.  It seems like any pthread symbols not explicitly
>>> mentioned in nptl/pthread_create.c would have this problem too, though:
>>> for example, if you had a function in libc that wanted to be thread-safe
>>> when linked with -pthread and so called pthread_mutex_init() to set up a
>>> mutex in malloc'ed memory (for example), it would actually end up
>>> getting the libc version of pthread_mutex_init() when linked
>>> statically.  The libpthread versions of pthread_mutex_lock() and unlock
>>> are linked in properly since they're referenced in pthread_create().
>>>
>>> I suspect the solution to all of this is to make sure to always
>>> "register" the correct function pointers for the whole API when
>>> libpthread's initialization code is called, so that the libc versions
>>> always end up doing a lookup on the registered function pointer and
>>> calling that, even with static linking.
>>>
>>
>> I understand your point, but can we say that we are building
>> a multi-threaded application if we don't call pthread_create
>> (that means linking pthread_create.o) ?
> 
> Sorry I wasn't clear.  Supposing we have a static library (or a function
> in libc.a) that wants to be thread-safe if it's linked with pthread, and
> still work if it's used in a single-thread program.  It calls
> pthread_mutex_init().  The main program does call pthread_create(), so
> when we link statically we do get a bunch of non-stub pthread functions
> -- but not pthread_mutex_init(), which we still get the stub for (unless
> the main program also called it).  Oops!  :-)
> 
Hi Chris,
I had to read it more carefully.. you are right, and yes, probably the 
issue you were referring to about static link and pthread was raised by 
me in the past.
It was related to opendir function that is the only function within libc
that calls pthread_mutex_init, and yes, when statically linked, even if 
using -lpthread, it was bind to the libc stub. At that time I fixed 
opendir by adding a memset to clear the lock data.
(see http://www.uclibc.org/cgi-bin/viewcvs.cgi?rev=20625&view=rev)

What about adding PTHREAD_STATIC_FN_REQUIRE (pthread_mutex_init)
in nptl/init.c ? were you thinking to this with the word 'register'.
I did not test it, but it may be sufficient.


>> I think that you should define your stub for mspace as weak,
>> and, for the static case, call it by guarding against NULL...
>> if I've understood it correctly.
> 
> I don't think weak will help in this case.  The weak undef will still
> just bind to the libc version, even if it's a weak def and the
> libpthread one is strong.
> 
yes, you're right.
> Thanks!
> 
Cheers,
Carmelo



More information about the uClibc mailing list