[concurrency-interest] Suggestion: .hardGet() for atomic variables

Ruslan Cheremin cheremin at gmail.com
Thu Jan 19 15:28:18 EST 2012


Actually you still can implement your "hard get" (which is actually
seems like LoadLoadBarrier + vload) with non-numeric types as
atomicRef.compareAndSet(current, current) -- it is exactly the code to
which getAndAdd(0) will be actually transformed (AFAIK).



2012/1/20 Raph Frank <raphfrk at gmail.com>:
> I gave more detail in the thread "Volatile happens before question".
>
> It is for an optimistic read situation
>
> The write is:
>
> W1: sequenceCounter.increment()
> W2: <modify the non-volatile memory>
> W3: sequenceCounter.increment()
>
> The increment makes the counter an odd number and the 2nd one sets it
> back to even.
>
> The read is:
>
> R1: sequenceCounter.get()
> R2: <read from non-volatile memory>
> R3: sequenceCounter.get()
>
> If the 2 reads give the same value (no sequence update) and it is even
> (wasn't unstable), then R2 is assumed to have read correctly.
>
> Otherwise, the read is considered to have failed.
>
> ------
>
> However, it doesn't technically work.
>
> R1, R3, W1 and W3 are changes to volatile variables (an AtomicInteger)
> so they have to be sequenced somehow.
>
> The danger sequence is this one:
>
> R1 (volatile read)
> R3 (volatile read)
> W1 (volatile read/write)
> W3 (volatile read/write)
>
> Since R3 happens before W1, the 2nd read is even (still at the initial
> value of 0), and therefore the read is considered to have read stable
> data.
>
> The happens before relationships are
>
> R1 happens-before R2 happens-before R3
> W1 happens-before W2 happens-before W3
>
> However, since W1 is a write and R3 is a read, there is no happens
> before relationship.
>
> This means that R2 and W2 have no happens-before relationship and
> effectively happen concurrently and there is a data race.
>
> ------
>
> The code could be changed so that it works by using
>
> The read is:
>
> R1: sequenceCounter.get()
> R2: <read from non-volatile memory>
> R3: sequenceCounter.getAndAdd(0) [*]
>
> [*] This assumes that adding zero still causes the write to be
> considered to have happened
>
> ------
>
> The sequence is this one:
>
> R1 (volatile read)
> R3 (volatile read/write)
> W1 (volatile read/write)
> W3 (volatile read/write)
>
> Since R3 is now a write and W1 is a read, R3 happens before W1 and
> therefore R2 happens before W2, so they execute in sequence.
>
> .hardGet() would be equivalent to .getAndAdd(0), but would work for
> the non-numeric Atomic types.
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at cs.oswego.edu
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest


More information about the Concurrency-interest mailing list