kerneltest/e32test/smpsoak/t_smpsoakspin.cpp
changeset 10 36bfc973b146
child 8 538db54a451d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/smpsoak/t_smpsoakspin.cpp	Thu Jan 07 13:38:45 2010 +0200
@@ -0,0 +1,287 @@
+// Copyright (c) 2002-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\t_smpsoakspin.cpp
+//
+
+#define __E32TEST_EXTENSION__
+#include <e32test.h>
+#include <u32hal.h>
+#include <f32file.h>
+
+
+#include "d_smpsoak.h"
+
+#define PRINT(string) if (!gQuiet) test.Printf(string)
+#define PRINT1(string,param) if (!gQuiet) test.Printf(string,param)
+#define TESTNEXT(string) if (!gQuiet) test.Next(string)
+
+#define DEBUG_PRINT(__args)		test.Printf __args
+
+//------------globals---------------------
+LOCAL_D RTest test(_L("T_SMPSOAKSPIN"));
+LOCAL_D TBool gQuiet = EFalse;
+LOCAL_D TBool gAbort = EFalse;
+
+TInt		TestCpuCount = 0;
+
+const TInt KTimerPeriod = 10000;
+
+const TInt KHeapMinSize=0x1000;
+const TInt KHeapMaxSize=0x1000;
+
+// Create a new thread
+RThread *spinthread = new RThread;
+
+//Periadic Bip
+CPeriodic*	Timer;
+
+TInt SMPSpinThread(TAny*);
+
+
+struct TThread
+	{
+	RThread thread;
+	TDesC threadName;
+	TInt threadPriority;
+	TInt cpuAffinity;
+	TInt loopCount;
+	TInt endLoopDelay;
+	TBool fixedCPU;
+	TBool endFlag;
+	};
+
+TThread ThreadTable[] =
+	{
+		{ RThread(), _L("Thread1"),  EPriorityAbsoluteHigh,     0, 1000, 100, EFalse,    EFalse}, 	
+		{ RThread(), _L("Thread2"),  EPriorityAbsoluteHigh,     0, 1000, 100, EFalse,    EFalse}, 	 
+	};
+
+enum 
+	{
+	KThreads = (TInt)(sizeof(ThreadTable) / sizeof(TThread))
+};
+
+void ShowHelp()
+	{
+	PRINT(_L("***************************************\n"));
+	PRINT(_L("The following are available commands\n"));
+	PRINT(_L("Esc     to exit\n"));
+	PRINT(_L("***************************************\n"));
+	}
+
+TInt NumberOfCpus()
+	{
+	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
+	test(r>0);
+	return r;
+	}
+
+
+void ParseCommandLine ()
+	{
+	TBuf<64> c;
+	
+	User::CommandLine(c);
+	c.LowerCase();
+
+	if (c != KNullDesC)
+		{
+		TLex lex(c);
+		TPtrC token;
+
+		while (token.Set(lex.NextToken()), token != KNullDesC)
+			{
+			if (token.Mid(0) == _L("quiet"))
+				{
+				gQuiet = ETrue;
+				continue;
+				}
+
+			if (token.Mid(0) == _L("verbose"))
+				{
+				gQuiet = EFalse;
+				continue;
+				}
+			}
+		}
+	}
+
+// CActive class to monitor KeyStrokes from User
+class CActiveConsole : public CActive
+	{
+public:
+	CActiveConsole();
+	~CActiveConsole();
+	void GetCharacter();
+	static TInt Callback(TAny* aCtrl);
+	static CPeriodic* TimerL();
+private:
+
+	
+	// Defined as pure virtual by CActive;
+	// implementation provided by this class.
+	virtual void DoCancel();
+	// Defined as pure virtual by CActive;
+	// implementation provided by this class,
+	virtual void RunL();
+	void ProcessKeyPressL(TChar aChar);
+	};
+
+// Class CActiveConsole
+CActiveConsole::CActiveConsole()
+	: CActive(EPriorityHigh)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CActiveConsole::~CActiveConsole()
+	{
+    Cancel();
+	}
+
+CPeriodic* CActiveConsole::TimerL()
+    {
+    return(CPeriodic::NewL(EPriorityNormal));
+    }
+
+// Callback function for timer expiry
+TInt CActiveConsole::Callback(TAny* aControl)
+	{
+	return KErrNone;
+	}
+
+void CActiveConsole::GetCharacter()
+	{
+	test.Console()->Read(iStatus);
+	SetActive();
+	}
+
+void CActiveConsole::DoCancel()
+	{
+	PRINT(_L("CActiveConsole::DoCancel\n"));
+	test.Console()->ReadCancel();
+	}
+
+void CActiveConsole::ProcessKeyPressL(TChar aChar)
+	{
+	if (aChar == EKeyEscape)
+		{
+		PRINT(_L("CActiveConsole: ESC key pressed -> stopping active scheduler...\n"));
+		CActiveScheduler::Stop();
+		return;
+		}
+	aChar.UpperCase();
+	GetCharacter();
+	}
+
+void CActiveConsole::RunL()
+	{
+	ProcessKeyPressL(static_cast<TChar>(test.Console()->KeyCode()));
+	}
+
+TInt E32Main()
+	{
+	test.Title();
+	__UHEAP_MARK;
+	test.Start(_L("SMP Soak Test"));
+
+	test.Next(_L("Load device driver"));
+	TInt r = User::LoadLogicalDevice(_L("d_smpsoak.ldd"));
+	if (r == KErrNotFound)
+		{
+		test.Printf(_L("Test not supported on this platform because the D_SMPSOAK.LDD Driver is Not Present\n"));
+		test.End();
+		return 0;
+		}
+
+	test.Next(_L("Calling rt.Open"));
+	RSMPSoak rt;
+	r = rt.Open();
+	if (r!=KErrNone)
+		{
+		test.Printf(_L("Error- Couldn't able to open soak driver:%d"),r);
+		return r;
+		}
+	test.Next(_L("rt.Open called"));
+
+    spinthread->Create(_L("SMPSpinThread"), SMPSpinThread, KDefaultStackSize, KHeapMinSize, KHeapMaxSize, &rt);
+	DEBUG_PRINT((_L("SMPSoak Thread is %x\n"), spinthread));
+
+	spinthread->SetPriority(EPriorityAbsoluteLow);
+
+	spinthread->Resume();
+	
+	ParseCommandLine();
+	
+	CActiveScheduler* myScheduler = new (ELeave) CActiveScheduler();
+	test(myScheduler !=NULL);
+	CActiveScheduler::Install(myScheduler);
+
+	CPeriodic* theTimer=NULL;
+	TRAPD(ret,theTimer=CActiveConsole::TimerL())
+	test_KErrNone(ret);
+	theTimer->Start(0,KTimerPeriod,TCallBack(CActiveConsole::Callback));
+
+	CActiveConsole* myActiveConsole = new CActiveConsole();
+	test(myActiveConsole !=NULL);
+	myActiveConsole->GetCharacter();
+
+	CActiveScheduler::Start();
+
+	delete theTimer;
+
+	 __UHEAP_MARKEND;
+
+	test.End();
+
+	return 0;
+	}
+
+TInt SMPSpinThread(TAny* rt)
+{
+	TInt startCpu = 0x00;
+	TInt endCpu = 0x00;
+	RTimer timer;
+	test(timer.CreateLocal()==KErrNone);
+	TRequestStatus s;
+
+	RSMPSoak* pMyDriver = (RSMPSoak*)rt;
+	RTest test(_L("SMPSpinThread"));
+	test.Title();
+
+	FOREVER
+	{
+		startCpu = pMyDriver->TryControl(RSMPSoak::KGETCURRENTCPU, 0);
+		
+		timer.After(s, 250000);			
+		User::WaitForRequest(s);
+		test(s==KErrNone);
+		DEBUG_PRINT((_L("+")));
+
+		endCpu = pMyDriver->TryControl(RSMPSoak::KGETCURRENTCPU, 0);
+		
+		if(startCpu != endCpu)
+		{
+			DEBUG_PRINT((_L("\r\nSMPSoakSpin app:- Thread moved from cpu %d to cpu %d ************\n"), startCpu, endCpu));
+		}
+		if (gAbort)
+			break;
+	}
+	
+	timer.Cancel();
+	DEBUG_PRINT((_L("MyTimer.Cancel() called\n")));
+	return 0x00;	
+}
+
+