[PATCH] Unify pthread_once (bug 15215)
Torvald Riegel
triegel@redhat.com
Mon Apr 7 12:38:00 GMT 2014
On Fri, 2014-03-28 at 19:29 -0400, Carlos O'Donell wrote:
> David, Marcus, Joseph, Mike, Andreas, Steve, Chris,
>
> We would like to unify all C-based pthread_once implmentations
> per the plan in bug 15215 for glibc 2.20.
>
> Your machines are on the list of C-based pthread_once implementations.
>
> See this for the intial discussions on the unified pthread_once:
> https://sourceware.org/ml/libc-alpha/2013-05/msg00210.html
>
> The goal is to provide a single and correct C implementation of
> pthread_once. Architectures can then build on that if they need more
> optimal implementations, but I don't encourage that and I'd rather
> see deep discussions on how to make one unified solution where
> possible.
>
> I've also just reviewed Torvald's new pthread_once microbenchmark which
> you can use to compare your previous C implementation with the new
> standard C implementation (measures pthread_once latency). The primary
> use of this test is to help provide objective proof for or against the
> i386 and x86_64 assembly implementations.
>
> We are not presently converting any of the machines with custom
> implementations, but that will be a next step after testing with the
> help of the maintainers for sh, i386, x86_64, powerpc, s390 and alpha.
>
> If we don't hear any objections we will go forward with this change
> in one week and unify ia64, hppa, mips, tile, sparc, m68k, arm
> and aarch64 on a single pthread_once implementation based on sparc's C
> implementation.
So far, I've seen an okay for tile, and a question about ARM. Will, are
you okay with the change for ARM?
Any other objections to the updated patch that's attached?
> > + When forking the process, some threads can be interrupted during the second
> > + state; they won't be present in the forked child, so we need to restart
> > + initialization in the child. To distinguish an in-progress initialization
> > + from an interrupted initialization (in which case we need to reclaim the
> > + lock), we look at the fork generation that's part of the second state: We
> > + can reclaim iff it differs from the current fork generation.
> > + XXX: This algorithm has an ABA issue on the fork generation: If an
> > + initialization is interrupted, we then fork 2^30 times (30b of once_control
>
> What's "30b?" 30 bits? Please spell it out.
>
> > + are used for the fork generation), and try to initialize again, we can
> > + deadlock because we can't distinguish the in-progress and interrupted cases
> > + anymore. */
>
> Would you mind filing a bug for this in the upstream bugzilla?
https://sourceware.org/bugzilla/show_bug.cgi?id=16816
> It's a distinct bug from this unification work, but a valid problem.
>
> Can this be fixed by detecting generation counter overflow in fork
> and failing the function call?
Yes, but this would prevent us from doing more than 2^30 fork calls.
That may not be a problem in practice -- but if so, then we won't hit
the ABA either :)
> > + do
> > + {
> > + /* Check if the initialization has already been done. */
> > + if (__builtin_expect ((val & 2) != 0, 1))
>
> Use __glibc_likely.
>
> e.g. if (__glibc_likely ((val & 2) != 0))
>
> This is the fast path that we are testing for in the microbenchmark?
Yes.
> > + return 0;
> > +
> > + oldval = val;
> > + /* We try to set the state to in-progress and having the current
> > + fork generation. We don't need atomic accesses for the fork
> > + generation because it's immutable in a particular process, and
> > + forked child processes start with a single thread that modified
> > + the generation. */
> > + newval = __fork_generation | 1;
>
> OT: I wonder if Valgrind will report a benign race in accessing __fork_generation.
Perhaps. I believe that eventually, lots of this and similar variables
should be atomic-typed and/or accessed with relaxed-memory-order atomic
loads. This would clarify that we expect concurrent accesses and that
they don't constitute a data race.
[BZ #15215]
* nptl/sysdeps/unix/sysv/linux/sparc/pthread_once.c: Moved to ...
* nptl/sysdeps/unix/sysv/linux/pthread_once.c: ... here. Add missing
memory barriers. Add comments.
* sysdeps/unix/sysv/linux/aarch64/nptl/pthread_once.c: Remove file.
* sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c: Remove file.
* sysdeps/unix/sysv/linux/ia64/nptl/pthread_once.c: Remove file.
* sysdeps/unix/sysv/linux/m68k/nptl/pthread_once.c: Remove file.
* sysdeps/unix/sysv/linux/mips/nptl/pthread_once.c: Remove file.
* sysdeps/unix/sysv/linux/tile/nptl/pthread_once.c: Remove file.
Changelog.hppa:
[BZ #15215]
* sysdeps/unix/sysv/linux/hppa/nptl/pthread_once.c: Remove file.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: pthread_once.patch
Type: text/x-patch
Size: 29093 bytes
Desc: not available
URL: <http://sourceware.org/pipermail/libc-alpha/attachments/20140407/7887fdf3/attachment.bin>
More information about the Libc-alpha
mailing list