[concurrency-interest] Stricter read ordering

Tobias Lindaaker thobes at gmail.com
Wed Apr 23 10:12:57 EDT 2014


See comments below.

On 23 Apr 2014, at 15:36 , Aleksey Shipilev <aleksey.shipilev at oracle.com> wrote:

> On 04/23/2014 05:05 PM, Tobias Lindaaker wrote:
>> Yes, I had a look at StampedLock and Unsafe.loadFence(), and it seems
>> to do exactly what I want, and if I was fortunate enough to be able
>> to move to Java 8 I would use it. Unfortunately we are still stuck on
>> Java 7. We even have customers who are still strongly requesting Java
>> 6 compatibility.
> 
> These constraints make the problem unresolvable.
> 
> You might want to look for pre-JDK8 prototype for StampedLock [1]:
> 
>     * As noted in Boehm's paper (above), sequence validation (mainly
>     * method validate()) requires stricter ordering rules than apply
>     * to normal volatile reads (of "state").  In the absence of (but
>     * continual hope for) explicit JVM support of intrinsics with
>     * double-sided reordering prohibition, or corresponding fence
>     * intrinsics, we for now uncomfortably rely on the fact that the
>     * Unsafe.getXVolatile intrinsic must have this property
>     * (syntactic volatile reads do not) for internal purposes anyway,
>     * even though it is not documented.
> 
>    public boolean validate(long stamp) {
>        return (stamp & SBITS) == (U.getLongVolatile(this, STATE) & SBITS);
>    }
> 
> But if Unsafe.loadFence() is risky since it is not specified (yet)
> JMM-wise, and so interactions with other volatile ops and fences is just
> undocumented... then using Unsafe.getXVolatile is double-risky because
> the behavioral effect of read ordering is *REALLY*
> implementation-specific, and you if are using it for read ordering, you
> are five miles past the gateway to Hell already.
> 
> Thanks,
> -Aleksey.
> 
> [1]
> http://gee.cs.oswego.edu/cgi-bin/viewcvs.cgi/jsr166/src/jsr166e/StampedLock.java?revision=1.1

Thank you Aleksey,

Those incidental implementation implications of Unsafe.get*Volatile(...) is exactly what we were looking for.
I agree that it is scary and sad to have to rely on these things (and that even in Java 8, many things you need is hidden behind the discouraging name of "sun.misc.Unsafe"), but it's the reality of working on the JVM. Given how far we've already ventured beyond those gates, five more miles will make virtually no difference...

As a side note, if we could move to Java 8, it is possible that StampedLock could completely fulfil this use case, and that we could use that to simplify our code here. Although we would have to measure the implications of the indirection that would add.


On 23 Apr 2014, at 15:16 , Oleksandr Otenko <oleksandr.otenko at oracle.com> wrote:
> Your code does lead to inconsistencies.
> 
> A permitted reordering is:
> 
> this.x=x; can go ahead of this.next=next;, which will lead to the reading thread observe written==next, yet x being updated, and not y.
> 
> Alex
> 

You are right Alex, there is of course that reordering problem as well, and I would need similar fencing there too.

I would think this would suffice in Java 8:

  public synchronized void update( int x, int y ) {
    long next = this.next + 1;
    this.next = next;
    Unsafe.storeFence(); // <- this being the added line
    this.x = x;
    this.y = y;
    this.written = next;
  }

... and is there some primitive with similar incidental implications to what Aleksey pointed out for the load fence (but for store fencing in this case) that could be used in earlier JDKs?

Thank you both,
Tobias
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://cs.oswego.edu/pipermail/concurrency-interest/attachments/20140423/c34cfce0/attachment.html>


More information about the Concurrency-interest mailing list