
网络给我们带来了很多方便,查阅我们目前认知范围外的道理。但是,凡事也要学会分辨,不然可能会误导你。
话说,最近的一个项目(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 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,&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平台)上,根据具体的实现,返回值是反的。
总结以上是内存溢出为你收集整理的Android原子 *** 作——android_atomic_cmpxchg全部内容,希望文章能够帮你解决Android原子 *** 作——android_atomic_cmpxchg所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)