Shadowrun: Awakened 29 September 2011 - Build 871
Functions
cat::Atomic Namespace Reference

Functions

CAT_INLINE u32 Add (volatile u32 *x, s32 y)
CAT_INLINE bool BTR (volatile u32 *x, int bit)
CAT_INLINE bool BTS (volatile u32 *x, int bit)
CAT_INLINE bool CAS2 (volatile void *x, const void *expected_old_value, const void *new_value)
CAT_INLINE u32 Set (volatile u32 *x, u32 new_value)

Function Documentation

u32 cat::Atomic::Add ( volatile u32 *  x,
s32  y 
)

Definition at line 200 of file Atomic.hpp.

Referenced by DataStructures::BinarySearchTree< BinarySearchTreeType >::BinarySearchTree(), DataStructures::CircularLinkedList< CircularLinkedListType >::Concatenate(), and DataStructures::BinarySearchTree< BinarySearchTreeType >::operator=().

{
    CAT_FENCE_COMPILER

#if defined(CAT_COMPILER_MSVC) && defined(CAT_WORD_64)

    u32 result = _InterlockedAdd((volatile LONG*)x, y) - y;

    CAT_FENCE_COMPILER
    return result;

#elif defined(CAT_ASM_INTEL) && defined(CAT_WORD_32) && defined(CAT_ISA_X86)

    CAT_ASM_BEGIN
        mov edx,x
        mov eax,y
        lock XADD [edx],eax
    CAT_ASM_END

    CAT_FENCE_COMPILER

#elif defined(CAT_ASM_ATT) && defined(CAT_ISA_X86)

    u32 retval;

    CAT_ASM_BEGIN
        "lock; XADDl %%eax, %0\n\t"
        : "=m" (*x), "=a" (retval)
        : "m" (*x), "a" (y)
        : "memory", "cc"
    CAT_ASM_END

    CAT_FENCE_COMPILER
    return retval;

#else

#define CAT_NO_ATOMIC_ADD /* Platform/compiler does not support atomic add */

    u32 old_x = *x;
    *x = old_x + y;

    CAT_FENCE_COMPILER
    return old_x;

#endif
}
bool cat::Atomic::BTR ( volatile u32 *  x,
int  bit 
)

Definition at line 366 of file Atomic.hpp.

{
    CAT_FENCE_COMPILER

#if defined(CAT_COMPILER_MSVC)

#if (_MSC_VER <= 1400) // MSVC 2005
    bool success = !!_interlockedbittestandreset((long*)x, bit);
#else // MSVC 2008+
    bool success = !!_interlockedbittestandreset((volatile LONG*)x, bit);
#endif

    CAT_FENCE_COMPILER
    return success;

#elif defined(CAT_ASM_INTEL) && defined(CAT_WORD_32) && defined(CAT_ISA_X86)

    CAT_ASM_BEGIN
        mov edx,x
        mov ecx,bit
        lock BTR [edx],ecx
        mov eax,0
        setc al
    CAT_ASM_END

    CAT_FENCE_COMPILER

#elif defined(CAT_ASM_ATT) && defined(CAT_ISA_X86)

    bool retval;

    CAT_ASM_BEGIN
        "lock; BTRl %2, %0\n\t"
        "setc %%al"
        : "=m" (*x), "=a" (retval)
        : "Ir" (bit)
        : "memory", "cc"
    CAT_ASM_END

    CAT_FENCE_COMPILER
    return retval;

#else

#define CAT_NO_ATOMIC_BTR /* Platform/compiler does not support atomic btr */

    u32 mask = 1 << bit;

    u32 old_x = *x;
    *x = old_x & ~mask;

    CAT_FENCE_COMPILER
    return (old_x & mask) ? true : false;

#endif
}
bool cat::Atomic::BTS ( volatile u32 *  x,
int  bit 
)

Definition at line 306 of file Atomic.hpp.

{
    CAT_FENCE_COMPILER

#if defined(CAT_COMPILER_MSVC)

#if (_MSC_VER <= 1400) // MSVC 2005
    bool success = !!_interlockedbittestandset((long*)x, bit);
#else // MSVC 2008+
    bool success = !!_interlockedbittestandset((volatile LONG*)x, bit);
#endif

    CAT_FENCE_COMPILER
    return success;

#elif defined(CAT_ASM_INTEL) && defined(CAT_WORD_32) && defined(CAT_ISA_X86)

    CAT_ASM_BEGIN
        mov edx,x
        mov ecx,bit
        lock BTS [edx],ecx
        mov eax,0
        setc al
    CAT_ASM_END

    CAT_FENCE_COMPILER

#elif defined(CAT_ASM_ATT) && defined(CAT_ISA_X86)

    bool retval;

    CAT_ASM_BEGIN
        "lock; BTSl %2, %0\n\t"
        "setc %%al"
        : "=m" (*x), "=a" (retval)
        : "Ir" (bit)
        : "memory", "cc"
    CAT_ASM_END

    CAT_FENCE_COMPILER
    return retval;

#else

#define CAT_NO_ATOMIC_BTS /* Platform/compiler does not support atomic bts */

    u32 mask = 1 << bit;

    u32 old_x = *x;
    *x = old_x | mask;

    CAT_FENCE_COMPILER
    return (old_x & mask) ? true : false;

#endif
}
bool cat::Atomic::CAS2 ( volatile void *  x,
const void *  expected_old_value,
const void *  new_value 
)

Definition at line 129 of file Atomic.hpp.

{
    CAT_FENCE_COMPILER

#if defined(CAT_COMPILER_MSVC)

    s64 old_value = ((s64*)expected_old_value)[0];

    bool success = (old_value == _InterlockedCompareExchange64((s64*)x, ((s64*)new_value)[0], old_value));

    CAT_FENCE_COMPILER
    return success;

#elif defined(CAT_ASM_INTEL) && defined(CAT_ISA_X86)

    CAT_ASM_BEGIN
        push ebx
        mov eax, new_value
        push esi
        mov ebx, dword ptr[eax]
        mov ecx, dword ptr[eax+4]
        mov edx, expected_old_value
        mov esi, x
        mov eax, dword ptr[edx]
        mov edx, dword ptr[edx+4]
        lock CMPXCHG8B qword ptr[esi]
        pop ebx
        mov eax, 0
        pop esi
        setz al
    CAT_ASM_END

    CAT_FENCE_COMPILER

#elif defined(CAT_ASM_ATT) && defined(CAT_ISA_X86)

    u64 *target = (u64*)x;
    u32 *replace = (u32*)new_value;
    u64 *expected = (u64*)expected_old_value;
    bool retval;

    CAT_ASM_BEGIN
        "lock; CMPXCHG8B %0\n\t"
        "sete %%al"
        : "=m" (*target), "=a" (retval)
        : "m" (*target), "b" (replace[0]), "c" (replace[1]), "A" (*expected)
        : "memory", "cc"
    CAT_ASM_END

    CAT_FENCE_COMPILER
    return retval;

#else

#define CAT_NO_ATOMIC_CAS2 /* Platform/compiler does not support atomic CAS2 */

    (void) x; // avoid unused parameter warning
    (void) expected_old_value;
    (void) new_value;

    return true;

#endif
}
u32 cat::Atomic::Set ( volatile u32 *  x,
u32  new_value 
)

Definition at line 251 of file Atomic.hpp.

{
    CAT_FENCE_COMPILER

#if defined(CAT_COMPILER_MSVC)

#if (_MSC_VER <= 1400) // MSVC 2005
    u32 result = _InterlockedExchange((long*)x, new_value);
#else // MSVC 2008+
    u32 result = _InterlockedExchange((volatile LONG*)x, new_value);
#endif

    CAT_FENCE_COMPILER
    return result;

#elif defined(CAT_ASM_INTEL) && defined(CAT_WORD_32) && defined(CAT_ISA_X86)

    CAT_ASM_BEGIN
        mov edx,x
        mov eax,new_value
        lock XCHG [edx],eax
    CAT_ASM_END

    CAT_FENCE_COMPILER

#elif defined(CAT_ASM_ATT) && defined(CAT_ISA_X86)

    u32 retval;

    CAT_ASM_BEGIN
        "lock; XCHGl %%eax, %0\n\t"
        : "=m" (*x), "=a" (retval)
        : "m" (*x), "a" (new_value)
        : "memory", "cc"
    CAT_ASM_END

    CAT_FENCE_COMPILER
    return retval;

#else

#define CAT_NO_ATOMIC_SET /* Platform/compiler does not support atomic set */

    u32 old_x = *x;
    *x = new_value;

    CAT_FENCE_COMPILER
    return old_x;

#endif
}

Copyright © 2007-2010 by The Shadowrun: Awakened Team. This work is licensed under the GNU Lesser General Public License 3.

GNU Lesser General Public License 3 Sourceforge.net