kerneltest/e32test/nkern/d_implicit.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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