This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC 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: question on semantics


On Wed, May 04, 2005 at 11:59:49AM -0600, Chris Friesen wrote:

> Without the locks, the compiler is free to only load *b once (and in 
> fact gcc does so).  Is the addition of the locks sufficient to force *b 
> to be re-read each time, or do I need to declare it as
> 
As long as you keep 'b' pointing to memory outside the current
compilation unit, GCC will consider the calls to <lock> and
<unlock> as clobbering *b.  So, you shouldn't need to mark it
volatile.

However, you could get into trouble if you somehow managed to get
a local stack slot shared between threads:


int test()
{
    int *b;
    int a;

    b=&a;

    while(1) {
        <lock>
        if (*b) {
            break;
        }
        <unlock>
    }
    <unlock>

    return *b;
}

If you arrange things so that

- Threads share the same stack.
- The address of 'a' does not escape the current function

Then GCC will remove the second load from *b.  In fact, it will
change '*b'  to 'a'.

I very much doubt you can create that situation, however.
Sharing stack between threads will give you tons of other races
and you will always need to make the address of 'a' escape the
function somehow (e.g. when placing it in shared memory).

Since it is very unlikely for the compiler to inline the calls to
<lock> and <unlock>, the optimizers will treat those calls as
black boxes and will assume *b clobbered.


Diego.


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