免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 6556 | 回复: 8
打印 上一主题 下一主题

[C++] 关于linux c原子锁 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-12-02 18:22 |只看该作者 |倒序浏览
找了些资料,可用调用如下函数,
__sync_lock_test_and_set
__sync_val_compare_and_swap
__sync_fetch_and_sub
__sync_fetch_and_add
__sync_add_and_fetch
__sync_fetch_and_sub
但是他们也只有gcc4.1.2以上的版本才支持,那么在低版本的GCC中如何实现这些函数呢?

论坛徽章:
0
2 [报告]
发表于 2014-12-03 09:04 |只看该作者
用嵌入汇编可以实现。

intel指令集支持lock前缀,
如 lock xadd  指令,可以实现原子加,lock xcha 原子交换




论坛徽章:
0
3 [报告]
发表于 2014-12-03 10:07 |只看该作者
回复 2# codechurch


    我看到网上有用到addl,addq,xaddl等指令,我要同时实现对int(32位)和long long(64位)的原子操作,用那个指令呢?

    像__sync_add_and_fetch这个函数即支持32位又支持64位,我要用那个指令实现呢?

论坛徽章:
0
4 [报告]
发表于 2014-12-03 11:26 |只看该作者
github.com/ivmai/libatomic_ops

论坛徽章:
0
5 [报告]
发表于 2014-12-03 11:41 |只看该作者
回复 4# zhouzhenghui


    太过复杂了,看不懂,谢谢!

AO_INLINE AO_t
475 AO_fetch_compare_and_swap(volatile AO_t *addr, AO_t old_val, AO_t new_val)
476 {
477   AO_t fetched_val;
478   int flag;
479  
480   __asm__ __volatile__("@AO_fetch_compare_and_swap\n"
481     AO_THUMB_GO_ARM
482     "1:     mov     %0, #2\n"           /* store a flag */
483     "       ldrex   %1, [%3]\n"         /* get original */
484     "       teq     %1, %4\n"           /* see if match */
485 #   ifdef __thumb2__
486       "       it      eq\n"
487 #   endif
488     "       strexeq %0, %5, [%3]\n"     /* store new one if matched */
489     "       teq     %0, #1\n"
490     "       beq     1b\n"               /* if update failed, repeat */
491     AO_THUMB_RESTORE_MODE
492     : "=&r"(flag), "=&r"(fetched_val), "+m"(*addr)
493     : "r"(addr), "r"(old_val), "r"(new_val)
494     : AO_THUMB_SWITCH_CLOBBERS "cc");
495   return fetched_val;
496 }

论坛徽章:
0
6 [报告]
发表于 2014-12-03 12:35 |只看该作者
回复 3# colin8080

64位的,要用64位指令,如64位比较交换指令 cmpxchg8b





   

论坛徽章:
0
7 [报告]
发表于 2014-12-03 17:24 |只看该作者
在网上查了一下,32位用xaddl,addl,cmpxchgl等指令,64位用xaddq,addq,cmpxchgq等指令,

但是如果我要在32位操作系统下对long long(64位)加原子锁,xaddq,addq,cmpxchgq这些指令都不能用,

最后没办法只有用线程锁了pthread_mutex_t啦,期待有更好的办法!

论坛徽章:
0
8 [报告]
发表于 2014-12-03 19:05 |只看该作者
回复 7# colin8080


    32bit的intel cpu 支持  cmpxchg8b  这条指令。而且我非常确定这一点,因为我做过。

    其他32位系统下的64位指令,你要去查查intel的手册。

论坛徽章:
0
9 [报告]
发表于 2014-12-03 19:11 |只看该作者
回复 7# colin8080

这个是我写的在32位系统里用的64位比较交换的函数:

编译环境是MSVC

#pragma warning(disable: 4405)
static inline int64_t
atomic_compare_exchange_ll( int64_t volatile *mem, int64_t with, int64_t cp )
{
        _compiler_barrier;
    __asm {
        lea   esi, qword ptr [cp]
        lea   edi, qword ptr [with]
        mov   eax, [esi]
        mov   edx, [esi + 4]
        mov   ebx, [edi]
        mov   ecx, [edi + 4]
        mov   edi, mem
        lock  cmpxchg8b [edi]
        jz    lab
        mov   [esi], eax
        mov   [esi + 4], edx
    lab:
    }
        _compiler_barrier;
    return cp;
}
#pragma warning(default: 4405)


其中 _compiler_barrier 是编译器barrier,防止编译器调动指令次序,windows下函数为  _ReadWriteBarrier

你把这个函数改写为gcc的at&t的样子就行了。




   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP