ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

jvm源码解读--16 cas 用法解析

2021-05-19 14:32:26  阅读:166  来源: 互联网

标签:cur jint -- 16 jlong value dest 源码 exchange


UNSAFE_ENTRY(jboolean, Unsafe_CompareAndSwapInt(JNIEnv *env, jobject unsafe, jobject obj, jlong offset, jint e, jint x))
  UnsafeWrapper("Unsafe_CompareAndSwapInt");
  oop p = JNIHandles::resolve(obj);
  jint* addr = (jint *) index_oop_from_field_offset_long(p, offset);
  return (jint)(Atomic::cmpxchg(x, addr, e)) == e;
UNSAFE_END
return (jint)(Atomic::cmpxchg(x, addr, e)) == e;

分析,有三个值,内存值V,旧的预期值A,新的修改值B;

如果A==V,那么把B赋值给V,返回V,如果A!=V,直接返回V;

 

进入

jbyte Atomic::cmpxchg(jbyte exchange_value, volatile jbyte* dest, jbyte compare_value) {
  assert(sizeof(jbyte) == 1, "assumption.");
  uintptr_t dest_addr = (uintptr_t)dest;
  uintptr_t offset = dest_addr % sizeof(jint);
  volatile jint* dest_int = (volatile jint*)(dest_addr - offset);
  jint cur = *dest_int;
  jbyte* cur_as_bytes = (jbyte*)(&cur);
  jint new_val = cur;
  jbyte* new_val_as_bytes = (jbyte*)(&new_val);
  new_val_as_bytes[offset] = exchange_value;
  while (cur_as_bytes[offset] == compare_value) {
    jint res = cmpxchg(new_val, dest_int, cur);// 
if (res == cur) break; cur = res; new_val = cur; new_val_as_bytes[offset] = exchange_value; } return cur_as_bytes[offset]; }

inline jlong Atomic::cmpxchg (jlong exchange_value, volatile jlong* dest, jlong compare_value) {

                    // 

return _Atomic_cmpxchg_long(exchange_value, dest, compare_value, os::is_MP());
}

 
                        // 
inline jlong _Atomic_cmpxchg_long(jlong exchange_value, volatile jlong* dest, jlong compare_value, int mp) {
#ifdef AMD64 __asm__ __volatile__ (LOCK_IF_MP(%4) "cmpxchgq %1,(%3)" : "=a" (exchange_value) : "r" (exchange_value), "a" (compare_value), "r" (dest), "r" (mp) : "cc", "memory"); return exchange_value; #else return _Atomic_cmpxchg_long_gcc(exchange_value, dest, compare_value, os::is_MP()); #if 0 // The code below does not work presumably because of the bug in gcc // The error message says: // can't find a register in class BREG while reloading asm // However I want to save this code and later replace _Atomic_cmpxchg_long_gcc // with such inline asm code: volatile jlong_accessor evl, cvl, rv; evl.long_value = exchange_value; cvl.long_value = compare_value; int mp = os::is_MP(); __asm__ volatile ("cmp $0, %%esi\n\t" "je 1f \n\t" "lock\n\t" "1: cmpxchg8b (%%edi)\n\t" : "=a"(cvl.words[0]), "=d"(cvl.words[1]) : "a"(cvl.words[0]), "d"(cvl.words[1]), "b"(evl.words[0]), "c"(evl.words[1]), "D"(dest), "S"(mp) : "cc", "memory"); return cvl.long_value; #endif // if 0 #endif // AMD64 }

标签:cur,jint,--,16,jlong,value,dest,源码,exchange
来源: https://www.cnblogs.com/zytcomeon/p/14784900.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有