[concurrency-interest] [Javamemorymodel-discussion] Fences.keepAlive

Boehm, Hans hans.boehm at hp.com
Wed Jan 21 16:15:20 EST 2009


> -----Original Message-----
> From: javamemorymodel-discussion-bounces at cs.umd.edu 
> [mailto:javamemorymodel-discussion-bounces at cs.umd.edu] On 
> Behalf Of Doug Lea
> Sent: Wednesday, January 21, 2009 10:31 AM
> To: Joe Bowbeer
> Cc: concurrency-interest; javamemorymodel-discussion
> Subject: Re: [Javamemorymodel-discussion] 
> [concurrency-interest] Fences.keepAlive
> Joe Bowbeer wrote:
> > 
> > It's hard for me to mesh fences with the JMM.  In the 
> context of JMM, 
> > fences seem like magic.  (Whereas in the magical world of a 
> DEC Alpha, 
> > fences impose
> > reality.)
> > 
> Although from a different perspective, it is almost the 
> opposite.  Memory consistency is all about the relations 
> among memory accesses, not the accesses themselves. If people 
> somehow liked programming the interstices across accesses 
> (which is what fences do), it would probably be easier to 
> specify a fairly simple memory model of sorts that described 
> effects.  But no one likes to program in this way, and even 
> if they did, it would be much harder to verify correct usage. 
> So instead the JMM associates relations with sets of accesses 
> of variables tagged as volatile etc. Which enters the messy 
> territory of how mixtures of volatiles, non-volatile, and 
> final accesses interrelate. If you instead program directly 
> use Fence API, you don't have to pay attention to this part 
> much, but on penalty of having to program in a very unnatural 
> way -- a style that you would only tolerate in a small part 
> of your program for the sake of enforcing an ordering 
> relation that is not otherwise obtainable; i.e., because the 
> available means of expressing them are either too weak to too strong.
> In other words, the Fences API methods are just as removed 
> from hardware as volatile specs are. They feel closer because 
> HW folks have no sympathy about programmability, so usually 
> only provide instruction sets supporting 
> interstice-programming (fences), on top of a set of base 
> ordering guarantees, rather than tagged variable access, so 
> the mapping is easier.
> (*) Footnote/disclaimer: However, there is one access-based, 
> not relation-based property of volatiles -- access is 
> guaranteed atomic even for longs and doubles, unlike the case 
> for non-volatiles.
This may understate the difficulty of pinning down a satisfactory semantics for fences.  As far as I can tell, they are really hard to specify in a both that's both strong enough to avoid surprises and weak enough to be implementable across commercially significant hardware.  For one example of this, see the thread leading to http://www.decadentplace.org.uk/pipermail/cpp-threads/2009-January/001967.html .

Part of the difficulty here is that volatiles at least have the property that if you declare enough things volatile, you can always get sequential consistency back.  (In Java, there are some minor glitches since we don't have volatile array elements, but those can be worked around.)  Even if you add all possible fences between every pair of memory operations, you won't get sequential consistency back (e.g. for the IRIW example, or for the one in the above thread).  At least I don't know of a reasonable definition for fences that would give you those semantics.

My feeling about the C++ fences has always been that we traded off generality and potentially some performance for a spec with tolerable complexity.  They don't do everything you might want.

Clearly Doug's current proposal for Java fences is different from the C++ one.  Restricting it to a single object seems cleaner and safer, though it doesn't address some of the concerns that drove the C++ one, e.g. minimizing overhead when releasing multiple locks.  But I think the current version still doesn't address some critical details:

1) I think lazySet already fundamentally broke the Java memory model formalism, in that I don't see how it's compatible with a total synchronization order.  LazySet operations performed by different threads presumably don't have to be seen in the same order by all observers?  The fence API breaks it further.

2) I'm really nervous about the final field emulation piece of this, since it assumes the implementation of the reader respects data dependencies.  The current Java memory model guarantees that only for final fields, so I don't think this can be correct, as it stands.  I think I would be much more comfortable if the reader side were also explicit about the required ordering.

3) As I think others have pointed out, the fence wording needs work.  It's unclear what role the argument plays.


More information about the Concurrency-interest mailing list