| 0 |      1 | // Copyright (c) 1997-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\nkern\d_implicit.cpp
 | 
|  |     15 | // LDD for testing nanokernel implicit system lock
 | 
|  |     16 | // 
 | 
|  |     17 | //
 | 
|  |     18 | 
 | 
|  |     19 | #define __INCLUDE_NTHREADBASE_DEFINES__
 | 
|  |     20 | 
 | 
|  |     21 | #include "platform.h"
 | 
|  |     22 | #include "nk_priv.h"
 | 
|  |     23 | #include "d_implicit.h"
 | 
|  |     24 | 
 | 
|  |     25 | #ifndef __SMP__
 | 
|  |     26 | #include "../misc/prbs.h"
 | 
|  |     27 | 
 | 
|  |     28 | const TInt KMajorVersionNumber=0;
 | 
|  |     29 | const TInt KMinorVersionNumber=1;
 | 
|  |     30 | const TInt KBuildVersionNumber=1;
 | 
|  |     31 | 
 | 
|  |     32 | const TInt KStackSize=1024;
 | 
|  |     33 | 
 | 
|  |     34 | inline NThreadBase::NThreadBase()
 | 
|  |     35 | 	{
 | 
|  |     36 | 	}
 | 
|  |     37 | 
 | 
|  |     38 | class DImpSysTestFactory : public DLogicalDevice
 | 
|  |     39 | //
 | 
|  |     40 | // Implicit system lock test LDD factory
 | 
|  |     41 | //
 | 
|  |     42 | 	{
 | 
|  |     43 | public:
 | 
|  |     44 | 	DImpSysTestFactory();
 | 
|  |     45 | 	virtual TInt Install();						//overriding pure virtual
 | 
|  |     46 | 	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
 | 
|  |     47 | 	virtual TInt Create(DLogicalChannelBase*& aChannel);	//overriding pure virtual
 | 
|  |     48 | 	};
 | 
|  |     49 | 
 | 
|  |     50 | class DImpSysTest : public DLogicalChannelBase
 | 
|  |     51 | //
 | 
|  |     52 | // Implicit system lock test LDD channel
 | 
|  |     53 | //
 | 
|  |     54 | 	{
 | 
|  |     55 | public:
 | 
|  |     56 | 	DImpSysTest();
 | 
|  |     57 | protected:
 | 
|  |     58 | 	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
 | 
|  |     59 | 	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
 | 
|  |     60 | public:
 | 
|  |     61 | 	TInt CreateThread(TInt);
 | 
|  |     62 | 	TInt Start(TInt aTest);
 | 
|  |     63 | 	TInt Stop(SStats& aStats);
 | 
|  |     64 | 	static void Thread1(TAny*);
 | 
|  |     65 | 	static void Thread2(TAny*);
 | 
|  |     66 | 	static void Thread3(TAny*);
 | 
|  |     67 | public:
 | 
|  |     68 | 	TInt iFailCount;
 | 
|  |     69 | 	TInt iCount1;
 | 
|  |     70 | 	TInt iCount2;
 | 
|  |     71 | 	TInt iCount3;
 | 
|  |     72 | 	TInt iTestNum;
 | 
|  |     73 | 	NFastMutex iMutex;
 | 
|  |     74 | 	NThread iThread1;	// holds fast mutex, imp sys
 | 
|  |     75 | 	NThread iThread2;	// holds system lock, not imp sys
 | 
|  |     76 | 	NThread iThread3;	// random stuff
 | 
|  |     77 | 	TUint32 iStack1[KStackSize/sizeof(TUint32)];
 | 
|  |     78 | 	TUint32 iStack2[KStackSize/sizeof(TUint32)];
 | 
|  |     79 | 	TUint32 iStack3[KStackSize/sizeof(TUint32)];
 | 
|  |     80 | 	};
 | 
|  |     81 | 
 | 
|  |     82 | TInt DImpSysTest::CreateThread(TInt a)
 | 
|  |     83 | 	{
 | 
|  |     84 | 	SNThreadCreateInfo info;
 | 
|  |     85 | 	info.iStackSize=KStackSize;
 | 
|  |     86 | 	info.iPriority=(a==3)?16:12;
 | 
|  |     87 | 	info.iTimeslice=-1;
 | 
|  |     88 | 	info.iAttributes=(TUint8)((a==1)?KThreadAttImplicitSystemLock:0);
 | 
|  |     89 | 	info.iHandlers=NULL;
 | 
|  |     90 | 	info.iFastExecTable=NULL;
 | 
|  |     91 | 	info.iSlowExecTable=NULL;
 | 
|  |     92 | 	info.iParameterBlock=(const TUint32*)this;
 | 
|  |     93 | 	info.iParameterBlockSize=0;
 | 
|  |     94 | 
 | 
|  |     95 | 	NThread* pT=NULL;
 | 
|  |     96 | 	switch (a)
 | 
|  |     97 | 		{
 | 
|  |     98 | 		case 1:
 | 
|  |     99 | 			pT=&iThread1;
 | 
|  |    100 | 			info.iFunction=&Thread1;
 | 
|  |    101 | 			info.iStackBase=iStack1;
 | 
|  |    102 | 			break;
 | 
|  |    103 | 		case 2:
 | 
|  |    104 | 			pT=&iThread2;
 | 
|  |    105 | 			info.iFunction=&Thread2;
 | 
|  |    106 | 			info.iStackBase=iStack2;
 | 
|  |    107 | 			break;
 | 
|  |    108 | 		case 3:
 | 
|  |    109 | 			pT=&iThread3;
 | 
|  |    110 | 			info.iFunction=&Thread3;
 | 
|  |    111 | 			info.iStackBase=iStack3;
 | 
|  |    112 | 			break;
 | 
|  |    113 | 		default:
 | 
|  |    114 | 			return KErrArgument;
 | 
|  |    115 | 		}
 | 
|  |    116 | 
 | 
|  |    117 | 	return NKern::ThreadCreate(pT,info);
 | 
|  |    118 | 	}
 | 
|  |    119 | 
 | 
|  |    120 | void DImpSysTest::Thread1(TAny* aPtr)
 | 
|  |    121 | 	{
 | 
|  |    122 | 	DImpSysTest& d=*(DImpSysTest*)aPtr;
 | 
|  |    123 | 	TScheduler* pS=TScheduler::Ptr();
 | 
|  |    124 | 	NFastMutex& m=pS->iLock;
 | 
|  |    125 | 	TUint seed[2];
 | 
|  |    126 | 	seed[0]=1;
 | 
|  |    127 | 	seed[1]=0;
 | 
|  |    128 | 	FOREVER
 | 
|  |    129 | 		{
 | 
|  |    130 | 		NKern::FMWait(&d.iMutex);
 | 
|  |    131 | 		Kern::NanoWait(1300000);	// spin for 1.3ms
 | 
|  |    132 | 		TInt c = NKern::CurrentContext();
 | 
|  |    133 | 		__NK_ASSERT_ALWAYS(c == NKern::EThread);
 | 
|  |    134 | 		NKern::FMSignal(&d.iMutex);
 | 
|  |    135 | 		if (m.iHoldingThread)
 | 
|  |    136 | 			++d.iFailCount;
 | 
|  |    137 | 		TInt x=Random(seed)&3;
 | 
|  |    138 | 		if (x)
 | 
|  |    139 | 			NKern::Sleep(x);
 | 
|  |    140 | 		++d.iCount1;
 | 
|  |    141 | 		}
 | 
|  |    142 | 	}
 | 
|  |    143 | 
 | 
|  |    144 | void DImpSysTest::Thread2(TAny* aPtr)
 | 
|  |    145 | 	{
 | 
|  |    146 | 	DImpSysTest& d=*(DImpSysTest*)aPtr;
 | 
|  |    147 | 	TUint seed[2];
 | 
|  |    148 | 	seed[0]=2;
 | 
|  |    149 | 	seed[1]=0;
 | 
|  |    150 | 	FOREVER
 | 
|  |    151 | 		{
 | 
|  |    152 | 		TInt c = NKern::CurrentContext();
 | 
|  |    153 | 		__NK_ASSERT_ALWAYS(c == NKern::EThread);
 | 
|  |    154 | 		NKern::LockSystem();
 | 
|  |    155 | 		Kern::NanoWait(1100000);	// spin for 1.1ms
 | 
|  |    156 | 		NKern::UnlockSystem();
 | 
|  |    157 | 		TInt x=Random(seed)&3;
 | 
|  |    158 | 		if (x)
 | 
|  |    159 | 			NKern::Sleep(x);
 | 
|  |    160 | 		++d.iCount2;
 | 
|  |    161 | 		}
 | 
|  |    162 | 	}
 | 
|  |    163 | 
 | 
|  |    164 | void DImpSysTest::Thread3(TAny* aPtr)
 | 
|  |    165 | 	{
 | 
|  |    166 | 	DImpSysTest& d=*(DImpSysTest*)aPtr;
 | 
|  |    167 | 	TUint seed[2];
 | 
|  |    168 | 	seed[0]=3;
 | 
|  |    169 | 	seed[1]=0;
 | 
|  |    170 | 	if (d.iTestNum==RImpSysTest::ETestPriority)
 | 
|  |    171 | 		{
 | 
|  |    172 | 		FOREVER
 | 
|  |    173 | 			{
 | 
|  |    174 | 			TInt c = NKern::CurrentContext();
 | 
|  |    175 | 			__NK_ASSERT_ALWAYS(c == NKern::EThread);
 | 
|  |    176 | 			TInt x=Random(seed)&15;
 | 
|  |    177 | 			NKern::Sleep(x+1);
 | 
|  |    178 | 			x=Random(seed)&1;
 | 
|  |    179 | 			TInt p=10+Random(seed)&3;
 | 
|  |    180 | 			if (x)
 | 
|  |    181 | 				NKern::ThreadSetPriority(&d.iThread1,p);
 | 
|  |    182 | 			else
 | 
|  |    183 | 				NKern::ThreadSetPriority(&d.iThread2,p);
 | 
|  |    184 | 			++d.iCount3;
 | 
|  |    185 | 			}
 | 
|  |    186 | 		}
 | 
|  |    187 | 	else if (d.iTestNum==RImpSysTest::ETestRoundRobin)
 | 
|  |    188 | 		{
 | 
|  |    189 | 		FOREVER
 | 
|  |    190 | 			{
 | 
|  |    191 | 			TInt c = NKern::CurrentContext();
 | 
|  |    192 | 			__NK_ASSERT_ALWAYS(c == NKern::EThread);
 | 
|  |    193 | 			TInt x=Random(seed)&15;
 | 
|  |    194 | 			NKern::Sleep(x+1);
 | 
|  |    195 | 			NKern::RotateReadyList(12);
 | 
|  |    196 | 			++d.iCount3;
 | 
|  |    197 | 			}
 | 
|  |    198 | 		}
 | 
|  |    199 | 	else if (d.iTestNum==RImpSysTest::ETestDummy)
 | 
|  |    200 | 		{
 | 
|  |    201 | 		FOREVER
 | 
|  |    202 | 			{
 | 
|  |    203 | 			TInt c = NKern::CurrentContext();
 | 
|  |    204 | 			__NK_ASSERT_ALWAYS(c == NKern::EThread);
 | 
|  |    205 | 			TInt x=Random(seed)&15;
 | 
|  |    206 | 			NKern::Sleep(x+1);
 | 
|  |    207 | 			x=Random(seed)&255;
 | 
|  |    208 | 			TInt p=10+Random(seed)&3;
 | 
|  |    209 | 			if (x<85)
 | 
|  |    210 | 				{
 | 
|  |    211 | 				NKern::LockSystem();
 | 
|  |    212 | 				NKern::ThreadSetPriority(&d.iThread1,p);
 | 
|  |    213 | 				NKern::UnlockSystem();
 | 
|  |    214 | 				}
 | 
|  |    215 | 			else if (x<170)
 | 
|  |    216 | 				{
 | 
|  |    217 | 				NKern::LockSystem();
 | 
|  |    218 | 				NKern::ThreadSetPriority(&d.iThread2,p);
 | 
|  |    219 | 				NKern::UnlockSystem();
 | 
|  |    220 | 				}
 | 
|  |    221 | 			else
 | 
|  |    222 | 				{
 | 
|  |    223 | 				NKern::FMWait(&d.iMutex);
 | 
|  |    224 | 				NKern::FMSignal(&d.iMutex);
 | 
|  |    225 | 				}
 | 
|  |    226 | 			++d.iCount3;
 | 
|  |    227 | 			}
 | 
|  |    228 | 		}
 | 
|  |    229 | 	}
 | 
|  |    230 | 
 | 
|  |    231 | TInt DImpSysTest::Start(TInt aTest)
 | 
|  |    232 | 	{
 | 
|  |    233 | 	if (iTestNum>=0)
 | 
|  |    234 | 		return KErrInUse;
 | 
|  |    235 | 	iTestNum=aTest;
 | 
|  |    236 | 	iFailCount=0;
 | 
|  |    237 | 	iCount1=0;
 | 
|  |    238 | 	iCount2=0;
 | 
|  |    239 | 	iCount3=0;
 | 
|  |    240 | 	new (&iMutex) NFastMutex;
 | 
|  |    241 | 	TInt r=CreateThread(1);
 | 
|  |    242 | 	if (r==KErrNone)
 | 
|  |    243 | 		r=CreateThread(2);
 | 
|  |    244 | 	if (r==KErrNone)
 | 
|  |    245 | 		r=CreateThread(3);
 | 
|  |    246 | 	if (r==KErrNone)
 | 
|  |    247 | 		{
 | 
|  |    248 | 		NKern::ThreadResume(&iThread3);
 | 
|  |    249 | 		NKern::ThreadResume(&iThread1);
 | 
|  |    250 | 		NKern::ThreadResume(&iThread2);
 | 
|  |    251 | 		}
 | 
|  |    252 | 	if (r!=KErrNone)
 | 
|  |    253 | 		iTestNum=-1;
 | 
|  |    254 | 	return r;
 | 
|  |    255 | 	}
 | 
|  |    256 | 
 | 
|  |    257 | 
 | 
|  |    258 | TInt DImpSysTest::Stop(SStats& a)
 | 
|  |    259 | 	{
 | 
|  |    260 | 	NKern::ThreadKill(&iThread1);
 | 
|  |    261 | 	NKern::ThreadKill(&iThread2);
 | 
|  |    262 | 	NKern::ThreadKill(&iThread3);
 | 
|  |    263 | 	NKern::ThreadSetPriority(&iThread1,16);
 | 
|  |    264 | 	NKern::ThreadSetPriority(&iThread2,16);
 | 
|  |    265 | 	NKern::ThreadSetPriority(&iThread3,16);
 | 
|  |    266 | 	while (iThread1.iNState!=NThread::EDead || iThread2.iNState!=NThread::EDead || iThread3.iNState!=NThread::EDead)
 | 
|  |    267 | 		NKern::Sleep(10);
 | 
|  |    268 | 	TInt size=3*(sizeof(NThread)+KStackSize)+sizeof(NFastMutex);
 | 
|  |    269 | 	memset(&iMutex,0xbb,size);
 | 
|  |    270 | 	a.iFailCount=iFailCount;
 | 
|  |    271 | 	a.iCount1=iCount1;
 | 
|  |    272 | 	a.iCount2=iCount2;
 | 
|  |    273 | 	a.iCount3=iCount3;
 | 
|  |    274 | 	iTestNum=-1;
 | 
|  |    275 | 	return KErrNone;
 | 
|  |    276 | 	}
 | 
|  |    277 | 
 | 
|  |    278 | DImpSysTestFactory::DImpSysTestFactory()
 | 
|  |    279 | //
 | 
|  |    280 | // Constructor
 | 
|  |    281 | //
 | 
|  |    282 |     {
 | 
|  |    283 |     iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
 | 
|  |    284 |     //iParseMask=0;//No units, no info, no PDD
 | 
|  |    285 |     //iUnitsMask=0;//Only one thing
 | 
|  |    286 |     }
 | 
|  |    287 | 
 | 
|  |    288 | TInt DImpSysTestFactory::Create(DLogicalChannelBase*& aChannel)
 | 
|  |    289 | //
 | 
|  |    290 | // Create a new DImpSysTest on this logical device
 | 
|  |    291 | //
 | 
|  |    292 |     {
 | 
|  |    293 | 	aChannel=new DImpSysTest;
 | 
|  |    294 |     return aChannel?KErrNone:KErrNoMemory;
 | 
|  |    295 |     }
 | 
|  |    296 | 
 | 
|  |    297 | TInt DImpSysTestFactory::Install()
 | 
|  |    298 | //
 | 
|  |    299 | // Install the LDD - overriding pure virtual
 | 
|  |    300 | //
 | 
|  |    301 |     {
 | 
|  |    302 |     return SetName(&KLddName);
 | 
|  |    303 |     }
 | 
|  |    304 | 
 | 
|  |    305 | void DImpSysTestFactory::GetCaps(TDes8& aDes) const
 | 
|  |    306 | //
 | 
|  |    307 | // Get capabilities - overriding pure virtual
 | 
|  |    308 | //
 | 
|  |    309 |     {
 | 
|  |    310 |     TCapsImpSysTestV01 b;
 | 
|  |    311 |     b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
 | 
|  |    312 |     Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
 | 
|  |    313 |     }
 | 
|  |    314 | 
 | 
|  |    315 | DImpSysTest::DImpSysTest()
 | 
|  |    316 | //
 | 
|  |    317 | // Constructor
 | 
|  |    318 | //
 | 
|  |    319 | 	: iTestNum(-1)
 | 
|  |    320 |     {
 | 
|  |    321 |     }
 | 
|  |    322 | 
 | 
|  |    323 | TInt DImpSysTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
 | 
|  |    324 | //
 | 
|  |    325 | // Create channel
 | 
|  |    326 | //
 | 
|  |    327 |     {
 | 
|  |    328 | 
 | 
|  |    329 |     if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
 | 
|  |    330 |     	return KErrNotSupported;
 | 
|  |    331 | 	return KErrNone;
 | 
|  |    332 | 	}
 | 
|  |    333 | 
 | 
|  |    334 | TInt DImpSysTest::Request(TInt aReqNo, TAny* a1, TAny*)
 | 
|  |    335 | 	{
 | 
|  |    336 | 	SStats s;
 | 
|  |    337 | 	TInt r=KErrNotSupported;
 | 
|  |    338 | 	switch (aReqNo)
 | 
|  |    339 | 		{
 | 
|  |    340 | 		case RImpSysTest::EControlStart:
 | 
|  |    341 | 			r=Start((TInt)a1);
 | 
|  |    342 | 			break;
 | 
|  |    343 | 		case RImpSysTest::EControlStop:
 | 
|  |    344 | 			{
 | 
|  |    345 | 			r=Stop(s);
 | 
|  |    346 | 			kumemput32(a1,&s,sizeof(s));
 | 
|  |    347 | 			}
 | 
|  |    348 | 			break;
 | 
|  |    349 | 		default:
 | 
|  |    350 | 			break;
 | 
|  |    351 | 		}
 | 
|  |    352 | 	return r;
 | 
|  |    353 | 	}
 | 
|  |    354 | 
 | 
|  |    355 | #endif
 | 
|  |    356 | 
 | 
|  |    357 | 
 | 
|  |    358 | DECLARE_STANDARD_LDD()
 | 
|  |    359 | 	{
 | 
|  |    360 | #ifdef __SMP__
 | 
|  |    361 | 	return 0;	// not used on SMP
 | 
|  |    362 | #else
 | 
|  |    363 |     return new DImpSysTestFactory;
 | 
|  |    364 | #endif
 | 
|  |    365 |     }
 | 
|  |    366 | 
 |