Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8080588 VarHandles development
  3. JDK-8161444

VarHandles should provide access bitwise atomics

    XMLWordPrintable

    Details

    • Type: Sub-task
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 9
    • Fix Version/s: 9
    • Component/s: core-libs
    • Labels:

      Description

      VarHandles provide safe and efficient access to atomic operations commonly available on modern processors. Since single-bit test-and-operate operations are common, VarHandles should support them.

      Current processors (led by x86) support CAS (cmpxchg), fetch-and-add (xadd), and single-bit test-and-set, -clear, and -flip (bts, btr, btc). The single-bit ops should be represented explicitly, because they are difficult for an optimizer to derive from an equivalent CAS-loop.

      Proposed API addition:

      /**
      * Atomically loads the bit at the specified {@code index} in a variable with
      * the memory semantics of {@link #getAcquire}; if the bit is clear,
      * sets it with the memory semantics of {@link #set}; and finally returns
      * the original bit value as a boolean.
      *
      * <p>The variable may be of any primitive type.
      * Bits are numbered from zero, which refers to the arithmetically
      * least-significant bit, to {@code N-1} inclusive, where {@code N} is
      * the number of bits in the variable. Booleans have exactly one bit,
      * while other variables have an appropriate multiple of eight bits.
      *
      * <p>The method signature is of the form {@code (CT, int index)boolean}.
      *
      * <p>The symbolic type descriptor at the call site of {@code testAndSetBitAcquire}
      * must match the access mode type that is the result of calling
      * {@code accessModeType(VarHandle.AccessMode.TEST_AND_SET_BIT_ACQUIRE)} on this
      * VarHandle.
      *
      * @implNote The effects of this method are similar to a call to
      * {@code get} and {@code compareAndExchangeAcquire}, where the new
      * value is obtained from the old value by setting the specified bit.
      * The full effect of {@code testAndSetBitAcquire} would be obtained
      * by retrying the sequence as needed until the bit is either observed
      * to be set, or updated to be set. More efficient implementations may
      * be available on some platforms.
      *
      * @param args the signature-polymorphic parameter list of the form
      * {@code (CT, int index)}
      * , statically represented using varargs.
      * @return a boolean, the original value of the bit (before any update)
      * , statically represented using {@code Object}.
      * @throws UnsupportedOperationException if the access mode is unsupported
      * for this VarHandle.
      * @throws WrongMethodTypeException if the access mode type is not
      * compatible with the caller's symbolic type descriptor.
      * @throws ClassCastException if the access mode type is compatible with the
      * caller's symbolic type descriptor, but a reference cast fails.
      * @throws ClassCastException if the access mode type is compatible with the
      * caller's symbolic type descriptor, but a reference cast fails.
      * @throws IllegalArgumentException if the supplied index is not in the range
      * of zero (inclusive) to the number of bits in the variable (exclusive).
      * @see #getAcquire(Object...)
      * @see #set(Object...)
      * @see #compareAndExchangeAcquire(Object...)
      */
      public final native
      @MethodHandle.PolymorphicSignature
      @HotSpotIntrinsicCandidate
      Object testAndSetBitAcquire(Object... args);

      /**
      * Atomically loads the bit at the specified {@code index} in a variable with
      * the memory semantics of {@link #get}; if the bit is set,
      * clears it with the memory semantics of {@link #setRelease}; and finally returns
      * the original bit value as a boolean.
      *
      * ........................
      * @see #get(Object...)
      * @see #setRelease(Object...)
      * @see #compareAndExchangeRelease(Object...)
      */
      public final native
      @MethodHandle.PolymorphicSignature
      @HotSpotIntrinsicCandidate
      Object testAndClearBitRelease(Object... args);

      /**
      * Atomically loads the bit at the specified {@code index} in a variable with
      * the memory semantics of {@link #getVolatile}, and stores the complement of
      * the bit with the memory semantics of {@link #setVolatile}, returning the
      * updated bit value as a boolean.
      *
      * ........................
      * @see #getVolatile(Object...)
      * @see #setVolatile(Object...)
      * @see #compareAndExchange(Object...)
      */
      public final native
      @MethodHandle.PolymorphicSignature
      @HotSpotIntrinsicCandidate
      Object flipAndGetBit(Object... args);


      Discussion:

      To keep the number of entry points down, only the
      acquire version of testAndSet is supplied.
      The assumption here is that a lock's critical section
      state will be expressed as a set bit.

      The testAndClearRelease is supplied by symmetry,
      although it is unusual for a lock release operation to
      be conditional.

      A fuller set of entry points could be added,
      though they are not needed for simple use cases like
      simple locks (seq-locks) with tag bits. These could be:
       - testAndClearBitAcquire
       - testAndSetBitRelease
       - getAndBitwise{And,Or,Xor}{,Acquire,Release}
       - testAnd{Set,Clear,Flip}Bit (with explicit memory order parameters)
       - getAndBitwise{And,Or,Xor} (with explicit memory order parameters)

      The index parameter maps directly to an instruction operand on x86.
      Adding explicit range checking on it is in the spirit of Java, and will cost nothing if the index value is constant.

        Attachments

          Issue Links

            Activity

              People

              Assignee:
              psandoz Paul Sandoz
              Reporter:
              jrose John Rose
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Dates

                Created:
                Updated:
                Resolved: