From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7708 invoked by alias); 27 Aug 2013 02:29:27 -0000 Mailing-List: contact libc-ports-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Post: List-Help: , Sender: libc-ports-owner@sourceware.org Received: (qmail 7685 invoked by uid 89); 27 Aug 2013 02:29:26 -0000 Received: from 216-12-86-13.cv.mvl.ntelos.net (HELO brightrain.aerifal.cx) (216.12.86.13) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 27 Aug 2013 02:29:26 +0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL,BAYES_00,NO_RELAYS autolearn=ham version=3.3.2 X-Spam-User: qpsmtpd, 2 recipients X-HELO: brightrain.aerifal.cx Received: from dalias by brightrain.aerifal.cx with local (Exim 3.15 #2) id 1VE91s-0008Mz-00; Tue, 27 Aug 2013 02:29:12 +0000 Date: Tue, 27 Aug 2013 02:29:00 -0000 From: Rich Felker To: =?utf-8?B?T25kxZllaiBCw61sa2E=?= Cc: Carlos O'Donell , Torvald Riegel , GLIBC Devel , libc-ports Subject: Re: [PATCH] Unify pthread_once (bug 15215) Message-ID: <20130827022912.GI20515@brightrain.aerifal.cx> References: <1368024237.7774.794.camel@triegel.csb> <519D97E4.4030808@redhat.com> <20130826124955.GA6065@domone.kolej.mff.cuni.cz> <20130826164507.GA20515@brightrain.aerifal.cx> <20130826184150.GA8772@domone.kolej.mff.cuni.cz> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20130826184150.GA8772@domone.kolej.mff.cuni.cz> User-Agent: Mutt/1.5.21 (2010-09-15) X-SW-Source: 2013-08/txt/msg00048.txt.bz2 On Mon, Aug 26, 2013 at 08:41:50PM +0200, Ondřej Bílka wrote: > > No, pthread_once _calls_ tend to be once per access to an interface > > that requires static data to have been initialized, so possibly very > > often. On the other hand, pthread_once only invokes the init function > > once per program instance. I don't see anything that would typically > > happen once per thread, although I suppose you could optimize out > > calls to pthread_once with tls: > > > Could happen often but dees it? Given need of doing locking you need to > avoid it in performance critical code. With once per thread I meant an > patterns: > > computation(){ > pthread_once(baz,init); // Do common initialization. > pthread_create(foo,bar,routine); > } > > or > > pthread_create(foo,bar,routine); > > with > > routine() > { > pthread_once(baz,init); // Do common initialization. > ... > } These patterns arise is the library is making threads and using pthread_once to initialize its static data before making the thread. I'm thinking instead of the case where your library is being _called_ by multi-threaded code, and using pthread_once to ensure that its data is safely initialized even if there are multiple threads which might be racing to be the first caller. > > static __thread int once_done = 0; > > static pthread_once_t once; > > if (!once_done) { > > pthread_once(&once, init); > > once_done = 1; > > } > > > > This requires work at the application level, though, and whether it's > > a net advantage depends a lot on whether multiple threads are likely > > to be hammering pthread_once on the same once object, and whether the > > arch has expensive acquire barriers and inexpensive TLS access. > > > Actually you can use following if you are concerned about that use cases: > > #define pthread_once2(x,y) ({ \ > static __thread int once = 0; \ > if (!once) \ > pthread_once(x,y); \ > once=1; \ > }) Indeed; actually, this could even be done in pthread.h, with some slight variations, perhaps: #define pthread_once(x,y) ({ \ pthread_once_t *__x = (x); \ static __thread pthread_once_t *__once; \ if (__once != __x) { \ pthread_once(__x,y); \ __once = __x; \ } \ }) Rich