From owner-freebsd-threads@FreeBSD.ORG Thu Nov 19 17:06:45 2009 Return-Path: Delivered-To: threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 07084106568D; Thu, 19 Nov 2009 17:06:45 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from cyrus.watson.org (cyrus.watson.org [65.122.17.42]) by mx1.freebsd.org (Postfix) with ESMTP id B79578FC13; Thu, 19 Nov 2009 17:06:44 +0000 (UTC) Received: from bigwig.baldwin.cx (66.111.2.69.static.nyinternet.net [66.111.2.69]) by cyrus.watson.org (Postfix) with ESMTPSA id 49CD746B03; Thu, 19 Nov 2009 12:06:44 -0500 (EST) Received: from jhbbsd.hudson-trading.com (unknown [209.249.190.8]) by bigwig.baldwin.cx (Postfix) with ESMTPA id 422968A020; Thu, 19 Nov 2009 12:06:43 -0500 (EST) From: John Baldwin To: Daniel Eischen Date: Thu, 19 Nov 2009 12:06:40 -0500 User-Agent: KMail/1.9.7 References: <200911191030.14151.jhb@freebsd.org> <200911191202.30738.jhb@freebsd.org> In-Reply-To: <200911191202.30738.jhb@freebsd.org> MIME-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Content-Disposition: inline Message-Id: <200911191206.40934.jhb@freebsd.org> X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.0.1 (bigwig.baldwin.cx); Thu, 19 Nov 2009 12:06:43 -0500 (EST) X-Virus-Scanned: clamav-milter 0.95.1 at bigwig.baldwin.cx X-Virus-Status: Clean X-Spam-Status: No, score=-2.5 required=4.2 tests=AWL,BAYES_00,RDNS_NONE autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on bigwig.baldwin.cx Cc: threads@freebsd.org Subject: Re: Using pthread_once() in libc X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 19 Nov 2009 17:06:45 -0000 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