Вопрос

I am writing an application, this application is an implementation of lock-free queue and will be running on linux and compiled by GCC 3.4.2.

The implementation is based on following atomic operations:

__sync_fetch_and_add

__sync_fetch_and_sub

__sync_bool_compare_and_swap

__sync_val_compare_and_swap**

The problem is GCC doesn't have the above builtins until GCC 4.1, so currently I have to define them myself in assembly language. But I know nothing about assembly, can anybody give me the defintions of above function? Any help will be greatly appreciated.

More information:

/// @brief atomically adds a_count to the variable pointed by a_ptr /// @return the value that had previously been in memory __sync_fetch_and_add

/// @brief atomically substracts a_count from the variable pointed by a_ptr /// @return the value that had previously been in memory __sync_fetch_and_sub

/// @brief Compare And Swap /// If the current value of *a_ptr is a_oldVal, then write a_newVal into *a_ptr /// @return true if the comparison is successful and a_newVal was written __sync_bool_compare_and_swap

/// @brief Compare And Swap /// If the current value of *a_ptr is a_oldVal, then write a_newVal into *a_ptr /// @return the contents of *a_ptr before the operation __sync_val_compare_and_swap(a_ptr, a_oldVal, a_newVal)

Это было полезно?

Решение

(Untested, may contain typos):

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;
}

If you need a compare_and_swap that operates on a two-words value rather than just one, see e.g. http://src.chromium.org/svn/trunk/src/third_party/tcmalloc/chromium/src/base/atomicops-internals-x86.h.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top