Date: Thu, 19 Nov 2009 12:06:40 -0500 From: John Baldwin <jhb@freebsd.org> To: Daniel Eischen <deischen@freebsd.org> Cc: threads@freebsd.org Subject: Re: Using pthread_once() in libc Message-ID: <200911191206.40934.jhb@freebsd.org> In-Reply-To: <200911191202.30738.jhb@freebsd.org> References: <200911191030.14151.jhb@freebsd.org> <Pine.GSO.4.64.0911191143300.8401@sea.ntplx.net> <200911191202.30738.jhb@freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thursday 19 November 2009 12:02:30 pm 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: Perhaps this would work to fix pthread_once: Index: gen/_pthread_stubs.c =================================================================== --- gen/_pthread_stubs.c (revision 199529) +++ gen/_pthread_stubs.c (working copy) @@ -51,6 +51,8 @@ static int stub_main(void); static void *stub_null(void); +static int stub_once(pthread_once_t *once_control, + void (*init_routine)(void)); static struct pthread *stub_self(void); static int stub_zero(void); static int stub_true(void); @@ -105,7 +107,7 @@ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_LOCK */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_TRYLOCK */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_MUTEX_UNLOCK */ - {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_ONCE */ + {PJT_DUAL_ENTRY(stub_once)}, /* PJT_ONCE */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_DESTROY */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_INIT */ {PJT_DUAL_ENTRY(stub_zero)}, /* PJT_RWLOCK_RDLOCK */ @@ -301,3 +303,14 @@ { exit(0); } + +static int +stub_once(pthread_once_t *once_control, void (*init_routine)(void)) +{ + + if (once_control->state == ONCE_DONE) + return (0); + init_routine(); + once_control->state = ONCE_DONE; + return (0); +} -- John Baldwin
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200911191206.40934.jhb>