[concurrency-interest] Racy lazy initialization: blush test

Vitaly Davidovich vitalyd at gmail.com
Wed Feb 20 18:07:13 EST 2013


.net docs are clearly wrong.  Thread.VolatileRead() invokes
Thread.MemoryBarrier() after the read, thus preventing the reordering.  In
turn, Thread.VolatileWrite() issues MemoryBarrier() before the write,
preventing reordering in the other direction.  For some reason, they don't
mention this important bit.

Write to a volatile on x86/64 in .net means nothing in terms of codegen -
it's a plain mov.  In java, there's a fenced instruction (lock add rsp 0 or
the like) for volatile writes, and that's where the "disconnect" is.

Sent from my phone
On Feb 20, 2013 3:57 PM, "Dmitry Zaslavsky" <dmitry.zaslavsky at gmail.com>
wrote:

> My understanding of what Hans is saying:****
>
>
>
> 1. No races, no atomics = sc****
>
> I am not even adding anything to what Hans said****
>
>
>
> 2. No races but volatiles (Java) or atomics (c++) you get SC.****
>
>
>
> And this is where C# differs or at leastthings become interesting.****
>
> In Dekkers algorithm even if you make the2 variables volatile you still
> have a broken code in c#.****
>
> In .net volatile read has acquire semantics as in no reads pass it. Using
> language from****
>
> http://g.oswego.edu/dl/jmm/cookbook.htmlon StoreLoad java would do a
> fence of sorts on x86 and .net (at least v4) doesn’t.****
>
>
>
> From I.12.6.7 of the .net spec volatile read has “acquire semantics”
> meaning that the read is guaranteed to occur *prior* to any****
>
> references to memory that occur after the read instruction in the CIL
> instruction sequence. A****
>
> volatile write has “release semantics” meaning that the write is
> guaranteed to happen after any****
>
> memory references *prior* to the write instruction in the CIL instruction
> sequence.****
>
>
>
> What that rule allows is for things to move inside of the acquire/release
> pair (from above acquire and from below release).****
>
> .NET spec is silent on the following issue: can acquire move above release
> (2 pairs to cross, or exactly what happens in Dekker’s algorithm)****
>
> Java as you can see from the reference above on StoreLoad (the case here)
> requires fences and don’t allow for such reordering.****
>
>
>
>
>
> What’s a bit strange in .net is thatThread.ReadVolatile fixes the problem
> even though the documentation says that it does exactly reading volatile
> field would do. But that could be extra implementation detail of
> ReadVolatile.
>
> Sent from mobile device
>
> On Feb 18, 2013, at 4:39 PM, Timothy Chen <tnachen at gmail.com> wrote:
>
> Just curious, you said C# doesn't give you sequential consistency in no
> data races and no atomics/volatiles usage, then what does C# do?
>
> Is the behavior documented somewhere?
>
> Thanks,
>
> Tim
>
>
>
> On Mon, Feb 18, 2013 at 11:59 AM, Boehm, Hans <hans.boehm at hp.com> wrote:
>
>>  On rereading, I think I misunderstood the context here. When Nitsan
>> said “SC equivalent”, I think he meant “sequentially equivalent”, in which
>> case I now understand the original posting.  Sorry about that.****
>>
>> ** **
>>
>> I agree that this is a valid transformation.****
>>
>> ** **
>>
>> Hans****
>>
>> ** **
>>
>> *From:* concurrency-interest-bounces at cs.oswego.edu [mailto:
>> concurrency-interest-bounces at cs.oswego.edu] *On Behalf Of *Boehm, Hans
>> *Sent:* Monday, February 18, 2013 9:33 AM
>> *To:* Nitsan Wakart; Aleksey Shipilev; Dmitry Tsitelov
>> *Cc:* Concurrency-interest at cs.oswego.edu
>> *Subject:* Re: [concurrency-interest] Racy lazy initialization: blush
>> test****
>>
>> ** **
>>
>> I think some things got confused here, including the rules for different
>> languages.****
>>
>> ** **
>>
>> The basic rules are:****
>>
>> ** **
>>
>> In basically all modern languages: IF THERE ARE NO DATA RACES and no uses
>> of atomics/volatiles, you get sequential consistency.****
>>
>> ** **
>>
>> In Java, C, C++: If there are no data races, and accesses to
>> atomics/volatiles don’t say otherwise, you still get sequential
>> consistency.  (This doesn’t hold in C# or OpenMP, for example.)****
>>
>> ** **
>>
>> In the presence of data races, these languages instead provide really
>> weak or no guarantees.  The examples under discussion here have data races,
>> so none of this applies.****
>>
>> ** **
>>
>> Hans****
>>
>> ** **
>>
>> *From:* concurrency-interest-bounces at cs.oswego.edu [
>> mailto:concurrency-interest-bounces at cs.oswego.edu<concurrency-interest-bounces at cs.oswego.edu>]
>> *On Behalf Of *Nitsan Wakart
>> *Sent:* Monday, February 18, 2013 6:32 AM
>> *To:* Aleksey Shipilev; Dmitry Tsitelov
>> *Cc:* Concurrency-interest at cs.oswego.edu
>> *Subject:* Re: [concurrency-interest] Racy lazy initialization: blush
>> test****
>>
>> ** **
>>
>> My understanding is that the program is open to SC equivalent
>> interpretation given no hints are given with regards to
>> ordering/concurrency.****
>>
>> Consider the code:****
>>
>> r2 = x.f;****
>>
>> if(x.f == 0){****
>>
>>           x.f = 1;****
>>
>>           r2 = 1;****
>>
>> }****
>>
>> Is SC equivalent to the original. The fact that x.f is written to
>> concurrently is not conveyed to the compiler, so as far as it's concerned
>> it's fine. Why would the above interpretation be a good idea I'm not sure,
>> but I think it's allowed.****
>>    ------------------------------
>>
>> *From:* Aleksey Shipilev <aleksey.shipilev at oracle.com>
>> *To:* Dmitry Tsitelov <cit at cit.spb.ru>
>> *Cc:* "Concurrency-interest at cs.oswego.edu" <
>> Concurrency-interest at cs.oswego.edu>
>> *Sent:* Monday, February 18, 2013 10:48 AM
>> *Subject:* Re: [concurrency-interest] Racy lazy initialization: blush
>> test****
>>
>>
>> On 02/18/2013 02:39 PM, Dmitry Tsitelov wrote:
>> >>  class X {
>> >>      int f;
>> >>  }
>> >>
>> >>  X x = new X();
>> >>
>> >>          T1      |    T2
>> >>  ---------------+---------------
>> >>  if (x.f == 0)  | if (x.f == 0)
>> >>      x.f = 1    |    x.f = 1
>> >>  r1 = x.f      | r2 = x.f
>> >>
>> >> Is there a valid execution which yields (r1, r2) as (1, 0) or (0, 1)?
>> >> (It appears there are valid executions under JMM, mostly because there
>> >> is the data race on x.f; Jeremy had a post [2] about the similar issue
>> >> before, and reaching to the same conclusion.)
>> >>
>> >
>> > Could someone point me to a sequentially-consistent execution of this
>> > scenario emitting (1,0)/(0,1) result, please?
>>
>> I'm afraid there are no SC executions that yield this result. We have
>> the data race on x.f, DRF guarantee is out of the window, it's useless
>> to seek SC execution to justify this behavior.
>>
>> -Aleksey.
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest****
>>
>> _______________________________________________
>> Concurrency-interest mailing list
>> Concurrency-interest at cs.oswego.edu
>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>>
>>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20130220/ffdce8f7/attachment-0001.html>


More information about the Concurrency-interest mailing list