I basically agree with David's observation. However the C++ atomic_thread_fence(memory_order_acquire)
actually has somewhat different semantics from load(memory_order_acquire). It basically ensures that prior atomic loads L are not reordered with later (i.e. following the fence in program order) loads and stores, making it something like a LoadLoad|LoadStore fence. Thus the fence orders two sets of operations where the acquire load orders a single operation with respect to a set. This makes the fence versions of memory_order_acquire and memory_order_release meaningful, but somewhat different from the non-fence versions. The terminology is probably not great, but that seems to be the most common usage now. On Wed, Nov 26, 2014 at 11:48 PM, Peter Levart <peter.lev...@gmail.com> wrote: > On 11/27/2014 04:00 AM, David Holmes wrote: > >> Can I make an observation about acquire() and release() - to me they are >> meaningless when considered in isolation. Given their definitions they >> allow >> anything to move into a region bounded by acquire() and release(), then >> you >> can effectively move the whole program into the region and thus the >> acquire() and release() do not constrain any reorderings. >> acquire() and >> release() only make sense when their own movement is constrained with >> respect to something else - such as lock acquisition/release, or when >> combined with specific load/store actions. >> > > ...or another acquire/release region? > > Regards, Peter > > > >> David >> >> Martin Buchholz writes: >> >>> On Tue, Nov 25, 2014 at 6:04 AM, Paul Sandoz >>> <paul.san...@oracle.com> wrote: >>> >>>> Hi Martin, >>>> >>>> Thanks for looking into this. >>>> >>>> 1141 * Currently hotspot's implementation of a Java >>>> >>> language-level volatile >>> >>>> 1142 * store has the same effect as a storeFence followed >>>> >>> by a relaxed store, >>> >>>> 1143 * although that may be a little stronger than needed. >>>> >>>> IIUC to emulate hotpot's volatile store you will need to say >>>> >>> that a fullFence immediately follows the relaxed store. >>> >>> Right - I've been groking that. >>> >>> The bit that always confuses me about release and acquire is >>>> >>> ordering is restricted to one direction, as talked about in >>> orderAccess.hpp [1]. So for a release, accesses prior to the >>> release cannot move below it, but accesses succeeding the release >>> can move above it. And that seems to apply to Unsafe.storeFence >>> [2] (acting like a monitor exit). Is that contrary to C++ release >>> fences where ordering is restricted both to prior and succeeding >>> accesses? [3] >>> >>>> So what about the following? >>>> >>>> a = r1; // Cannot move below the fence >>>> Unsafe.storeFence(); >>>> b = r2; // Can move above the fence? >>>> >>> I think the hotspot docs need to be more precise about when they're >>> talking about movement of stores and when about loads. >>> >>> // release. I.e., subsequent memory accesses may float above the >>>> // release, but prior ones may not float below it. >>>> >>> As I've said elsewhere, the above makes no sense without restricting >>> the type of access. >>> >>> _______________________________________________ >>> Concurrency-interest mailing list >>> concurrency-inter...@cs.oswego.edu >>> http://cs.oswego.edu/mailman/listinfo/concurrency-interest >>> >> > _______________________________________________ > Concurrency-interest mailing list > concurrency-inter...@cs.oswego.edu > http://cs.oswego.edu/mailman/listinfo/concurrency-interest >