00001
00002
00003
00004
00005 #pragma once
00006
00007 namespace MPMA
00008 {
00009
00010 inline void AtomicIntInc(volatile nuint *pint)
00011 {
00012 #ifdef _WIN64
00013 _InterlockedIncrement64((volatile __int64*)pint);
00014 #else //WIN32
00015 __asm
00016 {
00017 mov eax, pint;
00018 lock inc dword ptr [eax];
00019 }
00020 #endif
00021 }
00022
00023
00024 inline void AtomicIntDec(volatile nuint *pint)
00025 {
00026 #ifdef _WIN64
00027 _InterlockedDecrement64((volatile __int64*)pint);
00028 #else //WIN32
00029 __asm
00030 {
00031 mov eax, pint;
00032 lock dec dword ptr [eax];
00033 }
00034 #endif
00035 }
00036
00037
00038 inline nsint AtomicIntAdd(volatile nsint *pint, nsint addValue)
00039 {
00040 #ifdef _WIN64
00041 return _InterlockedExchangeAdd64((volatile __int64*)pint, addValue);
00042 #else //WIN32
00043 int rval;
00044 __asm
00045 {
00046 mov eax, addValue;
00047 mov ebx, pint;
00048 lock xadd dword ptr [ebx], eax;
00049 mov rval, eax;
00050 }
00051 return rval;
00052 #endif
00053 }
00054
00055
00056 inline bool AtomicCompareExchange(volatile nuint *pInt, nuint expectedValue, nuint newValue, volatile nuint &outResultValue)
00057 {
00058 #ifdef _WIN64
00059 nuint rval;
00060 rval=_InterlockedCompareExchange64((volatile __int64*)pInt, newValue, expectedValue);
00061 if (rval==expectedValue)
00062 {
00063 outResultValue=newValue;
00064 return true;
00065 }
00066 else
00067 {
00068 outResultValue=rval;
00069 return false;
00070 }
00071
00072 #else //WIN32
00073 nuint rval;
00074 nuint changed=0;
00075 __asm
00076 {
00077 mov eax, expectedValue;
00078 mov ebx, pInt;
00079 mov ecx, newValue;
00080 lock cmpxchg [ebx], ecx;
00081 jnz AtomCmpExch_Diff;
00082 mov eax,ecx;
00083 inc changed;
00084 AtomCmpExch_Diff:
00085 mov rval, eax;
00086 }
00087 outResultValue=rval;
00088 return changed!=0;
00089 #endif
00090 }
00091
00092 };