I'd like to answer one last argument, mostly for the sake of curious
reader, because Michael himself has agreed with (at least the part of)
the point.


On Mon, Oct 29, 2007 at 16:00:18 +0100, Michael Matz wrote:
> The issue is, that people want to write this:
> 
>   if (condition)
>     *p = value;
> 
> (i.e. without any synchronization primitive or in fact anything else after 
> the store in the control region) and expect that the store indeed only 
> happens in that control region.  And this expectation is misguided.  Had 
> they written it like:
> 
>   if (condition) {
>     *p = value;
>     membarrier();
>   }
> 
> it would have worked just fine.

Even if we put aside the fact that there's no such membarrier()
equivalent in POSIX bindings, this won't help.

First of all, let's note that you can't break the program by making it
_more_ ordered.  Indeed, program correctness doesn't depend on some
particular reordering (you can't predict it anyway), it depends only
on some particular ordering.  So we can rewrite

  if (condition) {
    *p = value;
    membarrier();
  }

as

  if (condition) {
    *p = value;
    membarrier();
  } else {
    membarrier();
  }

But this is the same as

  if (condition)
    *p = value;
  membarrier();

and we are back to the start: the store could me moved outside the
condition.  In general the following would work

  if (condition) {
    *p = value;
    opaque_function();
  }

because GCC has to assume that the call may access any memory, thus
store to *p can't be moved outside of the condition, because the call
itself can't be moved outside.  But such a construction can't be the
requirement for threaded programming.


In the original example there _were_ synchronization primitives
already, the complete piece is:


  if (condition)
    pthread_mutex_lock(&mutex);

  ...

  if (condition)
    *p = value;

  ...

  if (condition)
    pthread_mutex_unlock(&mutex);


and POSIX doesn't require any additional ordering between lock() and
unlock().  When condition is false, any speculative store to *p is
bogus, because any condition is potentially a 'lock acquired'
condition (or 'not read-only' condition).  And it was shown that the
volatile qualifier can't be applied in general case.


But perhaps I'm the only one who is still unsure about the outcome of
this discussion :).


-- 
   Tomash Brechko

Reply via email to