00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef __CS_CSUTIL_ATOMICOPS_SPARC_H__
00020 #define __CS_CSUTIL_ATOMICOPS_SPARC_H__
00021
00022 #ifndef DOXYGEN_RUN
00023
00024 namespace CS
00025 {
00026 namespace Threading
00027 {
00028 class AtomicOperationsSparc
00029 {
00030 public:
00031 inline static int32 Set (int32* target, int32 value)
00032 {
00033 *const_cast<volatile int32*> (target) = value;
00034 __asm__ __volatile__
00035 (
00036 "membar #StoreStore | #StoreLoad"
00037 : : : "memory"
00038 );
00039 return value;
00040 }
00041
00042 inline static void* Set (void** target, void* value)
00043 {
00044 return (void*)Set ((int32*)target, (int32)value);
00045 }
00046
00047 inline static int32 CompareAndSet (int32* target, int32 value,
00048 int32 comparand)
00049 {
00050 int32 prev;
00051
00052 __asm__ __volatile__
00053 (
00054 "cas [%1],%2,%0"
00055 : "+r" (value)
00056 : "r" (target), "r" (comparand)
00057 );
00058
00059 return prev;
00060 }
00061
00062 inline static void* CompareAndSet (void** target, void* value,
00063 void* comparand)
00064 {
00065 return (void*)CompareAndSet ((int32*)target, (int32)value,
00066 (int32)comparand);
00067 }
00068
00069 inline static int32 Increment (int32* target, int32 incr = 1)
00070 {
00071
00072 int32 prevValue, currValue, nextValue;
00073 do
00074 {
00075 __asm__ __volatile__
00076 (
00077 "membar #StoreLoad | #LoadLoad"
00078 : : : "memory"
00079 );
00080
00081 currValue = *reinterpret_cast<volatile int32*> (target);
00082 nextValue = currValue + incr;
00083 prevValue = CompareAndSet (target, nextValue, currValue);
00084 } while(prevValue == currValue);
00085 return nextValue;
00086 }
00087
00088 inline static int32 Decrement (int32* target)
00089 {
00090 return (int32)Increment (target, -1);
00091 }
00092 };
00093 }
00094 }
00095
00096 #endif // DOXYGEN_RUN
00097
00098 #endif // __CS_CSUTIL_ATOMICOPS_SPARC_H__