os/kernelhwsrv/kerneltest/e32test/system/d_atomic.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test\system\d_atomic.cpp
    15 // LDD for testing atomic operations
    16 // 
    17 //
    18 
    19 #include <kernel/kern_priv.h>
    20 #include "t_atomic.h"
    21 
    22 class DAtomicTest;
    23 struct TPerThreadK : public TPerThread
    24 	{
    25 	TAny* iOldExtraContext;
    26 	const SSlowExecEntry* iOldSlowExecTable;
    27 	DAtomicTest* iCh;
    28 	TInt iId;
    29 	};
    30 
    31 
    32 class DAtomicTestFactory : public DLogicalDevice
    33 	{
    34 public:
    35 	DAtomicTestFactory();
    36 	~DAtomicTestFactory();
    37 	virtual TInt Install();
    38 	virtual void GetCaps(TDes8& aDes) const;
    39 	virtual TInt Create(DLogicalChannelBase*& aChannel);
    40 public:
    41 	};
    42 
    43 
    44 class DAtomicTest : public DLogicalChannelBase
    45 	{
    46 public:
    47 	virtual ~DAtomicTest();
    48 protected:
    49 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
    50 	virtual TInt Request(TInt aFunction, TAny* a1, TAny* a2);
    51 private:
    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();
    57 private:
    58 	TUint64A	iReg;
    59 	TPerThreadK	iPerThread[KMaxThreads];
    60 	TUint32		iXT[19];
    61 	};
    62 
    63 
    64 DAtomicTestFactory::DAtomicTestFactory()
    65 	{
    66 	}
    67 
    68 DAtomicTestFactory::~DAtomicTestFactory()
    69 	{
    70 	}
    71 TInt DAtomicTestFactory::Create(DLogicalChannelBase*& aChannel)
    72 	{
    73 	aChannel = new DAtomicTest;
    74 	return KErrNone;
    75 	}
    76 
    77 TInt DAtomicTestFactory::Install()
    78 	{
    79 	return SetName(&KAtomicTestLddName);
    80 	}
    81 
    82 void DAtomicTestFactory::GetCaps(TDes8& aDes) const
    83 	{
    84 	// Not used but required as DLogicalDevice::GetCaps is pure virtual
    85 	}
    86 
    87 DECLARE_STANDARD_LDD()
    88 	{
    89 	return new DAtomicTestFactory;
    90 	}
    91 
    92 
    93 TInt DAtomicTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& /*aVer*/)
    94 	{
    95 	SetupExecTable();
    96 	return KErrNone;
    97 	}
    98 
    99 DAtomicTest::~DAtomicTest()
   100 	{
   101 	}
   102 
   103 void DAtomicTest::SetupExecTable()
   104 	{
   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;
   119 	}
   120 
   121 TInt DAtomicTest::Request(TInt aFunction, TAny* a1, TAny* a2)
   122 	{
   123 	TInt r = KErrNotSupported;
   124 	switch (aFunction)
   125 		{
   126 		case RTestAtomic::ETDGExecuteK:
   127 			{
   128 			TDGBase tdg;
   129 			kumemget32(&tdg, a1, sizeof(tdg));
   130 			r = tdg.Execute();
   131 			kumemput32(a1, &tdg, sizeof(tdg));
   132 			break;
   133 			}
   134 		case RTestAtomic::EInitialise:
   135 			{
   136 			kumemget32(&iReg, a1, sizeof(TUint64));
   137 			break;
   138 			}
   139 		case RTestAtomic::ERetrieve:
   140 			{
   141 			kumemput32(a1, &iReg, sizeof(TUint64));
   142 			break;
   143 			}
   144 		case RTestAtomic::ESetCurrentThreadTimeslice:
   145 			{
   146 			NKern::ThreadSetTimeslice(NKern::CurrentThread(), NKern::TimesliceTicks((TInt)a1));
   147 			r = KErrNone;
   148 			break;
   149 			}
   150 		case RTestAtomic::ESwitchExecTables:
   151 			{
   152 			TUint tid = (TUint)a1;
   153 			NThread* nt = NKern::CurrentThread();
   154 			DThread& t = Kern::CurrentThread();
   155 			if (Kern::NThreadToDThread(nt)==&t && tid<TUint(KMaxThreads))
   156 				{
   157 				TPerThreadK* p = iPerThread + tid;
   158 				p->iOldExtraContext = nt->iExtraContext;
   159 				p->iOldSlowExecTable = nt->iSlowExecTable;
   160 				p->iId = tid;
   161 				p->iCh = this;
   162 				nt->iExtraContext = p;
   163 				SSlowExecTable& sxt = *(SSlowExecTable*)iXT;
   164 				nt->iSlowExecTable = sxt.iEntries;
   165 				r = KErrNone;
   166 				}
   167 			break;
   168 			}
   169 		case RTestAtomic::EGetKernelMemoryAddress:
   170 			{
   171 			r = (TInt)NKern::CurrentThread();	// if we trash this the test should go bang
   172 			break;
   173 			}
   174 		default:
   175 			break;
   176 		}
   177 	return r;
   178 	}
   179 
   180 TInt DAtomicTest::XGetThreadInfo(TAny* aDest)
   181 	{
   182 	NThread* t = NKern::CurrentThread();
   183 	TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
   184 	kumemput32(aDest, p, sizeof(TPerThread));
   185 	return KErrNone;
   186 	}
   187 
   188 TInt DAtomicTest::XSetThreadInfo(const TAny* aSrc)
   189 	{
   190 	NThread* t = NKern::CurrentThread();
   191 	TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
   192 	kumemget32(p, aSrc, sizeof(TPerThread));
   193 	return KErrNone;
   194 	}
   195 
   196 TInt DAtomicTest::XAtomicAction(TAny* aPtr)
   197 	{
   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);
   205 	}
   206 
   207 TInt DAtomicTest::XRestore()
   208 	{
   209 	NThread* t = NKern::CurrentThread();
   210 	TPerThreadK* p = (TPerThreadK*)t->iExtraContext;
   211 	t->iExtraContext = p->iOldExtraContext;
   212 	t->iSlowExecTable = p->iOldSlowExecTable;
   213 	return KErrNone;
   214 	}