Using pthread_once() in libc

Daniel Eischen deischen at
Thu Nov 19 20:00:21 UTC 2009

On Thu, 19 Nov 2009, John Baldwin wrote:

> On Thursday 19 November 2009 12:09:33 pm Daniel Eischen wrote:
>> On Thu, 19 Nov 2009, John Baldwin wrote:
>>> On Thursday 19 November 2009 11:48:54 am Daniel Eischen wrote:
>>>> On Thu, 19 Nov 2009, John Baldwin wrote:
>>>>> I would like to provide a pthread_once()-like facility in libc that library
>>>>> bits can use to initialize data safely rather than trying to home-roll their
>>>>> own variants (see the recent commit to stdtime in libc).  Ideally what I
>>>>> would like to do is have libc use the "real" pthread_once() when libthr is
>>>>> linked in and fall back to a simple stub without libthr linked in.  I know we
>>>>> already do something like this for _spinlock() and friends.  My question is
>>>>> what is the most correct way to do this?  Should libc grow a new _once()
>>>>> symbol ala _spinlock() that is a weak symbol to a stub version and
>>>>> pthread_once() in thr_once.c would override that, or should there be a
>>>>> _pthread_once() in libc that is a stub in place of the current stub_zero?  I
>>>>> noticed a comment in thr_spinlock.c saying the spinlock stuff is kept for
>>>>> backwards compat.  Does this mean that for the future we would like to expose
>>>>> pthread symbols directly in libc?  Meaning would we rather have libc export a
>>>>> pthread_once() and that ideally libc would be using pthread_mutex_lock/unlock
>>>>> instead of _spinlock/unlock?
>>>> pthread_once() is already a stub in libc that gets overloaded with the
>>>> real thing when libthr is linked.  See libc/gen/_pthread_stubs.c.
>>>> Isn't that what you want or does it not serve your purpose?
>>> Hmm, the libc stub will never run the init routine.  I would like to do
>>> something like this:
>> Well, I suppose you could do that.  But what happens if libthr gets
>> dlopen()'d and your once function needs to initialize a mutex or
>> something that can only be properly done by a real threads library?
>> Can we envision a scenario where that would be a problem?
> Hmmm, so I guess __is_threaded is how the dlopen() case is handled now for
> mutex lock/unlock as that avoids resolving the symbol until pthread_create()
> has been invoked?  I guess then we could take an approach that works
> something like this:
> /* libc-internal function */
> int
> _once(pthread_once_t *once_control, void (*init_routine)(void))
> {
> 	if (__is_threaded)
> 		return (_pthread_once(once_control, init_routine));
> 	return (_stub_once(once_control, init_routine));
> }
> It is probably still a good idea to have the stub_once() patch I think so
> that pthread_once() DTRT in a single-threaded program.

I guess that works.


More information about the freebsd-threads mailing list