00001
00002
00003
00004
00005 #pragma once
00006
00007 namespace MPMA
00008 {
00009
00010 inline void AtomicIntInc(volatile nuint *pint)
00011 {
00012 #ifdef __i386__
00013 asm( "lock incl (%0);"
00014 :
00015 :"r"(pint)
00016 :"%0", "memory");
00017 #else
00018 __sync_fetch_and_add(pint, 1);
00019 #endif
00020 }
00021
00022
00023 inline void AtomicIntDec(volatile nuint *pint)
00024 {
00025 #ifdef __i386__
00026 asm( "lock decl (%0);"
00027 :
00028 :"r"(pint)
00029 :"%0", "memory");
00030 #else
00031 __sync_fetch_and_add(pint, -1);
00032 #endif
00033 }
00034
00035
00036 inline nsint AtomicIntAdd(volatile nsint *pint, nsint addValue)
00037 {
00038 #ifdef __i386__
00039 int rval;
00040 asm volatile( "lock xaddl %2, (%1);"
00041 "movl %2, %0"
00042 :"=g"(rval)
00043 :"r"(pint), "r"(addValue)
00044 :"%0", "%1", "%2", "memory");
00045 return rval;
00046 #else
00047 return __sync_fetch_and_add(pint, addValue);
00048 #endif
00049 }
00050
00051
00052 inline bool AtomicCompareExchange(volatile nuint *pInt, nuint expectedValue, nuint newValue, volatile nuint &outResultValue)
00053 {
00054 #ifdef __i386__
00055 volatile nuint changed=0;
00056 nuint rval;
00057 asm(
00058 "lock cmpxchgl %4, (%2);"
00059 "jnz AtomCmpExch_Diff%=;"
00060 "movl %4, %%eax;"
00061 "incl %1;"
00062 "AtomCmpExch_Diff%=:;"
00063 "movl %%eax, %0;"
00064 :"=g"(rval), "=g"(changed)
00065 :"r"(pInt), "a"(expectedValue), "r"(newValue)
00066 :"memory", "cc");
00067
00068 outResultValue=rval;
00069 return changed!=0;
00070 #else
00071 nuint ret=__sync_val_compare_and_swap(pInt, expectedValue, newValue);
00072 if (ret==expectedValue)
00073 {
00074 outResultValue=newValue;
00075 return true;
00076 }
00077 else
00078 {
00079 outResultValue=ret;
00080 return false;
00081 }
00082 #endif
00083 }
00084
00085 };