os/kernelhwsrv/kerneltest/e32test/nkern/d_implicit.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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