This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Unify pthread_once (bug 15215)


On Mon, Aug 26, 2013 at 12:45:07PM -0400, Rich Felker wrote:
> On Mon, Aug 26, 2013 at 02:49:55PM +0200, OndÅej BÃlka wrote:
> > On Thu, May 23, 2013 at 12:15:32AM -0400, Carlos O'Donell wrote:
> > > On 05/08/2013 10:43 AM, Torvald Riegel wrote:
> > > > Note that this will make a call to pthread_once that doesn't need to
> > > > actually run the init routine slightly slower due to the additional
> > > > acquire barrier.  If you're really concerned about this overhead, speak
> > > > up.  There are ways to avoid it, but it comes with additional complexity
> > > > and bookkeeping.
> > > 
> > > We want correctness. This is a place where correctness is infinitely
> > > more important than speed. We should be correct first and then we
> > > should argue about how to make it fast.
> > >
> > As pthread_once calls tend to be called once per thread performance is
> > not an issue. 
> 
> 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.
    ...
  }

>     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;                       \
})

> Rich


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]