• Android原子操作——android_atomic_cmpxchg


    网络给我们带来了很多方便,查阅我们目前认知范围外的道理。但是,凡事也要学会分辨,不然可能会误导你。

    话说,最近的一个项目(Mercury-Project),接近尾声中。然而,在调试一个demo时,却遇到了问题。

    理一下问题由来:

    1.目标:将Android下的一些基础工具移植到纯Linux平台环境上用。

    2.移植RefBase时,用到了原子操作:

    android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong)

    怎么办呢?因为这个api是Android实现的一套底层原子操作(应付并发场景下比较+交换操作的原子性要求),因此需要寻找通用Linux平台所对应的api。

    是什么呢?这个:__sync_bool_compare_and_swap(),其原型为:bool __sync_bool_compare_and_swap (type *ptr, type oldval, type newval)

    需要注意的是,这个是gcc提供的api,而非OS提供的。

    3.如何替换?

    分析gcc的CAS的原型:bool __sync_bool_compare_and_swap(type *ptr, type oldval, type newval)

    这个CAS函数,功能为:比较oldval与*ptr的值,如何相等,则用newval更新*ptr的值,否则不更新;当更新时,返回true,不跟新时,返回false。

    Android的这个api原型:int android_atomic_cmpxchg(int32_t oldvalue, int32_t newvalue, volatile int32_t* addr)

    然而,这个函数,网上一大片错的!估计都没验证过,就抄过来抄过去。呵呵。。。

    截取网上找到的两段:

      

    也天真的相信了,移植时,将如下代码:

    if (android_atomic_cmpxchg(curCount, curCount+1, &impl->mStrong) == 0)

    修改为了:

    if (__sync_bool_compare_and_swap(&impl->mStrong, curCount, curCount+1) == 0)

    4.问题出现:

    在跑demo,验证RefBase时,将对象进行promote时,等待了近一分钟,才执行完!

    回来查问题,才定位到,是这个CAS函数替换引入的!

    5.api真正的功能是什么?

    参考api说明:http://androidxref.com/4.4.4_r1/xref/system/core/include/cutils/atomic.h#115

    以及实现:http://androidxref.com/4.4.4_r1/xref/system/core/include/cutils/atomic-arm.h#108

    截下来:

     如果看不懂汇编,看最后一行的return语句,也猜的八九不离十:相等时,返回0;不等时,返回1。

     这一段API接口说明要仔细读:

    110-112行说,这个两个接口是新API(android_atomic_release_cas)的别名,在将来可能被移除掉,不建议再用此API。

    再看95-96行的说明,返回zero,只有在*addr==oldvalue时,才发生!!!

    第98行,补充说,在其他平台(非ARM平台)上,根据具体的实现,返回值是反的。

  • 相关阅读:
    软件工程第四周进度总结
    djang-模型层(model)--添加,查询,修改
    django--模型层(ORM)-建表
    django---模板层
    django--MTV基础模型
    django--权限管理思路版
    django--权限管理day1
    django-超级管理员操作
    django-orm的表操作.
    django---查询操作
  • 原文地址:https://www.cnblogs.com/Dreaming-in-Gottingen/p/14127523.html
Copyright © 2020-2023  润新知