如何在Linux GCC上定义/编写这些原子操作

时间:2013-01-08 14:09:26

标签: linux multithreading atomic operation

我正在编写一个应用程序,这个应用程序是一个无锁队列的实现,将在linux上运行并由 GCC 3.4.2 编译。

实施基于以下原子操作:

__ sync_fetch_and_add

__ sync_fetch_and_sub

__ sync_bool_compare_and_swap

__ sync_val_compare_and_swap **

问题是GCC在 GCC 4.1 之前没有上面的内置,所以目前我必须自己用汇编语言来定义它们。但我对装配一无所知,有人能给我上述功能的定义吗?任何帮助将不胜感激。

更多信息:

/// @brief atomically将a_count添加到a_ptr指向的变量 /// @return以前在内存中的值 __sync_fetch_and_add

/// @brief atomically从a_ptr指向的变量中减去a_count /// @return以前在内存中的值 __sync_fetch_and_sub

/// @brief比较和交换 ///如果* a_ptr的当前值是a_oldVal,那么将a_newVal写入* a_ptr /// @return如果比较成功并且写入了a_newVal,则为true __sync_bool_compare_and_swap

/// @brief比较和交换 ///如果* a_ptr的当前值是a_oldVal,那么将a_newVal写入* a_ptr /// @在操作之前返回* a_ptr的内容 __sync_val_compare_and_swap(a_ptr,a_oldVal,a_newVal)

1 个答案:

答案 0 :(得分:0)

(未经测试,可能包含拼写错误):

inline long
val_compare_and_swap(volatile long *ptr, long old, long _new) {
    long prev;
    asm volatile("lock;"
#if defined(__amd64__)
                 "cmpxchgq %1, %2;"
#else
                 "cmpxchgl %1, %2;"
#endif
                 : "=a"(prev)
                 : "q"(_new), "m"(*ptr), "a"(old)
                 : "memory");
    return prev;
}

inline int
bool_compare_and_swap(volatile long *ptr, long old, long _new) {
    return val_compare_and_swap(ptr, old, new) == old;
}

inline long
fetch_and_add(volatile long *ptr, long value) {
    long prev;
    do {
        prev = *ptr;
    } until (bool_compare_and_swap(ptr, prev, prev + value));
    return prev;
}

如果您需要对双字值而不仅仅是一个值进行操作的compare_and_swap,请参阅例如http://src.chromium.org/svn/trunk/src/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.h