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: Async-signal-safe access to __thread variables from dlopen()ed libraries?


On Mon, 2013-10-07 at 18:53 -0400, Rich Felker wrote:
> On Tue, Oct 08, 2013 at 12:50:37AM +0300, Torvald Riegel wrote:
> > I don't think it matters whether we're dealing with a char type or, say,
> > an int; both don't require the compiler to ensure that observations by
> > signal handlers return meaningful values.  Let's look at an example:
> > 
> > char foo = 1;
> > 
> > void handler() { x = foo; } // Can it read 42?
> > 
> > foo = 2;
> > *p = 0; // This causes a signal to be handled.
> > foo = 3;
> > 
> > Can the handler read a value of 42 for foo?  I think this is allowed
> > behavior because the compiler can assume that the accesses to foo are
> > sequential; thus, it could for example reuse the variable's memory
> > location for other stuff (eg, it's stack slot).  The handler could
> > probably also read 1, because the compiler could just remove the (dead)
> > store of 2.
> > 
> > Why do you think that optimizations like those mentioned above would be
> > disallowed for char types?
> 
> I don't. It's not disallowed for sig_atomic_t either. The magic
> ingredient that disallows these optimizations is volatile.

Well, if you meant *volatile* char, I can sort of follow your thoughts.
However, I think it's up to the standards committees to decide whether
they want to just offer sig_atomic_t or extend it to char.  I don't see
much benefit of extending it to char.

> But you
> can't just use volatile with any type to communicate between signal
> handlers and the main flow of execution; you have to use sig_atomic_t
> too. Why? As I see it, there are two reasons:
> 
> 1. In general, objects could be written as multiple parts (for
>    example, on x86_64, 64-bit values are sometimes written as two
>    32-bit slots). Note that this could never apply to char unless you
>    had a pathological architecture with only single-bit writes or
>    similar.
> 
> 2. Conversely, prior to C11 (and only on non-POSIX implementations)
>    objects could be written as a read-modify-write cycle on a larger
>    unit of memory. This could have applied to char types in the past,
>    but it's no longer permitted. (As you noted before, it could still
>    be implemented under the hood with a read-modify-CAS loop, but
>    since this is not observably different from writing the
>    correct-sized object, it doesn't matter.)
> 
> My view is that, since reason 1 never applies to char types (modulo
> the pathological/hypothetical bit-based arch) and reason 2 can no
> longer apply anywhere, "volatile char" should be just as valid to
> access from signal handlers as "volatile sig_atomic_t" is.
> 
> By the way, if you haven't already, please see my related open issue
> on the Austin Group tracker:
> 
> http://austingroupbugs.net/view.php?id=728
> 
> I don't claim it's entirely (or even nearly) correct at this point,
> but it's a starting point for fixing some of these things.

If you want to see changes in this area, I'd suggest to also reach out
to the C and C++ committees.  They have specified more detailed memory
models, and this really is a programming language aspect; so, my guess
would be that it's easier and more likely for C/C++ to come up with a
more precise specification than for POSIX.


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