From owner-freebsd-hackers@FreeBSD.ORG Thu Apr 2 00:12:13 2009 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 4056B106566C for ; Thu, 2 Apr 2009 00:12:13 +0000 (UTC) (envelope-from deischen@freebsd.org) Received: from mail.netplex.net (mail.netplex.net [204.213.176.10]) by mx1.freebsd.org (Postfix) with ESMTP id 0E4E38FC14 for ; Thu, 2 Apr 2009 00:12:12 +0000 (UTC) (envelope-from deischen@freebsd.org) Received: from sea.ntplx.net (sea.ntplx.net [204.213.176.11]) by mail.netplex.net (8.14.3/8.14.3/NETPLEX) with ESMTP id n320C8wW016010; Wed, 1 Apr 2009 20:12:08 -0400 (EDT) X-Virus-Scanned: by AMaViS and Clam AntiVirus (mail.netplex.net) X-Greylist: Message whitelisted by DRAC access database, not delayed by milter-greylist-4.0 (mail.netplex.net [204.213.176.10]); Wed, 01 Apr 2009 20:12:09 -0400 (EDT) Date: Wed, 1 Apr 2009 20:12:08 -0400 (EDT) From: Daniel Eischen X-X-Sender: eischen@sea.ntplx.net To: Dmitry Marakasov In-Reply-To: <20090401231831.GS1964@hades.panopticon> Message-ID: References: <20090401231831.GS1964@hades.panopticon> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed Cc: freebsd-hackers@freebsd.org, freebsd-ports@freebsd.org Subject: Re: -pthread propagation X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Daniel Eischen List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Apr 2009 00:12:13 -0000 On Thu, 2 Apr 2009, Dmitry Marakasov wrote: > Hi! > > I have a question about -pthread. Imagine the situation where one port > installs shared library that uses threads, and other port links with > this library. A question: should the second port explicitely add > -pthread to linker flags? Yes. > For example, graphics/ilmbase is built with pthread support by default, > but it's shared libraries are not linked with -pthread: > > % ldd /usr/local/lib/libIlmThread.so > /usr/local/lib/libIlmThread.so: > libIex.so.6 => /usr/local/lib/libIex.so.6 (0x2819c000) > libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x28300000) > libm.so.5 => /lib/libm.so.5 (0x281ad000) > libc.so.7 => /lib/libc.so.7 (0x2808b000) > libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x281c6000) > > no libthr.so mention. Thus, > > % gcc helloworld.cc -lIlmThread -L/usr/local/lib > /usr/local/lib/libIlmThread.so: undefined reference to `pthread_create' > > I assume this should be fixed in ilmbase instead of all dependent ports > (for example, graphics/nvidia-texture-tools and graphics/devil, which > supports the former), am I right? Btw, libIlmThread.la _does_ have > -pthread in dependency_libs. Yes, all ports that use libraries that create threads on their behalf should use -pthread. > However, I've encountered situations where linking with library > linked with -pthread will succeed, but the resulting binary will not > be broken. Example is games/battletanks: This is probably because libc contains some simple thread wrappers (mostly lock related stuff). They go unused unless a thread is created (and libthr is explicitly brought in), in which case those wrappers are overridden by libthr. > When built as is (note that it has ${PTHREAD_LIBS} explicitely added to > LDFLAGS), it runs without problems. However, if you remove > ${PTHREAD_LIBS}, it'll still build successfully, but won't run: > > % bt > [03:04:45.449][src/main.cpp:44] [notice] starting up... version: 5800 beta > [03:04:45.449][src/main.cpp:46] [notice] mem avail: -1 mb > terminate called after throwing an instance of '__gnu_cxx::__concurrence_lock_error' > what(): __gnu_cxx::__concurrence_lock_error > [1] 58620 abort (core dumped) bt > > I think that's linked with static variable initialization - it should > be protected with a mutex in threaded environment, but it doesn't happen > correctly when linking without -pthread, even if with -lthr. It is possible for a library to be thread-aware and thread-safe. In this case it can play pragma weak games with "pthread_create" and only use locks if pthread_create resolves to a non-null pointer. > I'll be really grateful if someone explains what really happens when > using -lpthread, and what happens in the above mentioned error case > (cc'ing hackers@). > > So should -pthread be forced in ldflags > 1) Only in ports that explicitely use threads > 2) In all ports that link with -lthr implicitely, including through > other ports? It depends, libraries can be made thread-safe/aware as above, and both threaded and non-threaded applications can link with them just fine. Assuming those libraries are smart about how they use the locking mechanisms, and never use them unless they know that "pthread_create" is present (or some other symbol not present in libc, but present in libthr). But for libraries that create threads, applications must also link with -pthread (or -lpthread). If you can understand it, you can see src/contrib/gcc/gthr-posix.h for how libgcc is thread-aware. A comment from that file: /* On Solaris 2.6 up to 9, the libc exposes a POSIX threads interface even if -pthreads is not specified. The functions are dummies and most return an error value. However pthread_once returns 0 without invoking the routine it is passed so we cannot pretend that the interface is active if -pthreads is not specified. On Solaris 2.5.1, the interface is not exposed at all so we need to play the usual game with weak symbols. On Solaris 10 and up, a working interface is always exposed. On FreeBSD 6 and later, libc also exposes a dummy POSIX threads interface, similar to what Solaris 2.6 up to 9 does. FreeBSD >= 700014 even provides a pthread_cancel stub in libc, which means the alternate __gthread_active_p below cannot be used there. */ -- DE