天天看點

jdk16中并發包裡cas的底層實作

sun.misc.Unsafe

/**
    * Atomically updates Java variable to {@code x} if it is currently
    * holding {@code expected}.
    *
    * <p>This operation has memory semantics of a {@code volatile} read
    * and write.  Corresponds to C11 atomic_compare_exchange_strong.
    *
    * @return {@code true} if successful
    */
@ForceInline
public final boolean compareAndSwapInt(Object o, long offset,
                                        int expected,
                                        int x) {
    return theInternalUnsafe.compareAndSetInt(o, offset, expected, x);
}      

jdk.internal.misc.Unsafe

Unsafe.class
/**
    * Atomically updates Java variable to {@code x} if it is currently
    * holding {@code expected}.
    *
    * <p>This operation has memory semantics of a {@code volatile} read
    * and write.  Corresponds to C11 atomic_compare_exchange_strong.
    *
    * @return {@code true} if successful
    */
@HotSpotIntrinsicCandidate
public final native boolean compareAndSetInt(Object o, long offset,
                                                int expected,
                                                int x);      

Unsafe.cpp

UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSetInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x)) {
  oop p = JNIHandles::resolve(obj);
  if (p == NULL) {
    volatile jint* addr = (volatile jint*)index_oop_from_field_offset_long(p, offset);
    return RawAccess<>::atomic_cmpxchg(addr, e, x) == e;
  } else {
    assert_field_offset_sane(p, offset);
    return HeapAccess<>::atomic_cmpxchg_at(p, (ptrdiff_t)offset, e, x) == e;
  }
} UNSAFE_END      

access.hpp

template <typename T>
  static inline T atomic_cmpxchg_at(oop base, ptrdiff_t offset, T compare_value, T new_value) {
    verify_primitive_decorators<atomic_cmpxchg_mo_decorators>();
    return AccessInternal::atomic_cmpxchg_at<decorators>(base, offset, compare_value, new_value);
  }      

accessBackend.hpp

template <DecoratorSet decorators, typename T>
  inline T atomic_xchg_at(oop base, ptrdiff_t offset, T new_value) {
    verify_types<decorators, T>();
    typedef typename Decay<T>::type DecayedT;
    DecayedT new_decayed_value = new_value;
    // atomic_xchg is only available in SEQ_CST flavour.
    const DecoratorSet expanded_decorators = DecoratorFixup<decorators | MO_SEQ_CST |
                                             (HasDecorator<decorators, INTERNAL_VALUE_IS_OOP>::value ?
                                              INTERNAL_CONVERT_COMPRESSED_OOP : DECORATORS_NONE)>::value;
    return PreRuntimeDispatch::atomic_xchg_at<expanded_decorators>(base, offset, new_decayed_value);
  }      
template<size_t byte_size>
struct Atomic::PlatformCmpxchg {
  template<typename T>
  T operator()(T volatile* dest,
               T compare_value,
               T exchange_value,
               atomic_memory_order order) const;
};      
template<>
template<typename T>
inline T Atomic::PlatformCmpxchg<4>::operator()(T volatile* dest,
                                                T compare_value,
                                                T exchange_value,
                                                atomic_memory_order /* order */) const {
  STATIC_ASSERT(4 == sizeof(T));
  __asm__ volatile ("lock cmpxchgl %1,(%3)"
                    : "=a" (exchange_value)
                    : "r" (exchange_value), "a" (compare_value), "r" (dest)
                    : "cc", "memory");
  return exchange_value;
}