base_thread_atomic2.hh

Go to the documentation of this file.
00001 /*
00008  * LEGAL:   COPYRIGHT (C) 2007 JIM E. BROOKS
00009  *          THIS SOURCE CODE IS RELEASED UNDER THE TERMS
00010  *          OF THE GNU GENERAL PUBLIC LICENSE VERSION 2 (GPL 2).
00011  *****************************************************************************/
00012 
00013 //------------------------------------------------------------------------------
00014 // #included in middle of Atomic class.
00015 
00019     inline CLASS_METHOD
00020     void
00021     Set( ATOMIC_TYPE* out, ATOMIC_TYPE val )
00022     {
00023         *out = val;  // atomic on x86 and powerpc
00024     }
00025 
00029     inline CLASS_METHOD
00030     ATOMIC_TYPE
00031     Add( ATOMIC_TYPE* sum, ATOMIC_TYPE addend )
00032     {
00033 #if CPU_X86
00034         // tmp is assigned with addend by C++.
00035         // XADD assigns tmp with oldSum.
00036         // ret val will be: newSum = tmp<oldSum> + addend
00037         ATOMIC_TYPE tmp = addend;
00038         asm volatile ( "lock; xadd %0,%1"
00039                        : "=r"(tmp), "=m"(*sum)
00040                        : "0"(tmp), "m"(*sum)
00041                        : "memory", "cc" );
00042         return tmp + addend;  // same value stored at sum
00043 #elif GCC_VERSION >= 40100
00044         return __sync_add_and_fetch( sum, addend );
00045 #elif CPU_PPC
00046         // linux-2.6.19/include/asm-powerpc/system.h : atomic_add_return()
00047         // This PowerPC assembly code was tested on Mac G4 (ppc32)
00048         // and Sony PS3 Cell (ppc64).
00049         ATOMIC_TYPE tmp;
00050         asm volatile( "    sync             \n"
00051                       "1:  lwarx %0,0,%2    \n"
00052                       "    add    %0,%1,%0  \n"
00053                       "    stwcx. %0,0,%2   \n"
00054                       "    bne-    1b       \n"
00055                       "    isync            \n"
00056                       : "=&r" (tmp)
00057                       : "r" (addend), "r" (sum)
00058                       : "cc", "memory" );
00059         return tmp;
00060 #else
00061 #error
00062 #endif
00063     }
00064 
00069     inline CLASS_METHOD
00070     ATOMIC_TYPE
00071     Xchg( ATOMIC_TYPE* ptr, ATOMIC_TYPE val )
00072     {
00073 #if CPU_X86
00074         asm volatile( "xchg %0, %1"
00075                       : "=r"(val), "=m"(*(ptr))
00076                       : "0"(val), "r"(*(ptr))
00077                       );
00078         return val;  // val now has old value ptr was pointing to
00079 #elif GCC_VERSION >= 40100
00080         // A misnomer.  It does an atomic exchange.
00081         return __sync_lock_test_and_set( ptr, val );
00082 #elif CPU_PPC
00083         long prev;
00084         asm volatile( "    sync             \n"
00085                       "1:  lwarx   %0,0,%2  \n"
00086                       "    stwcx.  %3,0,%2  \n"
00087                       "    bne-    1b       \n"
00088                       "    isync            \n"
00089                       : "=&r" (prev), "+m" (ptr)
00090                       : "r" (ptr), "r" (val)
00091                       : "cc", "memory");
00092         return prev;
00093 #else
00094 #error
00095 #endif
00096     }
00097 
00098 //------------------------------------------------------------------------------
Palomino 3D Engine documents generated by doxygen 1.5.3 on Fri Nov 23 11:26:07 2007