On 10/03/2015 2:21 AM, Martin Buchholz wrote:
On Mon, Mar 9, 2015 at 4:13 AM, David Holmes <david.hol...@oracle.com
<mailto:david.hol...@oracle.com>> wrote:

    On 9/03/2015 7:27 PM, Andrew Haley wrote:


    But who is to say that is the specification for the Unsafe API?


It's for us to say!

I meant specifically the choice of the specification, not the right to suggest one.

    The public API's have a specification for what they provide to the
    programmer. On what basis are we assigning that same specification
    to Unsafe API? The Unsafe API has to meet the requirements of the
    public APIs that use it, but that doesn't  mean it necessarily
    should have the same specification as those APIs.


We already have lots of code that implicitly depends on volatile
read/write visibility, especially in j.u.c.
Most obviously, how do you implement compareAndSet methods without the
same visibility guarantees on the Unsafe equivalents?

Obviously Unsafe has to be implemented in a way that satisfies the j.u.c routines that use it.

My spec change only documents what "everyone already knows to be true".
Another way of looking at it is that the Unsafe methods are a low-level
optimization of the equivalent j.u.c.a. objects without requiring memory
allocation.

The public API methods specify memory ordering semantics so that the end programmer can use those to reason about their use of j.u.c components.

The implementation of j.u.c has to satisfy its specified semantics.

The current implementation of j.u.c uses Unsafe operations that in turn utilize JVM operations. The JVM operations have memory synchronization affects that are stronger than required by j.u.c, and so satisfy them.

So the question is: should Unsafe specify the expectations of its j.u.c client (what you propose); or should it specify what the JVM implementations provide; or should it not actually specify anything in this regard knowing that the implementation is required to correctly implement the public APIs? I don't see much point in pushing down the spec from the public APIs to the Unsafe API. To me it suffices to say that the Unsafe methods must correctly implement the requirements of the public API without specifying that in specific terms of volatile read/writes (which it doesn't actually use) or full bi-directional fences (which it does use). It's not as if Unsafe were a public API for which we might switch in implementations from different providers and hence we need a clear specification for those implementors to follow.

But if you think it important that these Unsafe methods say something about memory synchronization then the wording still needs to make clear what "volatile" is assumed to be being accessed. In particular the j.u.c usage always passes the offset of a variable that is volatile - hence getting volatile read/write semantics. But you can pass the Unsafe methods the offset for a variable that is not declared volatile - so what then? Should the specification state that the offset is assumed/expected to that for a volatile variable and hence it provides volatile read/write only if that variable is volatile? Or should we state something more generic as in:

"This operation reads the Java variable at the given offset with volatile load semantics, and writes it with volatile store semantics."

That doesn't force the variable to be volatile but does require Unsafe to act as if it were. The wording is also similar to that used in getObjectVolatile/putObjectVolatile. (It also doesn't attempt to the address the debate as to whether there is any volatile write on failure - should it?)

Or should we say something else?

Cheers,
David

Reply via email to