This is the mail archive of the
mailing list for the glibc project.
Re: Async-signal-safe access to __thread variables from dlopen()ed libraries?
- From: Rich Felker <dalias at aerifal dot cx>
- To: Torvald Riegel <triegel at redhat dot com>
- Cc: Carlos O'Donell <carlos at redhat dot com>, Ian Lance Taylor <iant at google dot com>, Paul Pluzhnikov <ppluzhnikov at google dot com>, Roland McGrath <roland at hack dot frob dot com>, Richard Henderson <rth at twiddle dot net>, GNU C Library <libc-alpha at sourceware dot org>, Andrew Hunter <ahh at google dot com>, Alexandre Oliva <aoliva at redhat dot com>
- Date: Mon, 7 Oct 2013 14:16:20 -0400
- Subject: Re: Async-signal-safe access to __thread variables from dlopen()ed libraries?
- Authentication-results: sourceware.org; auth=none
- References: <20130920175246 dot GE20515 at brightrain dot aerifal dot cx> <1380705404 dot 8757 dot 1847 dot camel at triegel dot csb> <20131002205046 dot GT20515 at brightrain dot aerifal dot cx> <1381010778 dot 8757 dot 3460 dot camel at triegel dot csb> <20131006053800 dot GQ20515 at brightrain dot aerifal dot cx> <1381095401 dot 8757 dot 3814 dot camel at triegel dot csb> <20131006214057 dot GA14037 at brightrain dot aerifal dot cx> <1381096560 dot 8757 dot 3846 dot camel at triegel dot csb> <20131007141425 dot GU20515 at brightrain dot aerifal dot cx> <1381168100 dot 8757 dot 4498 dot camel at triegel dot csb>
On Mon, Oct 07, 2013 at 08:48:20PM +0300, Torvald Riegel wrote:
> On Mon, 2013-10-07 at 10:14 -0400, Rich Felker wrote:
> > On Sun, Oct 06, 2013 at 11:56:00PM +0200, Torvald Riegel wrote:
> > > On Sun, 2013-10-06 at 17:40 -0400, Rich Felker wrote:
> > > > On Sun, Oct 06, 2013 at 11:36:41PM +0200, Torvald Riegel wrote:
> > > > > > My point is that char seems to automatically have this property on any
> > > > > > sane hardware, because, per the the POSIX and C11 memory models, you
> > > > > > can't access char objects as a read-modify-write sequence on a larger
> > > > > > unit of storage; you must perform single-byte accesses.
> > > > >
> > > > > The compiler could still do "arbitrary" stuff to non-atomic and
> > > > > non-volatile char variables (reordering accesses, ...), provided that
> > > > > when assuming a sequential program, the program would behave as if the
> > > > > abstract machine would execute it. The atomics tell the compiler to not
> > > > > assume that this is sequential code; therefore, a char-typed variable
> > > > > doesn't have the stronger properties automatically.
> > > >
> > > > Adding volatile (which, BTW, also needs to be added to sig_atomic_t)
> > > > would avoid these ordering issues.
> > >
> > > It would prevent some of them -- but then we're talking not about plain
> > > char-typed variables anymore. Also, volatiles and atomics aren't the
> > > same thing;
> > I'm quite aware. None of this discussion has been about atomics in the
> > C11 or C++11 sense. The word "atomic" here has nothing to do with
> > synchronization between cores. In sig_atomic_t, it's just a part of
> > the name; in other usages, it's described the property whereby partial
> > changes to the object are never observed (described more precisely
> > earlier in this thread).
> IIRC, it's not specified on which thread a signal handler will be
> executed, so it might execute concurrent accesses.
This is a separate issue which is actually easier to deal with (using
atomics in the C11 sense) if needed. For the purposes of this
discussion, we can assume the signal handler and other accessess to
the object are occurring in the same thread, which is guaranteed in
any of the following situations (and possibly others I missed):
1. All other threads have the signal masked.
2. The signal is generated by pthread_kill.
3. The signal is generated synchronously by an action of the thread
(e.g. SIGFPE, SIGPIPE, SIGBUS, SIGSEGV, etc.).
> > > > > multi-byte accesses with atomic read-modify-write ops as long as it
> > > > > makes sure that those don't overlap with volatiles or similar.
> > > >
> > > > Is that observably different from a single-byte write? I don't think
> > > > so.
> > >
> > > That's the point: The compiler must not necessarily use single-byte
> > > accesses, as you seemed to say (see above).
> > The physical mechanism is irrelevant. If something is not observably
> > different from a single-byte write, then, for purposes of this
> > discussion, it's a single-byte write. The point, in any case, is that
> > the observable behavior must be as if single-byte writes exist and are
> > used for writing char-type objects. Of course, in some cases (e.g. if
> > multiple chars at adjacent addresses are written) then the compiler
> > can combine them without any observable effect.
> There is a difference whether the observer can only be the same thread
> (ie, as with types that are neither atomic, sig_atomic, nor volatile) or
> whether observers can include other threads or signal handlers. You
> cannot just throw char into the same bucket as atomics, sig_atomic_t, or
I'm not throwing any of them into the same bucket. What I'm saying is
that, for the purpose of defining a memory model for access to objects
from signal handlers, char type objects should be on equal ground as
sig_atomic_t. Previously they weren't, presumably because
implementations could theoretically implement char writes as a
read-modify-write cycle where the signal handler could be invoked
between the read and the write. With C11 or POSIX, such an
implementation is not valid, and thus I see no reason not to grant
char types the same privilege as sig_atomic_t has.