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 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. 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.

Rich


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