First public contribution.
1 // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\system\d_atomic.cpp
15 // LDD for testing atomic operations
19 #include <kernel/kern_priv.h>
23 struct TPerThreadK : public TPerThread
25 TAny* iOldExtraContext;
26 const SSlowExecEntry* iOldSlowExecTable;
32 class DAtomicTestFactory : public DLogicalDevice
36 ~DAtomicTestFactory();
37 virtual TInt Install();
38 virtual void GetCaps(TDes8& aDes) const;
39 virtual TInt Create(DLogicalChannelBase*& aChannel);
44 class DAtomicTest : public DLogicalChannelBase
47 virtual ~DAtomicTest();
49 virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
50 virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
52 void SetupExecTable();
53 static TInt XGetThreadInfo(TAny* aDest);
54 static TInt XSetThreadInfo(const TAny* aSrc);
55 static TInt XAtomicAction(TAny* aPtr);
56 static TInt XRestore();
59 TPerThreadK iPerThread[KMaxThreads];
64 DAtomicTestFactory::DAtomicTestFactory()
68 DAtomicTestFactory::~DAtomicTestFactory()
71 TInt DAtomicTestFactory::Create(DLogicalChannelBase*& aChannel)
73 aChannel = new DAtomicTest;
77 TInt DAtomicTestFactory::Install()
79 return SetName(&KAtomicTestLddName);
82 void DAtomicTestFactory::GetCaps(TDes8& aDes) const
84 // Not used but required as DLogicalDevice::GetCaps is pure virtual
87 DECLARE_STANDARD_LDD()
89 return new DAtomicTestFactory;
93 TInt DAtomicTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
99 DAtomicTest::~DAtomicTest()
103 void DAtomicTest::SetupExecTable()
105 NThread* t = NKern::CurrentThread();
106 SSlowExecTable& sxt = *(SSlowExecTable*)iXT;
107 const SSlowExecTable& orig_sxt = *_LOFF(t->iSlowExecTable, SSlowExecTable, iEntries);
108 sxt.iSlowExecCount = 4; // get thread info, set thread info, atomic action, restore exec table
109 sxt.iInvalidExecHandler = orig_sxt.iInvalidExecHandler;
110 sxt.iPreprocessHandler = 0; // not used
111 sxt.iEntries[0].iFlags = 0; // don't do anything special on entry or exit
112 sxt.iEntries[0].iFunction = (TLinAddr)&XGetThreadInfo;
113 sxt.iEntries[1].iFlags = 0; // don't do anything special on entry or exit
114 sxt.iEntries[1].iFunction = (TLinAddr)&XSetThreadInfo;
115 sxt.iEntries[2].iFlags = 0; // don't do anything special on entry or exit
116 sxt.iEntries[2].iFunction = (TLinAddr)&XAtomicAction;
117 sxt.iEntries[3].iFlags = 0; // don't do anything special on entry or exit
118 sxt.iEntries[3].iFunction = (TLinAddr)&XRestore;
121 TInt DAtomicTest::Request(TInt aFunction, TAny* a1, TAny* a2)
123 TInt r = KErrNotSupported;
126 case RTestAtomic::ETDGExecuteK:
129 kumemget32(&tdg, a1, sizeof(tdg));
131 kumemput32(a1, &tdg, sizeof(tdg));
134 case RTestAtomic::EInitialise:
136 kumemget32(&iReg, a1, sizeof(TUint64));
139 case RTestAtomic::ERetrieve:
141 kumemput32(a1, &iReg, sizeof(TUint64));
144 case RTestAtomic::ESetCurrentThreadTimeslice:
146 NKern::ThreadSetTimeslice(NKern::CurrentThread(), NKern::TimesliceTicks((TInt)a1));
150 case RTestAtomic::ESwitchExecTables:
152 TUint tid = (TUint)a1;
153 NThread* nt = NKern::CurrentThread();
154 DThread& t = Kern::CurrentThread();
155 if (Kern::NThreadToDThread(nt)==&t && tid<TUint(KMaxThreads))
157 TPerThreadK* p = iPerThread + tid;
158 p->iOldExtraContext = nt->iExtraContext;
159 p->iOldSlowExecTable = nt->iSlowExecTable;
162 nt->iExtraContext = p;
163 SSlowExecTable& sxt = *(SSlowExecTable*)iXT;
164 nt->iSlowExecTable = sxt.iEntries;
169 case RTestAtomic::EGetKernelMemoryAddress:
171 r = (TInt)NKern::CurrentThread(); // if we trash this the test should go bang
180 TInt DAtomicTest::XGetThreadInfo(TAny* aDest)
182 NThread* t = NKern::CurrentThread();
183 TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
184 kumemput32(aDest, p, sizeof(TPerThread));
188 TInt DAtomicTest::XSetThreadInfo(const TAny* aSrc)
190 NThread* t = NKern::CurrentThread();
191 TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
192 kumemget32(p, aSrc, sizeof(TPerThread));
196 TInt DAtomicTest::XAtomicAction(TAny* aPtr)
198 NThread* t = NKern::CurrentThread();
199 TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
200 TAtomicAction action;
201 kumemget32(&action, aPtr, sizeof(TAtomicAction));
202 if (action.iThread!=p->iId || TUint(action.iIndex)>=TUint(TOTAL_INDEXES))
203 return KErrNotSupported;
204 return DoAtomicAction(&p->iCh->iReg, p, action);
207 TInt DAtomicTest::XRestore()
209 NThread* t = NKern::CurrentThread();
210 TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
211 t->iExtraContext = p->iOldExtraContext;
212 t->iSlowExecTable = p->iOldSlowExecTable;