jdk9 VarHandle and Fence methods

classic Classic list List threaded Threaded
73 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Andrew Haley
On 08/23/2015 05:17 PM, thurstonn wrote:
> That's what I was referring to; I  presumed update_barrier_set resulted in
> some sort of store fence

As others have said, that's a GC write barrier.  This confusion is one
reason why we try to talk about "fence" instructions on this list, and
GC "barriers."

Andrew.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

thurstonn
In reply to this post by thurstonn
I have to laugh.  
(it) -> it
as an example UnaryOperator is a particularly bad example when illustrating CAS.
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

thurstonn
In reply to this post by Andrew Haley
Thanks for the clarification.
I generally had considered "memory fence" and "memory barrier" as more or less interchangeable.
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Martin Buchholz-3


On Mon, Aug 24, 2015 at 5:45 AM, thurstonn <[hidden email]> wrote:
Thanks for the clarification.
I generally had considered "memory fence" and "memory barrier" as more or
less interchangeable.

It's even more confusing, I think, since "memory barrier" and "gc barrier" seem to be different things.  "memory fence" and "memory barrier" may be the same thing, but the word "fence" is more likely to be used with actual machine instructions ... except that sparc has a "membar" instruction, and sparc strongly influenced hotspot?! 

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Andrew Haley
On 08/24/2015 05:59 PM, Martin Buchholz wrote:

>
>
> On Mon, Aug 24, 2015 at 5:45 AM, thurstonn <[hidden email] <mailto:[hidden email]>> wrote:
>
>     Thanks for the clarification.
>     I generally had considered "memory fence" and "memory barrier" as more or
>     less interchangeable.
>
>
> It's even more confusing, I think, since "memory barrier" and "gc
> barrier" seem to be different things.  "memory fence" and "memory
> barrier" may be the same thing, but the word "fence" is more likely
> to be used with actual machine instructions ... except that sparc
> has a "membar" instruction, and sparc strongly influenced hotspot?!

Well, yes.  But we are trying.  :-)

Andrew.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

thurstonn
In reply to this post by thurstonn
So I'm still not clear on the implementation of VarHandles, et al.

1.  Do each of the methods have a corresponding Unsafe method?

2.  Is each method "marked intrinsic"?  

Looking at this, I don't see compareAndExchangeXXX, e.g. listed
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Aleksey Shipilev-2
That's because your are <strike>barking up the wrong tree</strike>
looking at a wrong forest. See the reference to the actual VarHandles
development forest here:
  https://bugs.openjdk.java.net/browse/JDK-8080588

Thanks,
-Aleksey

On 08/31/2015 02:02 PM, thurstonn wrote:

> So I'm still not clear on the implementation of VarHandles, et al.
>
> 1.  Do each of the methods have a corresponding Unsafe method?
>
> 2.  Is each method "marked intrinsic"?  
>
> Looking at  this
> <http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/tip/src/share/vm/classfile/vmSymbols.hpp>
> , I don't see compareAndExchangeXXX, e.g. listed
>
>
>
> --
> View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12703.html
> Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
> _______________________________________________
> Concurrency-interest mailing list
> [hidden email]
> http://cs.oswego.edu/mailman/listinfo/concurrency-interest
>


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

signature.asc (836 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Paul Sandoz
In reply to this post by thurstonn

On 31 Aug 2015, at 13:02, thurstonn <[hidden email]> wrote:

So I'm still not clear on the implementation of VarHandles, et al.

1.  Do each of the methods have a corresponding Unsafe method?


Yes, they will.


2.  Is each method "marked intrinsic"?  

Looking at  this
<http://hg.openjdk.java.net/jdk9/jdk9/hotspot/file/tip/src/share/vm/classfile/vmSymbols.hpp>
, I don't see compareAndExchangeXXX, e.g. listed


We need to update the sandbox branch implementation to support the agreed set of methods.


(You can see some already, such as _weakCompareAndSwapObjectAcquire.)

At some point what is in the sandbox branch implementation will wind it’s way into the JDK 9 dev repo.

Paul.

_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

signature.asc (858 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

oleksandr otenko
In reply to this post by Vitaly Davidovich
Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex


On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:
Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Andrew Haley
In reply to this post by Vitaly Davidovich
On 08/22/2015 07:15 PM, Vitaly Davidovich wrote:

> I would hope there's no ordering difference between successful and
> unsuccessful CAS.  On x86/64 the instruction itself provides full
> fence irrespective of outcome; compiler doesn't know a priori
> whether it will succeed or not.

Right, but that's a side-effect of the implementation, not a
specification.  The specification says it's a volatile load followed
by a volatile store, and that's all we can assume.  It should be made
plain that if the store does not happen, the store fence doesn't
happen either.  It would be an extremely strange program which relied
on a failed store to have the side-effects of a volatile store.

> Are there platforms where the lowering of the CAS has different cpu
> ordering based on outcome?

Yes.  On AArch64 (and probably every other processor) a Store-Release
Exclusive instruction only has the release semantics if the store is
successful.

> LL/SC can fail if cacheline is modified in between (even if value is
> still the expected one) but I'm not aware of that changing ordering
> semantics.  However, if there are cases where this would matter, I
> hope the JVM ensures the requested ordering irrespective of outcome.

I hope so too, but I don't want to see pointless extra memory
barriers.  I don't think that most algorithms will ever need them.

Andrew.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

David Holmes-6
In reply to this post by oleksandr otenko

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex

On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

oleksandr otenko
You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex


On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex

On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

David Holmes-6

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex

On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex


On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest





_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

oleksandr otenko
Sure, lock acquires and releases in JMM don't guarantee ordering until the lock is acquired. But also they don't have a tryLock in JMM - as it really concerns the synchronized, doesn't it.

Alex

On 03/09/2015 23:34, David Holmes wrote:

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex

On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex


On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest





_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 



_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

David Holmes-6

j.u.c also adopts the same principle:

 

Actions prior to "releasing" synchronizer methods such as Lock.unlock, Semaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.

 

Note the use of “successful” which already indicates tryLock is not included here.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:48 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Sure, lock acquires and releases in JMM don't guarantee ordering until the lock is acquired. But also they don't have a tryLock in JMM - as it really concerns the synchronized, doesn't it.

Alex

On 03/09/2015 23:34, David Holmes wrote:

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex


On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex



On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest






_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Vitaly Davidovich

If thread A releases a lock and threads B and C tryLock it, with one succeeding, the failing thread may want to do something else but wants a happens-before edge with the lock release - that's the general use case.  As a simple example, consider two threads tryLock'ing to acquire the exclusive right to close a socket and then perform some additional actions that require ordering of actions done by the releasing thread.  The thread failing to acquire the lock will skip closing the socket but will proceed to do some work that requires happens-before edge.  This is typically done using CAS, with one thread successfully flipping the state, and the others just skip that action that's guarded by the CAS, but can proceed with doing subsequent work.  In other words, one may want to piggyback on the unlock/tryLock to provide the ordering rather than introducing additional dedicated state for this.

sent from my phone

On Sep 3, 2015 7:26 PM, "David Holmes" <[hidden email]> wrote:

j.u.c also adopts the same principle:

 

Actions prior to "releasing" synchronizer methods such as Lock.unlock, Semaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.

 

Note the use of “successful” which already indicates tryLock is not included here.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:48 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Sure, lock acquires and releases in JMM don't guarantee ordering until the lock is acquired. But also they don't have a tryLock in JMM - as it really concerns the synchronized, doesn't it.

Alex

On 03/09/2015 23:34, David Holmes wrote:

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex


On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex



On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest






_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

David Holmes-6

I don’t agree that is a general use-case. You can always postulate a need for a happens-before edge between two things. I don’t think it is reasonable to expect one on a failing tryLock. Any shared state will need to be protected by a lock or else volatile – and those should be what establishes the HB edges in my opinion.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Vitaly Davidovich
Sent: Friday, September 4, 2015 1:10 PM
To: [hidden email]
Cc: thurston; [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

If thread A releases a lock and threads B and C tryLock it, with one succeeding, the failing thread may want to do something else but wants a happens-before edge with the lock release - that's the general use case.  As a simple example, consider two threads tryLock'ing to acquire the exclusive right to close a socket and then perform some additional actions that require ordering of actions done by the releasing thread.  The thread failing to acquire the lock will skip closing the socket but will proceed to do some work that requires happens-before edge.  This is typically done using CAS, with one thread successfully flipping the state, and the others just skip that action that's guarded by the CAS, but can proceed with doing subsequent work.  In other words, one may want to piggyback on the unlock/tryLock to provide the ordering rather than introducing additional dedicated state for this.

sent from my phone

On Sep 3, 2015 7:26 PM, "David Holmes" <[hidden email]> wrote:

j.u.c also adopts the same principle:

 

Actions prior to "releasing" synchronizer methods such as Lock.unlock, Semaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.

 

Note the use of “successful” which already indicates tryLock is not included here.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:48 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Sure, lock acquires and releases in JMM don't guarantee ordering until the lock is acquired. But also they don't have a tryLock in JMM - as it really concerns the synchronized, doesn't it.

Alex

On 03/09/2015 23:34, David Holmes wrote:

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex

On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex


On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest





_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Vitaly Davidovich

By general I meant "here's the gist of what I'm saying", not general as in common.  However, I don't think it's that uncommon either.

Are we then going to stipulate different ordering semantics for successful vs unsuccessful CAS? The dichotomy of these is likely to trip some people up and may create subtle bugs on archs where there is an actual difference.

sent from my phone

On Sep 3, 2015 11:32 PM, "David Holmes" <[hidden email]> wrote:

I don’t agree that is a general use-case. You can always postulate a need for a happens-before edge between two things. I don’t think it is reasonable to expect one on a failing tryLock. Any shared state will need to be protected by a lock or else volatile – and those should be what establishes the HB edges in my opinion.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Vitaly Davidovich
Sent: Friday, September 4, 2015 1:10 PM
To: [hidden email]
Cc: thurston; [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

If thread A releases a lock and threads B and C tryLock it, with one succeeding, the failing thread may want to do something else but wants a happens-before edge with the lock release - that's the general use case.  As a simple example, consider two threads tryLock'ing to acquire the exclusive right to close a socket and then perform some additional actions that require ordering of actions done by the releasing thread.  The thread failing to acquire the lock will skip closing the socket but will proceed to do some work that requires happens-before edge.  This is typically done using CAS, with one thread successfully flipping the state, and the others just skip that action that's guarded by the CAS, but can proceed with doing subsequent work.  In other words, one may want to piggyback on the unlock/tryLock to provide the ordering rather than introducing additional dedicated state for this.

sent from my phone

On Sep 3, 2015 7:26 PM, "David Holmes" <[hidden email]> wrote:

j.u.c also adopts the same principle:

 

Actions prior to "releasing" synchronizer methods such as Lock.unlock, Semaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.

 

Note the use of “successful” which already indicates tryLock is not included here.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:48 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Sure, lock acquires and releases in JMM don't guarantee ordering until the lock is acquired. But also they don't have a tryLock in JMM - as it really concerns the synchronized, doesn't it.

Alex

On 03/09/2015 23:34, David Holmes wrote:

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex

On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex


On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest





_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

David Holmes-6

I see your point but I’d consider these at two different levels of abstraction. CAS, as a primitive, is easier to reason with if it has the ordering guarantees even on failure. I can easily imagine CAS-based algorithms that require such guarantees even if the CAS fails. The tryLock however is a higher-level API and I don’t expect, or see the need for, additional guarantees in the failure case.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Vitaly Davidovich
Sent: Friday, September 4, 2015 1:41 PM
To: [hidden email]
Cc: thurston; [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

By general I meant "here's the gist of what I'm saying", not general as in common.  However, I don't think it's that uncommon either.

Are we then going to stipulate different ordering semantics for successful vs unsuccessful CAS? The dichotomy of these is likely to trip some people up and may create subtle bugs on archs where there is an actual difference.

sent from my phone

On Sep 3, 2015 11:32 PM, "David Holmes" <[hidden email]> wrote:

I don’t agree that is a general use-case. You can always postulate a need for a happens-before edge between two things. I don’t think it is reasonable to expect one on a failing tryLock. Any shared state will need to be protected by a lock or else volatile – and those should be what establishes the HB edges in my opinion.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Vitaly Davidovich
Sent: Friday, September 4, 2015 1:10 PM
To: [hidden email]
Cc: thurston; [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

If thread A releases a lock and threads B and C tryLock it, with one succeeding, the failing thread may want to do something else but wants a happens-before edge with the lock release - that's the general use case.  As a simple example, consider two threads tryLock'ing to acquire the exclusive right to close a socket and then perform some additional actions that require ordering of actions done by the releasing thread.  The thread failing to acquire the lock will skip closing the socket but will proceed to do some work that requires happens-before edge.  This is typically done using CAS, with one thread successfully flipping the state, and the others just skip that action that's guarded by the CAS, but can proceed with doing subsequent work.  In other words, one may want to piggyback on the unlock/tryLock to provide the ordering rather than introducing additional dedicated state for this.

sent from my phone

On Sep 3, 2015 7:26 PM, "David Holmes" <[hidden email]> wrote:

j.u.c also adopts the same principle:

 

Actions prior to "releasing" synchronizer methods such as Lock.unlock, Semaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lock, Semaphore.acquire, Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.

 

Note the use of “successful” which already indicates tryLock is not included here.

 

David

 

From: [hidden email] [mailto:[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:48 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Sure, lock acquires and releases in JMM don't guarantee ordering until the lock is acquired. But also they don't have a tryLock in JMM - as it really concerns the synchronized, doesn't it.

Alex

On 03/09/2015 23:34, David Holmes wrote:

Not sure what “everything” is. If Thread A releases the lock and thread B acquires it, then B sees everything that happened in A before the release. If thread C now does a tryLock and sees the lock is already owned you are suggesting it should see what thread B sees because if it had acquired the lock then that would be the case. But it didn’t acquire it, it only sees that it is already acquired by another thread. So I don’t see there is any transitive relationship that has to be applied here. Implementation wise it is likely but in terms of the model I think expectations and requirements should be nil.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 8:18 AM
To: [hidden email]; 'Vitaly Davidovich'; 'thurston'
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

You should at least see everything preceding the lock acquire - since you see the lock acquired - and therefore everything preceding the lock release.

Alex

On 03/09/2015 21:57, David Holmes wrote:

tryLock seems a non-issue to me. If you acquire a lock you are guaranteed to see all changes made by previous owners of the lock. If you fail to acquire the lock then … you should not be expecting anything.

 

David

 

From: [hidden email] [[hidden email]] On Behalf Of Oleksandr Otenko
Sent: Friday, September 4, 2015 4:19 AM
To: Vitaly Davidovich; thurston
Cc: [hidden email]
Subject: Re: [concurrency-interest] jdk9 VarHandle and Fence methods

 

Has anyone come up with the answer about ordering for tryLock, or have I missed it?

It seems that tryLock can fail without attempting a CAS, but what guarantees are really expected by the code users, and are they in line with this assumption.


Alex

On 22/08/2015 19:15, Vitaly Davidovich wrote:

I would hope there's no ordering difference between successful and unsuccessful CAS.  On x86/64 the instruction itself provides full fence irrespective of outcome; compiler doesn't know a priori whether it will succeed or not.  Are there platforms where the lowering of the CAS has different cpu ordering based on outcome? LL/SC can fail if cacheline is modified in between (even if value is still the expected one) but I'm not aware of that changing ordering semantics.  However, if there are cases where this would matter, I hope the JVM ensures the requested ordering irrespective of outcome.

Along this line, the more "interesting" and related question is what the ordering guarantees are for failed tryLock methods.

sent from my phone

On Aug 22, 2015 1:41 PM, "thurstonn" <[hidden email]> wrote:

Thanks for the prompt reply.  I guess I'll operate then from the yes
perspective.

What are the plans with respect to the "higher-order methods" on e.g.
AtomicReference, i.e.

T getAndAccumulate(T, BinaryOperator<T>)
T updateAndGet(UnaryOperator<T>)
. . .
etc.


Are you going to have:
T getAndAccumulateVolatilely(T, BinaryOperator<T>)
T getAndAccumulateAcquiredly(T, BinaryOperator<T>)
etc versions?


That seems like a pollution of the API, IMO (and just awful names).  And I'm
not really sure where it ends.

And then a small javadoc modification suggestion:
/**
      * Returns the value, and ensures that subsequent loads and stores
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

I find
/**
      * Returns the value, and ensures that subsequent loads and stores (*in
the program order*)
      * are not reordered before this access.
      *
      * @apiNote Ignoring the many semantic differences from C and
      * C++, this method has memory ordering effects compatible with
      * memory_order_acquire ordering.
      *
      * @return the value
      */
     T getAcquire(Object owner);

to be a little clearer as *subsequent* is an overloaded term when it comes
to JMM matters.

And one final question that I've always been confused about;  are there
different "memory ordering effects" between a successful CAS and an
unsuccessful one (presumably in the latter because no write actually
occurs)?
IIRC, when looking at the java 8 JVM code, I believe a fence was inserted in
the successful case, at least on x86/64.  If so, I can take a shot at
producing some javadoc language to reflect that, if it would be helpful.



--
View this message in context: http://jsr166-concurrency.10961.n7.nabble.com/jdk9-VarHandle-and-Fence-methods-tp12666p12680.html
Sent from the JSR166 Concurrency mailing list archive at Nabble.com.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest




_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest

 

 

 


_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
Reply | Threaded
Open this post in threaded view
|

Re: jdk9 VarHandle and Fence methods

Andrew Haley
On 09/04/2015 05:10 AM, David Holmes wrote:

> I see your point but I’d consider these at two different levels of
> abstraction. CAS, as a primitive, is easier to reason with if it has
> the ordering guarantees even on failure. I can easily imagine
> CAS-based algorithms that require such guarantees even if the CAS
> fails.

In which case it makes sense to insert them explicitly.  There's no
reason not to follow a CAS with a full fence if one is really needed
on failure.  That will make the code easier to read.

It's trivial to take out the trailing fence in the JIT if some
hardware does a full fence on a failed CAS.

Andrew.
_______________________________________________
Concurrency-interest mailing list
[hidden email]
http://cs.oswego.edu/mailman/listinfo/concurrency-interest
1234