Subject: Re: Threading problems
To: Bill Studenmund <wrstuden@netbsd.org>
From: Eric Haszlakiewicz <erh@jodi.nimenees.com>
List: tech-kern
Date: 11/23/2004 14:58:54
On Tue, Nov 23, 2004 at 12:07:55PM -0800, Bill Studenmund wrote:
> We do this trick via weak aliasing of symbols. All these routines 
> (look in lib/libc/thread-stub/thread-stub.c) have weak aliases to 
> internal, do-little routines. Like the mutex lock & unlock routines map to 
> the one you saw. libpthread, however, has strong symbols for all of these 
> routines. So if libpthread is around at initial link (program launch), 
> these libc calls point to routines in libpthread (that know how to handle 
> mutexes, etc.). If not, they point to routines to ensure that libpthread 
> didn't get dlopen()'d.
> 
> The reason libc kills the program if libpthread gets loaded later is that
> there is no way libc's routines can recover. The lock & unlock routines
> point to code that doesn't know how to deal with mutexes. Even if we did
> magically change all of the calls in libc into ones that dealt with
> mutexes, mutexes and condvars didn't get initialized at startup. So there 
> isn't anything for them to work on.

	So why don't we initialize them then?  I can see how we would want to
avoid taking the performance hit on locking for programs that don't need
it, but wouldn't the impact of initialization be much smaller? 
	I can imagine building programs like postgres, that use dlopen, with
a "might-use-pthread" setting that turns on the initialization code.  Perhaps
the setting would be based on whether the program uses dlopen(), which
could be checked by ld.elf_so.  If dlopen() is used and loads libpthread
then it'd have to swap the weak references, which I'm guessing only
ld.elf_so does now.

eric