1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/nkern/d_implicit.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,366 @@
1.4 +// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +// e32test\nkern\d_implicit.cpp
1.18 +// LDD for testing nanokernel implicit system lock
1.19 +//
1.20 +//
1.21 +
1.22 +#define __INCLUDE_NTHREADBASE_DEFINES__
1.23 +
1.24 +#include "platform.h"
1.25 +#include "nk_priv.h"
1.26 +#include "d_implicit.h"
1.27 +
1.28 +#ifndef __SMP__
1.29 +#include "../misc/prbs.h"
1.30 +
1.31 +const TInt KMajorVersionNumber=0;
1.32 +const TInt KMinorVersionNumber=1;
1.33 +const TInt KBuildVersionNumber=1;
1.34 +
1.35 +const TInt KStackSize=1024;
1.36 +
1.37 +inline NThreadBase::NThreadBase()
1.38 + {
1.39 + }
1.40 +
1.41 +class DImpSysTestFactory : public DLogicalDevice
1.42 +//
1.43 +// Implicit system lock test LDD factory
1.44 +//
1.45 + {
1.46 +public:
1.47 + DImpSysTestFactory();
1.48 + virtual TInt Install(); //overriding pure virtual
1.49 + virtual void GetCaps(TDes8& aDes) const; //overriding pure virtual
1.50 + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual
1.51 + };
1.52 +
1.53 +class DImpSysTest : public DLogicalChannelBase
1.54 +//
1.55 +// Implicit system lock test LDD channel
1.56 +//
1.57 + {
1.58 +public:
1.59 + DImpSysTest();
1.60 +protected:
1.61 + virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
1.62 + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.63 +public:
1.64 + TInt CreateThread(TInt);
1.65 + TInt Start(TInt aTest);
1.66 + TInt Stop(SStats& aStats);
1.67 + static void Thread1(TAny*);
1.68 + static void Thread2(TAny*);
1.69 + static void Thread3(TAny*);
1.70 +public:
1.71 + TInt iFailCount;
1.72 + TInt iCount1;
1.73 + TInt iCount2;
1.74 + TInt iCount3;
1.75 + TInt iTestNum;
1.76 + NFastMutex iMutex;
1.77 + NThread iThread1; // holds fast mutex, imp sys
1.78 + NThread iThread2; // holds system lock, not imp sys
1.79 + NThread iThread3; // random stuff
1.80 + TUint32 iStack1[KStackSize/sizeof(TUint32)];
1.81 + TUint32 iStack2[KStackSize/sizeof(TUint32)];
1.82 + TUint32 iStack3[KStackSize/sizeof(TUint32)];
1.83 + };
1.84 +
1.85 +TInt DImpSysTest::CreateThread(TInt a)
1.86 + {
1.87 + SNThreadCreateInfo info;
1.88 + info.iStackSize=KStackSize;
1.89 + info.iPriority=(a==3)?16:12;
1.90 + info.iTimeslice=-1;
1.91 + info.iAttributes=(TUint8)((a==1)?KThreadAttImplicitSystemLock:0);
1.92 + info.iHandlers=NULL;
1.93 + info.iFastExecTable=NULL;
1.94 + info.iSlowExecTable=NULL;
1.95 + info.iParameterBlock=(const TUint32*)this;
1.96 + info.iParameterBlockSize=0;
1.97 +
1.98 + NThread* pT=NULL;
1.99 + switch (a)
1.100 + {
1.101 + case 1:
1.102 + pT=&iThread1;
1.103 + info.iFunction=&Thread1;
1.104 + info.iStackBase=iStack1;
1.105 + break;
1.106 + case 2:
1.107 + pT=&iThread2;
1.108 + info.iFunction=&Thread2;
1.109 + info.iStackBase=iStack2;
1.110 + break;
1.111 + case 3:
1.112 + pT=&iThread3;
1.113 + info.iFunction=&Thread3;
1.114 + info.iStackBase=iStack3;
1.115 + break;
1.116 + default:
1.117 + return KErrArgument;
1.118 + }
1.119 +
1.120 + return NKern::ThreadCreate(pT,info);
1.121 + }
1.122 +
1.123 +void DImpSysTest::Thread1(TAny* aPtr)
1.124 + {
1.125 + DImpSysTest& d=*(DImpSysTest*)aPtr;
1.126 + TScheduler* pS=TScheduler::Ptr();
1.127 + NFastMutex& m=pS->iLock;
1.128 + TUint seed[2];
1.129 + seed[0]=1;
1.130 + seed[1]=0;
1.131 + FOREVER
1.132 + {
1.133 + NKern::FMWait(&d.iMutex);
1.134 + Kern::NanoWait(1300000); // spin for 1.3ms
1.135 + TInt c = NKern::CurrentContext();
1.136 + __NK_ASSERT_ALWAYS(c == NKern::EThread);
1.137 + NKern::FMSignal(&d.iMutex);
1.138 + if (m.iHoldingThread)
1.139 + ++d.iFailCount;
1.140 + TInt x=Random(seed)&3;
1.141 + if (x)
1.142 + NKern::Sleep(x);
1.143 + ++d.iCount1;
1.144 + }
1.145 + }
1.146 +
1.147 +void DImpSysTest::Thread2(TAny* aPtr)
1.148 + {
1.149 + DImpSysTest& d=*(DImpSysTest*)aPtr;
1.150 + TUint seed[2];
1.151 + seed[0]=2;
1.152 + seed[1]=0;
1.153 + FOREVER
1.154 + {
1.155 + TInt c = NKern::CurrentContext();
1.156 + __NK_ASSERT_ALWAYS(c == NKern::EThread);
1.157 + NKern::LockSystem();
1.158 + Kern::NanoWait(1100000); // spin for 1.1ms
1.159 + NKern::UnlockSystem();
1.160 + TInt x=Random(seed)&3;
1.161 + if (x)
1.162 + NKern::Sleep(x);
1.163 + ++d.iCount2;
1.164 + }
1.165 + }
1.166 +
1.167 +void DImpSysTest::Thread3(TAny* aPtr)
1.168 + {
1.169 + DImpSysTest& d=*(DImpSysTest*)aPtr;
1.170 + TUint seed[2];
1.171 + seed[0]=3;
1.172 + seed[1]=0;
1.173 + if (d.iTestNum==RImpSysTest::ETestPriority)
1.174 + {
1.175 + FOREVER
1.176 + {
1.177 + TInt c = NKern::CurrentContext();
1.178 + __NK_ASSERT_ALWAYS(c == NKern::EThread);
1.179 + TInt x=Random(seed)&15;
1.180 + NKern::Sleep(x+1);
1.181 + x=Random(seed)&1;
1.182 + TInt p=10+Random(seed)&3;
1.183 + if (x)
1.184 + NKern::ThreadSetPriority(&d.iThread1,p);
1.185 + else
1.186 + NKern::ThreadSetPriority(&d.iThread2,p);
1.187 + ++d.iCount3;
1.188 + }
1.189 + }
1.190 + else if (d.iTestNum==RImpSysTest::ETestRoundRobin)
1.191 + {
1.192 + FOREVER
1.193 + {
1.194 + TInt c = NKern::CurrentContext();
1.195 + __NK_ASSERT_ALWAYS(c == NKern::EThread);
1.196 + TInt x=Random(seed)&15;
1.197 + NKern::Sleep(x+1);
1.198 + NKern::RotateReadyList(12);
1.199 + ++d.iCount3;
1.200 + }
1.201 + }
1.202 + else if (d.iTestNum==RImpSysTest::ETestDummy)
1.203 + {
1.204 + FOREVER
1.205 + {
1.206 + TInt c = NKern::CurrentContext();
1.207 + __NK_ASSERT_ALWAYS(c == NKern::EThread);
1.208 + TInt x=Random(seed)&15;
1.209 + NKern::Sleep(x+1);
1.210 + x=Random(seed)&255;
1.211 + TInt p=10+Random(seed)&3;
1.212 + if (x<85)
1.213 + {
1.214 + NKern::LockSystem();
1.215 + NKern::ThreadSetPriority(&d.iThread1,p);
1.216 + NKern::UnlockSystem();
1.217 + }
1.218 + else if (x<170)
1.219 + {
1.220 + NKern::LockSystem();
1.221 + NKern::ThreadSetPriority(&d.iThread2,p);
1.222 + NKern::UnlockSystem();
1.223 + }
1.224 + else
1.225 + {
1.226 + NKern::FMWait(&d.iMutex);
1.227 + NKern::FMSignal(&d.iMutex);
1.228 + }
1.229 + ++d.iCount3;
1.230 + }
1.231 + }
1.232 + }
1.233 +
1.234 +TInt DImpSysTest::Start(TInt aTest)
1.235 + {
1.236 + if (iTestNum>=0)
1.237 + return KErrInUse;
1.238 + iTestNum=aTest;
1.239 + iFailCount=0;
1.240 + iCount1=0;
1.241 + iCount2=0;
1.242 + iCount3=0;
1.243 + new (&iMutex) NFastMutex;
1.244 + TInt r=CreateThread(1);
1.245 + if (r==KErrNone)
1.246 + r=CreateThread(2);
1.247 + if (r==KErrNone)
1.248 + r=CreateThread(3);
1.249 + if (r==KErrNone)
1.250 + {
1.251 + NKern::ThreadResume(&iThread3);
1.252 + NKern::ThreadResume(&iThread1);
1.253 + NKern::ThreadResume(&iThread2);
1.254 + }
1.255 + if (r!=KErrNone)
1.256 + iTestNum=-1;
1.257 + return r;
1.258 + }
1.259 +
1.260 +
1.261 +TInt DImpSysTest::Stop(SStats& a)
1.262 + {
1.263 + NKern::ThreadKill(&iThread1);
1.264 + NKern::ThreadKill(&iThread2);
1.265 + NKern::ThreadKill(&iThread3);
1.266 + NKern::ThreadSetPriority(&iThread1,16);
1.267 + NKern::ThreadSetPriority(&iThread2,16);
1.268 + NKern::ThreadSetPriority(&iThread3,16);
1.269 + while (iThread1.iNState!=NThread::EDead || iThread2.iNState!=NThread::EDead || iThread3.iNState!=NThread::EDead)
1.270 + NKern::Sleep(10);
1.271 + TInt size=3*(sizeof(NThread)+KStackSize)+sizeof(NFastMutex);
1.272 + memset(&iMutex,0xbb,size);
1.273 + a.iFailCount=iFailCount;
1.274 + a.iCount1=iCount1;
1.275 + a.iCount2=iCount2;
1.276 + a.iCount3=iCount3;
1.277 + iTestNum=-1;
1.278 + return KErrNone;
1.279 + }
1.280 +
1.281 +DImpSysTestFactory::DImpSysTestFactory()
1.282 +//
1.283 +// Constructor
1.284 +//
1.285 + {
1.286 + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.287 + //iParseMask=0;//No units, no info, no PDD
1.288 + //iUnitsMask=0;//Only one thing
1.289 + }
1.290 +
1.291 +TInt DImpSysTestFactory::Create(DLogicalChannelBase*& aChannel)
1.292 +//
1.293 +// Create a new DImpSysTest on this logical device
1.294 +//
1.295 + {
1.296 + aChannel=new DImpSysTest;
1.297 + return aChannel?KErrNone:KErrNoMemory;
1.298 + }
1.299 +
1.300 +TInt DImpSysTestFactory::Install()
1.301 +//
1.302 +// Install the LDD - overriding pure virtual
1.303 +//
1.304 + {
1.305 + return SetName(&KLddName);
1.306 + }
1.307 +
1.308 +void DImpSysTestFactory::GetCaps(TDes8& aDes) const
1.309 +//
1.310 +// Get capabilities - overriding pure virtual
1.311 +//
1.312 + {
1.313 + TCapsImpSysTestV01 b;
1.314 + b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.315 + Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
1.316 + }
1.317 +
1.318 +DImpSysTest::DImpSysTest()
1.319 +//
1.320 +// Constructor
1.321 +//
1.322 + : iTestNum(-1)
1.323 + {
1.324 + }
1.325 +
1.326 +TInt DImpSysTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
1.327 +//
1.328 +// Create channel
1.329 +//
1.330 + {
1.331 +
1.332 + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
1.333 + return KErrNotSupported;
1.334 + return KErrNone;
1.335 + }
1.336 +
1.337 +TInt DImpSysTest::Request(TInt aReqNo, TAny* a1, TAny*)
1.338 + {
1.339 + SStats s;
1.340 + TInt r=KErrNotSupported;
1.341 + switch (aReqNo)
1.342 + {
1.343 + case RImpSysTest::EControlStart:
1.344 + r=Start((TInt)a1);
1.345 + break;
1.346 + case RImpSysTest::EControlStop:
1.347 + {
1.348 + r=Stop(s);
1.349 + kumemput32(a1,&s,sizeof(s));
1.350 + }
1.351 + break;
1.352 + default:
1.353 + break;
1.354 + }
1.355 + return r;
1.356 + }
1.357 +
1.358 +#endif
1.359 +
1.360 +
1.361 +DECLARE_STANDARD_LDD()
1.362 + {
1.363 +#ifdef __SMP__
1.364 + return 0; // not used on SMP
1.365 +#else
1.366 + return new DImpSysTestFactory;
1.367 +#endif
1.368 + }
1.369 +