This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] BZ #5784: Build libpthread.a with ld -r


On 9/6/2012 9:25 PM, Roland McGrath wrote:
> An alternative that's more different (and off hand seems vaguely worse to
> me), but perhaps is better in some way or other, is to make sure that
> libc defines redirector functions for every pthread_foo that libstdc++
> calls. Then if -lpthread is missing, the strong references are resolved
> to the libc definitions, which normally do nothing. This alternative has
> the advantage that, if paired with a b. solution for #1, it also
> correctly handles "dynamic static threadedness". I don't claim to have
> figured out every aspect of this yett, but what I've proposed avoids the
> pitfalls of the current libstdc++ strategy without inducing bloat. (It
> even allows us to get rid of the gratuitous bloat we already have induced
> in pthread_create.c today, if built to assume a new libstdc++.) I want
> people concerned with this bug to get serious about considering fleshing
> out something along these lines, rather than only looking for kludges to
> induce the bloat that works around libstdc++'s existing bad assumptions.

What libc currently does seems almost enough to handle this more cleanly,
but not quite.  There are function stubs in libc for pthread_mutex_lock(),
etc., that return 0 (or whatever) if libpthread hasn't been initialized,
and otherwise call through a function pointer.  I would think that simply
extending those function stubs to be slightly more complete might make the
picture better in general.

In particular, for libc.a we could include something similar to the
existing nptl/forward.c, which provides the function stubs, as well as the
no-op implementations, using __pthread_mutex_lock (e.g.) as the strong name
and providing pthread_mutex_lock weak names for everything.  (As usual,
this avoids namespace issues for programs that don't use <pthread.h> and
provide their own random functions in the pthread_ namespace.)

You could improve the performance of the stub routines by taking advantage
of the fact that all the no-op implementations are in one object file,
along with the __libc_pthread_functions structure definition that holds all
the pointers, and just statically initialize the structure with the no-op
functions.  This removes the need to test for __libc_pthread_functions_init
and makes it that much more efficient to call the stub functions when the
application is still single-threaded.

It does seem like if you did it this way, the upshot would be that all the
PTHREAD_STATIC_FN_REQUIRE stuff could be removed, and libstdc++ could just
directly call the pthread APIs it wants, at relatively low cost, without
having to worry about whether the application itself had linked against
-lpthread.  For the normal multithreaded case of linking with -pthread,
obviously libstdc++ gets the right APIs directly.  In the either the static
or dynamic case where -pthread is not used, libstdc++ just gets the no-op
functions in libc via the libc stubs, at a pretty low cost: a call, a jump
through a pointer, and a return with a nominal zero or error value.

While we're at it, it does seem like we're close to being able to support
libpthread.so being late-loaded.  For example, the no-op
pthread_mutex_init() could actually initialize a mutex structure properly,
even in a single-threaded build.  That way if the application later
dlopen()'s a DSO that depends on libpthread.so, things will actually work
correctly if that mutex is then locked/unlocked, despite the fact that we'd
then be using the "true" versions of lock/unlock. (I wonder if there's some
IFUNC-like mechanism we could invent for doing late rebinding of the GOT
arrays when libpthread is loaded to be even more efficient, but in any
case, that would be an optimization for another day.)

There is still Roland's question of providing an API for "are things
threaded", but perhaps libstdc++ wouldn't care any more so it would be
pragmatically a moot question.  Cancellation already works fine with the
internal APIs, so there's no rush to worry about that.  If needed as an
API, __glibc_is_threaded() seems pretty reasonable, or maybe we innovate in
the pthread namespace and export a __GNU_SOURCE pthread_is_threaded_np()
function.

As a general philosophy, my bias is to encourage programmers to be aware
enough of threading that they always think in terms of using the APIs
conservatively for locking, etc., even if the thing they're currently
coding up is not initially intended to run in a multi-threaded context.  It
makes reuse of such libraries in threaded applications easy and enables
better use of multicore processors as they become more and more the
standard case.

-- 
Chris Metcalf, Tilera Corp.
http://www.tilera.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]