diff -r 000000000000 -r a41df078684a kerneltest/e32test/system/t_atomic_common.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/system/t_atomic_common.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,803 @@ +// Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\system\t_atomic_common.cpp +// +// + +#ifdef __KERNEL_MODE__ +#include +#else +#define __E32TEST_EXTENSION__ + +#include + +extern RTest test; + +#define __INCLUDE_FUNC_NAMES__ +#endif + +#define __INCLUDE_ATOMIC_FUNCTIONS__ +#define __INCLUDE_CONTROL_FUNCTIONS__ +#define __INCLUDE_FUNCTION_ATTRIBUTES__ + +#include "t_atomic.h" + +#define DEBUGPRINTVAR(x) \ + { \ + const TUint8* p = (const TUint8*)&(x); \ + DEBUGPRINT("Line %d: " #x "=%02x %02x %02x %02x %02x %02x %02x %02x", __LINE__, p[0], p[1], p[2], p[3], p[4], p[5], p[6], p[7]); \ + } + +extern "C" { + +// Simulated versions of atomic functions without the atomicity +#define __LOAD(T) return *(T*)a +#define __STORE(T) *(T*)a=v; return v +#define __SWP(T) T oldv=*(T*)a; *(T*)a=v; return oldv +#define __CAS(T) if (*(T*)a==*q) {*(T*)a=v; return 1;} *q=*(T*)a; return 0 +#define __ADD(T) T oldv=*(T*)a; *(T*)a=(T)(oldv+v); return oldv +#define __AND(T) T oldv=*(T*)a; *(T*)a=(T)(oldv&v); return oldv +#define __IOR(T) T oldv=*(T*)a; *(T*)a=(T)(oldv|v); return oldv +#define __XOR(T) T oldv=*(T*)a; *(T*)a=(T)(oldv^v); return oldv +#define __AXO(T) T oldv=*(T*)a; *(T*)a=(T)((oldv&u)^v); return oldv +#define __TA(T) T oldv=*(T*)a; *(T*)a=(T)(oldv+((oldv>=t)?u:v)); return oldv + +TUint8 __nonatomic_load8(const volatile TAny* a) + { + __LOAD(TUint8); + } + +TUint8 __nonatomic_store8(volatile TAny* a, TUint8 v) + { + __STORE(TUint8); + } + +TUint8 __nonatomic_swp8(volatile TAny* a, TUint8 v) + { + __SWP(TUint8); + } + +TBool __nonatomic_cas8(volatile TAny* a, TUint8* q, TUint8 v) + { + __CAS(TUint8); + } + +TUint8 __nonatomic_add8(volatile TAny* a, TUint8 v) + { + __ADD(TUint8); + } + +TUint8 __nonatomic_and8(volatile TAny* a, TUint8 v) + { + __AND(TUint8); + } + +TUint8 __nonatomic_ior8(volatile TAny* a, TUint8 v) + { + __IOR(TUint8); + } + +TUint8 __nonatomic_xor8(volatile TAny* a, TUint8 v) + { + __XOR(TUint8); + } + +TUint8 __nonatomic_axo8(volatile TAny* a, TUint8 u, TUint8 v) + { + __AXO(TUint8); + } + +TUint8 __nonatomic_tau8(volatile TAny* a, TUint8 t, TUint8 u, TUint8 v) + { + __TA(TUint8); + } + +TInt8 __nonatomic_tas8(volatile TAny* a, TInt8 t, TInt8 u, TInt8 v) + { + __TA(TInt8); + } + + +TUint16 __nonatomic_load16(const volatile TAny* a) + { + __LOAD(TUint16); + } + +TUint16 __nonatomic_store16(volatile TAny* a, TUint16 v) + { + __STORE(TUint16); + } + +TUint16 __nonatomic_swp16(volatile TAny* a, TUint16 v) + { + __SWP(TUint16); + } + +TBool __nonatomic_cas16(volatile TAny* a, TUint16* q, TUint16 v) + { + __CAS(TUint16); + } + +TUint16 __nonatomic_add16(volatile TAny* a, TUint16 v) + { + __ADD(TUint16); + } + +TUint16 __nonatomic_and16(volatile TAny* a, TUint16 v) + { + __AND(TUint16); + } + +TUint16 __nonatomic_ior16(volatile TAny* a, TUint16 v) + { + __IOR(TUint16); + } + +TUint16 __nonatomic_xor16(volatile TAny* a, TUint16 v) + { + __XOR(TUint16); + } + +TUint16 __nonatomic_axo16(volatile TAny* a, TUint16 u, TUint16 v) + { + __AXO(TUint16); + } + +TUint16 __nonatomic_tau16(volatile TAny* a, TUint16 t, TUint16 u, TUint16 v) + { + __TA(TUint16); + } + +TInt16 __nonatomic_tas16(volatile TAny* a, TInt16 t, TInt16 u, TInt16 v) + { + __TA(TInt16); + } + + +TUint32 __nonatomic_load32(const volatile TAny* a) + { + __LOAD(TUint32); + } + +TUint32 __nonatomic_store32(volatile TAny* a, TUint32 v) + { + __STORE(TUint32); + } + +TUint32 __nonatomic_swp32(volatile TAny* a, TUint32 v) + { + __SWP(TUint32); + } + +TBool __nonatomic_cas32(volatile TAny* a, TUint32* q, TUint32 v) + { + __CAS(TUint32); + } + +TUint32 __nonatomic_add32(volatile TAny* a, TUint32 v) + { + __ADD(TUint32); + } + +TUint32 __nonatomic_and32(volatile TAny* a, TUint32 v) + { + __AND(TUint32); + } + +TUint32 __nonatomic_ior32(volatile TAny* a, TUint32 v) + { + __IOR(TUint32); + } + +TUint32 __nonatomic_xor32(volatile TAny* a, TUint32 v) + { + __XOR(TUint32); + } + +TUint32 __nonatomic_axo32(volatile TAny* a, TUint32 u, TUint32 v) + { + __AXO(TUint32); + } + +TUint32 __nonatomic_tau32(volatile TAny* a, TUint32 t, TUint32 u, TUint32 v) + { + __TA(TUint32); + } + +TInt32 __nonatomic_tas32(volatile TAny* a, TInt32 t, TInt32 u, TInt32 v) + { + __TA(TInt32); + } + + +TUint64 __nonatomic_load64(const volatile TAny* a) + { + __LOAD(TUint64); + } + +TUint64 __nonatomic_store64(volatile TAny* a, TUint64 v) + { + __STORE(TUint64); + } + +TUint64 __nonatomic_swp64(volatile TAny* a, TUint64 v) + { + __SWP(TUint64); + } + +TBool __nonatomic_cas64(volatile TAny* a, TUint64* q, TUint64 v) + { + __CAS(TUint64); + } + +TUint64 __nonatomic_add64(volatile TAny* a, TUint64 v) + { + __ADD(TUint64); + } + +TUint64 __nonatomic_and64(volatile TAny* a, TUint64 v) + { + __AND(TUint64); + } + +TUint64 __nonatomic_ior64(volatile TAny* a, TUint64 v) + { + __IOR(TUint64); + } + +TUint64 __nonatomic_xor64(volatile TAny* a, TUint64 v) + { + __XOR(TUint64); + } + +TUint64 __nonatomic_axo64(volatile TAny* a, TUint64 u, TUint64 v) + { + __AXO(TUint64); + } + +TUint64 __nonatomic_tau64(volatile TAny* a, TUint64 t, TUint64 u, TUint64 v) + { + __TA(TUint64); + } + +TInt64 __nonatomic_tas64(volatile TAny* a, TInt64 t, TInt64 u, TInt64 v) + { + __TA(TInt64); + } + +} // extern "C" + + +#define DEBUGPRINTxyrc() \ + DEBUGPRINTVAR(x); \ + DEBUGPRINTVAR(y); \ + DEBUGPRINTVAR(r); \ + DEBUGPRINTVAR(c) + +template TInt DoLoadTest(TInt aIndex, TAny* aPtr, T aInitialValue) + { +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("DoLoadTest %d %08x", aIndex, aPtr); +#endif + typename TLoadFn::F atomic = (typename TLoadFn::F)AtomicFuncPtr[aIndex]; + typename TLoadFn::F control = (typename TLoadFn::F)ControlFuncPtr[aIndex]; + T& x = *(T*)aPtr; + x = aInitialValue; + T y = aInitialValue; + T r = atomic(&x); + T c = control(&y); + if (r!=c || x!=y) + { + DEBUGPRINTxyrc(); + return __LINE__; + } + return 0; + } + +template TInt DoRmw1Test(TInt aIndex, TAny* aPtr, T aInitialValue, T a1) + { +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("DoRmw1Test %d %08x", aIndex, aPtr); +#endif + typename TRmw1Fn::F atomic = (typename TRmw1Fn::F)AtomicFuncPtr[aIndex]; + typename TRmw1Fn::F control = (typename TRmw1Fn::F)ControlFuncPtr[aIndex]; + T& x = *(T*)aPtr; + x = aInitialValue; + T y = aInitialValue; + T r = atomic(&x,a1); + T c = control(&y,a1); + if (r!=c || x!=y) + { + DEBUGPRINTxyrc(); + return __LINE__; + } + return 0; + } + +template TInt DoRmw2Test(TInt aIndex, TAny* aPtr, T aInitialValue, T a1, T a2) + { +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("DoRmw2Test %d %08x", aIndex, aPtr); +#endif + typename TRmw2Fn::F atomic = (typename TRmw2Fn::F)AtomicFuncPtr[aIndex]; + typename TRmw2Fn::F control = (typename TRmw2Fn::F)ControlFuncPtr[aIndex]; + T& x = *(T*)aPtr; + x = aInitialValue; + T y = aInitialValue; + T r = atomic(&x,a1,a2); + T c = control(&y,a1,a2); + if (r!=c || x!=y) + { + DEBUGPRINTxyrc(); + return __LINE__; + } + return 0; + } + +template TInt DoRmw3Test(TInt aIndex, TAny* aPtr, T aInitialValue, T a1, T a2, T a3) + { +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("DoRmw3Test %d %08x", aIndex, aPtr); +#endif + typename TRmw3Fn::F atomic = (typename TRmw3Fn::F)AtomicFuncPtr[aIndex]; + typename TRmw3Fn::F control = (typename TRmw3Fn::F)ControlFuncPtr[aIndex]; + T& x = *(T*)aPtr; + x = aInitialValue; + T y = aInitialValue; + T r = atomic(&x,a1,a2,a3); + T c = control(&y,a1,a2,a3); + if (r!=c || x!=y) + { + DEBUGPRINTxyrc(); + return __LINE__; + } + return 0; + } + +template TInt DoCasTest(TInt aIndex, TAny* aPtr, T aInitialValue, T aExpectedValue, T aFinalValue) + { +#ifdef __EXTRA_DEBUG__ + DEBUGPRINT("DoCasTest %d %08x", aIndex, aPtr); +#endif + typename TCasFn::F atomic = (typename TCasFn::F)AtomicFuncPtr[aIndex]; + typename TCasFn::F control = (typename TCasFn::F)ControlFuncPtr[aIndex]; + T& x = *(T*)aPtr; + x = aInitialValue; + T ex = aExpectedValue; + T y = aInitialValue; + T ey = aExpectedValue; + TBool r = atomic(&x,&ex,aFinalValue); + TBool c = control(&y,&ey,aFinalValue); + TInt line = 0; + if (r && !c) + line = __LINE__; + else if (!r && c) + line = __LINE__; + else if (x!=y) + line = __LINE__; + else if (ex!=ey) + line = __LINE__; + else if (r && x!=aFinalValue) + line = __LINE__; + else if (!r && ex!=aInitialValue) + line = __LINE__; + if (line) + { + DEBUGPRINT("r=%d",r); + DEBUGPRINTVAR(x); + DEBUGPRINTVAR(ex); + DEBUGPRINT("c=%d",c); + DEBUGPRINTVAR(y); + DEBUGPRINTVAR(ey); + } + return line; + } + + + +TEnclosed::TEnclosed(TInt aSize) + { + iOffset = -1; + iSize = aSize; + iData = (TUint64*)((T_UintPtr(i_Data) + 7) &~ 7); // align up to next 8 byte boundary + iBackup = iData + 8; + } + +TAny* TEnclosed::Ptr() + { + return ((TUint8*)iData + iOffset); + } + +TInt TEnclosed::Next() + { + const TInt KLimit[8] = {8, 16, 0, 32, 0, 0, 0, 32}; + if (iOffset<0) + iOffset = 0; + else + { + TInt r = Verify(); + if (r!=0) + return r; + iOffset += iSize; + } + if (iOffset >= KLimit[iSize-1]) + return KErrEof; + Init(); + return KErrNone; + } + +void TEnclosed::Init() + { + TUint32 x = iOffset+1; + x |= (x<<8); + x |= (x<<16); + TUint32* d = (TUint32*)iData; + TUint32* b = (TUint32*)iBackup; + TInt i; + for (i=0; i<16; ++i) + { + *d++ = x; + *b++ = x; + x = 69069*x + 41; + } + } + +TInt TEnclosed::Verify() + { + TUint8* d = (TUint8*)iData; + const TUint8* b = (const TUint8*)iBackup; + TInt i; + for (i=0; i(iIndex, ptr, (TUint8)i0); break; + case 2: res = DoLoadTest(iIndex, ptr, (TUint16)i0); break; + case 4: res = DoLoadTest(iIndex, ptr, (TUint32)i0); break; + case 8: res = DoLoadTest(iIndex, ptr, i0); break; + default: res = __LINE__; break; + } + break; + } + case EFuncTypeRmw1: + { + switch (size) + { + case 1: res = DoRmw1Test(iIndex, ptr, (TUint8)i0, (TUint8)i1); break; + case 2: res = DoRmw1Test(iIndex, ptr, (TUint16)i0, (TUint16)i1); break; + case 4: res = DoRmw1Test(iIndex, ptr, (TUint32)i0, (TUint32)i1); break; + case 8: res = DoRmw1Test(iIndex, ptr, i0, i1); break; + default: res = __LINE__; break; + } + break; + } + case EFuncTypeRmw2: + { + switch (size) + { + case 1: res = DoRmw2Test(iIndex, ptr, (TUint8)i0, (TUint8)i1, (TUint8)i2); break; + case 2: res = DoRmw2Test(iIndex, ptr, (TUint16)i0, (TUint16)i1, (TUint16)i2); break; + case 4: res = DoRmw2Test(iIndex, ptr, (TUint32)i0, (TUint32)i1, (TUint32)i2); break; + case 8: res = DoRmw2Test(iIndex, ptr, i0, i1, i2); break; + default: res = __LINE__; break; + } + break; + } + case EFuncTypeRmw3: + { + if (func==EAtomicFuncTAU) + { + switch (size) + { + case 1: res = DoRmw3Test(iIndex, ptr, (TUint8)i0, (TUint8)i1, (TUint8)i2, (TUint8)i3); break; + case 2: res = DoRmw3Test(iIndex, ptr, (TUint16)i0, (TUint16)i1, (TUint16)i2, (TUint16)i3); break; + case 4: res = DoRmw3Test(iIndex, ptr, (TUint32)i0, (TUint32)i1, (TUint32)i2, (TUint32)i3); break; + case 8: res = DoRmw3Test(iIndex, ptr, i0, i1, i2, i3); break; + default: res = __LINE__; break; + } + } + else if (func==EAtomicFuncTAS) + { + switch (size) + { + case 1: res = DoRmw3Test(iIndex, ptr, (TInt8)i0, (TInt8)i1, (TInt8)i2, (TInt8)i3); break; + case 2: res = DoRmw3Test(iIndex, ptr, (TInt16)i0, (TInt16)i1, (TInt16)i2, (TInt16)i3); break; + case 4: res = DoRmw3Test(iIndex, ptr, (TInt32)i0, (TInt32)i1, (TInt32)i2, (TInt32)i3); break; + case 8: res = DoRmw3Test(iIndex, ptr, i0, i1, i2, i3); break; + default: res = __LINE__; break; + } + } + else + res = __LINE__; + break; + } + case EFuncTypeCas: + { + switch (size) + { + case 1: res = DoCasTest(iIndex, ptr, (TUint8)i0, (TUint8)i1, (TUint8)i2); break; + case 2: res = DoCasTest(iIndex, ptr, (TUint16)i0, (TUint16)i1, (TUint16)i2); break; + case 4: res = DoCasTest(iIndex, ptr, (TUint32)i0, (TUint32)i1, (TUint32)i2); break; + case 8: res = DoCasTest(iIndex, ptr, i0, i1, i2); break; + default: res = __LINE__; break; + } + break; + } + default: + res = __LINE__; + break; + } + if (res) + return res; + } + if (res == KErrEof) + res = 0; + return res; + } + +#ifndef __KERNEL_MODE__ +void TDGBase::Dump(const char* aTitle) + { + TPtrC8 fname8((const TText8*)FuncName[iIndex]); + TBuf<64> fname; + fname.Copy(fname8); + DEBUGPRINT(aTitle); + DEBUGPRINT("iIndex=%d (%S)", iIndex, &fname); + DEBUGPRINT("i0 = %08x %08x", I64HIGH(i0), I64LOW(i0)); + DEBUGPRINT("i1 = %08x %08x", I64HIGH(i1), I64LOW(i1)); + DEBUGPRINT("i2 = %08x %08x", I64HIGH(i2), I64LOW(i2)); + DEBUGPRINT("i3 = %08x %08x", I64HIGH(i3), I64LOW(i3)); + } +#endif + +template TInt DoSwap(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TRmw1Fn::F atomic = (typename TRmw1Fn::F)AtomicFuncPtr[aA.iIndex]; + T newv = (T)aA.i0; + T orig = atomic(aPtr, newv); + T xr = (T)(newv ^ orig); + aT->iXor ^= xr; + T diff = (T)(newv - orig); + aT->iDiff += diff; + return 0; + } + +template TInt DoAdd(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TRmw1Fn::F atomic = (typename TRmw1Fn::F)AtomicFuncPtr[aA.iIndex]; + T arg = (T)aA.i0; + T orig = atomic(aPtr, arg); + T xr = (T)((arg+orig) ^ orig); + aT->iXor ^= xr; + aT->iDiff += arg; + return 0; + } + +template TInt DoXor(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TRmw1Fn::F atomic = (typename TRmw1Fn::F)AtomicFuncPtr[aA.iIndex]; + T arg = (T)aA.i0; + T orig = atomic(aPtr, arg); + T diff = (T)((arg^orig) - orig); + aT->iDiff += diff; + aT->iXor ^= arg; + return 0; + } + +template TInt DoAndOr(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TRmw1Fn::F atomic_and = (typename TRmw1Fn::F)AtomicFuncPtr[aA.iIndex]; + typename TRmw1Fn::F atomic_or = (typename TRmw1Fn::F)AtomicFuncPtr[aA.iIndex+4]; + T aarg = (T)aA.i0; + T oarg = (T)aA.i1; + T aorig = atomic_and(aPtr, aarg); + T oorig = atomic_or(aPtr, oarg); + T adiff = (T)((aorig & aarg) - aorig); + T odiff = (T)((oorig | oarg) - oorig); + aT->iDiff += adiff + odiff; + T axor = (T)((aorig & aarg) ^ aorig); + T oxor = (T)((oorig | oarg) ^ oorig); + aT->iXor ^= axor ^ oxor; + return 0; + } + +template TInt DoAxo(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TRmw2Fn::F atomic = (typename TRmw2Fn::F)AtomicFuncPtr[aA.iIndex]; + T aarg = (T)aA.i0; + T xarg = (T)aA.i1; + T orig = atomic(aPtr, aarg, xarg); + T newv = (T)((orig & aarg) ^ xarg); + aT->iDiff += (newv - orig); + aT->iXor ^= (newv ^ orig); + return 0; + } + +template TInt DoThAdd(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TRmw3Fn::F atomic = (typename TRmw3Fn::F)AtomicFuncPtr[aA.iIndex]; + T thr = (T)aA.i0; + T arg1 = (T)aA.i1; + T arg2 = (T)aA.i2; + T orig = atomic(aPtr, thr, arg1, arg2); + T newv = (T)((orig >= thr) ? (orig + arg1) : (orig + arg2)); + aT->iDiff += (orig >= thr) ? arg1 : arg2; + aT->iXor ^= (newv ^ orig); + return 0; + } + +template TInt DoCas(TAny* aPtr, TPerThread* aT, TAtomicAction& aA, T*) + { + typename TCasFn::F atomic = (typename TCasFn::F)AtomicFuncPtr[aA.iIndex]; + T orig = *(const volatile T*)aPtr; + T newv; + TBool done = FALSE; + TUint32 fails = 0xffffffffu; + do { + ++fails; + newv = Transform::F(orig); + done = atomic(aPtr, &orig, newv); + } while(!done); + aT->iFailCount += fails; + ++aT->iDiff; + aT->iXor ^= (newv ^ orig); + return 0; + } + +volatile TUint Dummy; +extern "C" TInt DoAtomicAction(TAny* aPtr, TPerThread* aT, TAtomicAction& aA) + { + TUint x = TUint(aT)*0x9E3779B9u; + x = (x>>8)&15; + while(x--) + ++Dummy; + TInt r = KErrNotSupported; + TUint attr = FuncAttr[aA.iIndex]; + TUint func = ATTR_TO_FUNC(attr); + TUint size = ATTR_TO_SIZE(attr); + switch (size) + { + case 1: + { + TUint8 xx; + TUint8* dummy = &xx; + TInt8 yy; + TInt8* sdummy = &yy; + switch (func) + { + case EAtomicFuncSWP: r=DoSwap(aPtr, aT, aA, dummy); break; + case EAtomicFuncADD: r=DoAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncAND: r=DoAndOr(aPtr, aT, aA, dummy); break; + case EAtomicFuncXOR: r=DoXor(aPtr, aT, aA, dummy); break; + case EAtomicFuncAXO: r=DoAxo(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAU: r=DoThAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAS: r=DoThAdd(aPtr, aT, aA, sdummy); break; + case EAtomicFuncCAS: r=DoCas(aPtr, aT, aA, dummy); break; + default: break; + } + break; + } + case 2: + { + TUint16 xx; + TUint16* dummy = &xx; + TInt16 yy; + TInt16* sdummy = &yy; + switch (func) + { + case EAtomicFuncSWP: r=DoSwap(aPtr, aT, aA, dummy); break; + case EAtomicFuncADD: r=DoAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncAND: r=DoAndOr(aPtr, aT, aA, dummy); break; + case EAtomicFuncXOR: r=DoXor(aPtr, aT, aA, dummy); break; + case EAtomicFuncAXO: r=DoAxo(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAU: r=DoThAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAS: r=DoThAdd(aPtr, aT, aA, sdummy); break; + case EAtomicFuncCAS: r=DoCas(aPtr, aT, aA, dummy); break; + default: break; + } + break; + } + case 4: + { + TUint32 xx; + TUint32* dummy = &xx; + TInt32 yy; + TInt32* sdummy = &yy; + switch (func) + { + case EAtomicFuncSWP: r=DoSwap(aPtr, aT, aA, dummy); break; + case EAtomicFuncADD: r=DoAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncAND: r=DoAndOr(aPtr, aT, aA, dummy); break; + case EAtomicFuncXOR: r=DoXor(aPtr, aT, aA, dummy); break; + case EAtomicFuncAXO: r=DoAxo(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAU: r=DoThAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAS: r=DoThAdd(aPtr, aT, aA, sdummy); break; + case EAtomicFuncCAS: r=DoCas(aPtr, aT, aA, dummy); break; + default: break; + } + break; + } + case 8: + { + TUint64A xx; + TUint64* dummy = &xx; + TInt64A yy; + TInt64* sdummy = &yy; + switch (func) + { + case EAtomicFuncSWP: r=DoSwap(aPtr, aT, aA, dummy); break; + case EAtomicFuncADD: r=DoAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncAND: r=DoAndOr(aPtr, aT, aA, dummy); break; + case EAtomicFuncXOR: r=DoXor(aPtr, aT, aA, dummy); break; + case EAtomicFuncAXO: r=DoAxo(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAU: r=DoThAdd(aPtr, aT, aA, dummy); break; + case EAtomicFuncTAS: r=DoThAdd(aPtr, aT, aA, sdummy); break; + case EAtomicFuncCAS: r=DoCas(aPtr, aT, aA, dummy); break; + default: break; + } + break; + } + default: + break; + } + ++aT->iCount; + return r; + } + + +