kerneltest/e32test/nkern/d_implicit.cpp
changeset 0 a41df078684a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/nkern/d_implicit.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,366 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test\nkern\d_implicit.cpp
+// LDD for testing nanokernel implicit system lock
+// 
+//
+
+#define __INCLUDE_NTHREADBASE_DEFINES__
+
+#include "platform.h"
+#include "nk_priv.h"
+#include "d_implicit.h"
+
+#ifndef __SMP__
+#include "../misc/prbs.h"
+
+const TInt KMajorVersionNumber=0;
+const TInt KMinorVersionNumber=1;
+const TInt KBuildVersionNumber=1;
+
+const TInt KStackSize=1024;
+
+inline NThreadBase::NThreadBase()
+	{
+	}
+
+class DImpSysTestFactory : public DLogicalDevice
+//
+// Implicit system lock test LDD factory
+//
+	{
+public:
+	DImpSysTestFactory();
+	virtual TInt Install();						//overriding pure virtual
+	virtual void GetCaps(TDes8& aDes) const;	//overriding pure virtual
+	virtual TInt Create(DLogicalChannelBase*& aChannel);	//overriding pure virtual
+	};
+
+class DImpSysTest : public DLogicalChannelBase
+//
+// Implicit system lock test LDD channel
+//
+	{
+public:
+	DImpSysTest();
+protected:
+	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+public:
+	TInt CreateThread(TInt);
+	TInt Start(TInt aTest);
+	TInt Stop(SStats& aStats);
+	static void Thread1(TAny*);
+	static void Thread2(TAny*);
+	static void Thread3(TAny*);
+public:
+	TInt iFailCount;
+	TInt iCount1;
+	TInt iCount2;
+	TInt iCount3;
+	TInt iTestNum;
+	NFastMutex iMutex;
+	NThread iThread1;	// holds fast mutex, imp sys
+	NThread iThread2;	// holds system lock, not imp sys
+	NThread iThread3;	// random stuff
+	TUint32 iStack1[KStackSize/sizeof(TUint32)];
+	TUint32 iStack2[KStackSize/sizeof(TUint32)];
+	TUint32 iStack3[KStackSize/sizeof(TUint32)];
+	};
+
+TInt DImpSysTest::CreateThread(TInt a)
+	{
+	SNThreadCreateInfo info;
+	info.iStackSize=KStackSize;
+	info.iPriority=(a==3)?16:12;
+	info.iTimeslice=-1;
+	info.iAttributes=(TUint8)((a==1)?KThreadAttImplicitSystemLock:0);
+	info.iHandlers=NULL;
+	info.iFastExecTable=NULL;
+	info.iSlowExecTable=NULL;
+	info.iParameterBlock=(const TUint32*)this;
+	info.iParameterBlockSize=0;
+
+	NThread* pT=NULL;
+	switch (a)
+		{
+		case 1:
+			pT=&iThread1;
+			info.iFunction=&Thread1;
+			info.iStackBase=iStack1;
+			break;
+		case 2:
+			pT=&iThread2;
+			info.iFunction=&Thread2;
+			info.iStackBase=iStack2;
+			break;
+		case 3:
+			pT=&iThread3;
+			info.iFunction=&Thread3;
+			info.iStackBase=iStack3;
+			break;
+		default:
+			return KErrArgument;
+		}
+
+	return NKern::ThreadCreate(pT,info);
+	}
+
+void DImpSysTest::Thread1(TAny* aPtr)
+	{
+	DImpSysTest& d=*(DImpSysTest*)aPtr;
+	TScheduler* pS=TScheduler::Ptr();
+	NFastMutex& m=pS->iLock;
+	TUint seed[2];
+	seed[0]=1;
+	seed[1]=0;
+	FOREVER
+		{
+		NKern::FMWait(&d.iMutex);
+		Kern::NanoWait(1300000);	// spin for 1.3ms
+		TInt c = NKern::CurrentContext();
+		__NK_ASSERT_ALWAYS(c == NKern::EThread);
+		NKern::FMSignal(&d.iMutex);
+		if (m.iHoldingThread)
+			++d.iFailCount;
+		TInt x=Random(seed)&3;
+		if (x)
+			NKern::Sleep(x);
+		++d.iCount1;
+		}
+	}
+
+void DImpSysTest::Thread2(TAny* aPtr)
+	{
+	DImpSysTest& d=*(DImpSysTest*)aPtr;
+	TUint seed[2];
+	seed[0]=2;
+	seed[1]=0;
+	FOREVER
+		{
+		TInt c = NKern::CurrentContext();
+		__NK_ASSERT_ALWAYS(c == NKern::EThread);
+		NKern::LockSystem();
+		Kern::NanoWait(1100000);	// spin for 1.1ms
+		NKern::UnlockSystem();
+		TInt x=Random(seed)&3;
+		if (x)
+			NKern::Sleep(x);
+		++d.iCount2;
+		}
+	}
+
+void DImpSysTest::Thread3(TAny* aPtr)
+	{
+	DImpSysTest& d=*(DImpSysTest*)aPtr;
+	TUint seed[2];
+	seed[0]=3;
+	seed[1]=0;
+	if (d.iTestNum==RImpSysTest::ETestPriority)
+		{
+		FOREVER
+			{
+			TInt c = NKern::CurrentContext();
+			__NK_ASSERT_ALWAYS(c == NKern::EThread);
+			TInt x=Random(seed)&15;
+			NKern::Sleep(x+1);
+			x=Random(seed)&1;
+			TInt p=10+Random(seed)&3;
+			if (x)
+				NKern::ThreadSetPriority(&d.iThread1,p);
+			else
+				NKern::ThreadSetPriority(&d.iThread2,p);
+			++d.iCount3;
+			}
+		}
+	else if (d.iTestNum==RImpSysTest::ETestRoundRobin)
+		{
+		FOREVER
+			{
+			TInt c = NKern::CurrentContext();
+			__NK_ASSERT_ALWAYS(c == NKern::EThread);
+			TInt x=Random(seed)&15;
+			NKern::Sleep(x+1);
+			NKern::RotateReadyList(12);
+			++d.iCount3;
+			}
+		}
+	else if (d.iTestNum==RImpSysTest::ETestDummy)
+		{
+		FOREVER
+			{
+			TInt c = NKern::CurrentContext();
+			__NK_ASSERT_ALWAYS(c == NKern::EThread);
+			TInt x=Random(seed)&15;
+			NKern::Sleep(x+1);
+			x=Random(seed)&255;
+			TInt p=10+Random(seed)&3;
+			if (x<85)
+				{
+				NKern::LockSystem();
+				NKern::ThreadSetPriority(&d.iThread1,p);
+				NKern::UnlockSystem();
+				}
+			else if (x<170)
+				{
+				NKern::LockSystem();
+				NKern::ThreadSetPriority(&d.iThread2,p);
+				NKern::UnlockSystem();
+				}
+			else
+				{
+				NKern::FMWait(&d.iMutex);
+				NKern::FMSignal(&d.iMutex);
+				}
+			++d.iCount3;
+			}
+		}
+	}
+
+TInt DImpSysTest::Start(TInt aTest)
+	{
+	if (iTestNum>=0)
+		return KErrInUse;
+	iTestNum=aTest;
+	iFailCount=0;
+	iCount1=0;
+	iCount2=0;
+	iCount3=0;
+	new (&iMutex) NFastMutex;
+	TInt r=CreateThread(1);
+	if (r==KErrNone)
+		r=CreateThread(2);
+	if (r==KErrNone)
+		r=CreateThread(3);
+	if (r==KErrNone)
+		{
+		NKern::ThreadResume(&iThread3);
+		NKern::ThreadResume(&iThread1);
+		NKern::ThreadResume(&iThread2);
+		}
+	if (r!=KErrNone)
+		iTestNum=-1;
+	return r;
+	}
+
+
+TInt DImpSysTest::Stop(SStats& a)
+	{
+	NKern::ThreadKill(&iThread1);
+	NKern::ThreadKill(&iThread2);
+	NKern::ThreadKill(&iThread3);
+	NKern::ThreadSetPriority(&iThread1,16);
+	NKern::ThreadSetPriority(&iThread2,16);
+	NKern::ThreadSetPriority(&iThread3,16);
+	while (iThread1.iNState!=NThread::EDead || iThread2.iNState!=NThread::EDead || iThread3.iNState!=NThread::EDead)
+		NKern::Sleep(10);
+	TInt size=3*(sizeof(NThread)+KStackSize)+sizeof(NFastMutex);
+	memset(&iMutex,0xbb,size);
+	a.iFailCount=iFailCount;
+	a.iCount1=iCount1;
+	a.iCount2=iCount2;
+	a.iCount3=iCount3;
+	iTestNum=-1;
+	return KErrNone;
+	}
+
+DImpSysTestFactory::DImpSysTestFactory()
+//
+// Constructor
+//
+    {
+    iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+    //iParseMask=0;//No units, no info, no PDD
+    //iUnitsMask=0;//Only one thing
+    }
+
+TInt DImpSysTestFactory::Create(DLogicalChannelBase*& aChannel)
+//
+// Create a new DImpSysTest on this logical device
+//
+    {
+	aChannel=new DImpSysTest;
+    return aChannel?KErrNone:KErrNoMemory;
+    }
+
+TInt DImpSysTestFactory::Install()
+//
+// Install the LDD - overriding pure virtual
+//
+    {
+    return SetName(&KLddName);
+    }
+
+void DImpSysTestFactory::GetCaps(TDes8& aDes) const
+//
+// Get capabilities - overriding pure virtual
+//
+    {
+    TCapsImpSysTestV01 b;
+    b.iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
+    Kern::InfoCopy(aDes,(TUint8*)&b,sizeof(b));
+    }
+
+DImpSysTest::DImpSysTest()
+//
+// Constructor
+//
+	: iTestNum(-1)
+    {
+    }
+
+TInt DImpSysTest::DoCreate(TInt /*aUnit*/, const TDesC8* /*anInfo*/, const TVersion& aVer)
+//
+// Create channel
+//
+    {
+
+    if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer))
+    	return KErrNotSupported;
+	return KErrNone;
+	}
+
+TInt DImpSysTest::Request(TInt aReqNo, TAny* a1, TAny*)
+	{
+	SStats s;
+	TInt r=KErrNotSupported;
+	switch (aReqNo)
+		{
+		case RImpSysTest::EControlStart:
+			r=Start((TInt)a1);
+			break;
+		case RImpSysTest::EControlStop:
+			{
+			r=Stop(s);
+			kumemput32(a1,&s,sizeof(s));
+			}
+			break;
+		default:
+			break;
+		}
+	return r;
+	}
+
+#endif
+
+
+DECLARE_STANDARD_LDD()
+	{
+#ifdef __SMP__
+	return 0;	// not used on SMP
+#else
+    return new DImpSysTestFactory;
+#endif
+    }
+