Update contrib.
1 // Copyright (c) 1995-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // e32test\misc\t_svr6.cpp
18 #define __E32TEST_EXTENSION__
20 #include <e32base_private.h>
24 #include "../misc/prbs.h"
25 #include "../mmu/freeram.h"
27 const TInt KStackSize=0x1000;
28 const TInt KHeapMaxSize=0x100000;
29 const TInt KMajorVersionNumber=1;
30 const TInt KMinorVersionNumber=0;
31 const TInt KBuildVersionNumber=1;
32 const TInt KNumMessageSlots=10;
34 _LIT(KServerName,"StressSvr");
36 LOCAL_D RTest test(_L("T_SVR6"));
38 class CMySession : public CSession2
42 virtual void ServiceL(const RMessage2& aMessage); //pure virtual fns.
43 void Process(const RMessage2& aMessage);
49 class CMyServer : public CServer2
54 CMyServer(TInt aPriority);
55 static CMyServer* New(TInt aPriority);
56 virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2&) const;//Overloading
59 class CMyActiveScheduler : public CActiveScheduler
62 virtual void Error(TInt anError) const; //Overloading pure virtual function
65 class RStressSvr : public RSessionBase
70 void Test(TRequestStatus& aStatus);
74 class CThread : public CActive
77 CThread(TInt aPriority);
80 virtual void DoCancel();
81 virtual void DisplayStats()=0;
82 virtual TBool PanicBadHandleAllowed();
83 virtual void RegisterAllowedPanic();
84 virtual void Cleanup();
85 virtual TInt ProcessStartError(TInt anError);
88 virtual TInt StartThread()=0;
92 TInt iServerTerminatedCount;
96 class CServerThread : public CThread
101 virtual TInt StartThread();
102 virtual void DisplayStats();
104 TInt iMessagesReceived;
107 class CClientThread : public CThread
110 static void NewL(TInt anId, TInt aPrimaryId);
111 CClientThread(TInt anId);
112 virtual TInt StartThread();
113 virtual void DisplayStats();
114 virtual TBool PanicBadHandleAllowed();
115 virtual void RegisterAllowedPanic();
116 virtual void Cleanup();
117 virtual TInt ProcessStartError(TInt anError);
121 CClientThread* iPrimary;
124 TBool iWaitingToRestart;
127 class CRandomTimer : public CActive
131 CRandomTimer(TInt aPriority);
134 virtual void DoCancel();
142 class CStatsTimer : public CActive
146 CStatsTimer(TInt aPriority);
149 virtual void DoCancel();
158 const TInt KNumPrimaryClients=3;
159 const TInt KNumSecondariesPerPrimary=3;
160 const TInt KNumClients=KNumPrimaryClients*KNumSecondariesPerPrimary;
161 LOCAL_D CServerThread* TheServer;
162 LOCAL_D CClientThread* TheClients[KNumClients];
163 LOCAL_D CRandomTimer* TheRandomTimer;
165 CMySession::CMySession()
170 iSeed[0]=User::TickCount();
173 CMyServer* CMyServer::New(TInt aPriority)
175 // Create a new CMyServer.
179 return new CMyServer(aPriority);
182 CMyServer::CMyServer(TInt aPriority)
186 : CServer2(aPriority, ESharableSessions)
189 CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
191 // Create a new client for this server.
195 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
196 if (!User::QueryVersionSupported(v,aVersion))
197 User::Leave(KErrNotSupported);
198 return new(ELeave) CMySession;
201 void CMySession::ServiceL(const RMessage2& aMessage)
203 // Handle messages for this server.
207 ++TheServer->iMessagesReceived;
208 switch (aMessage.Function())
210 case CMyServer::ETest:
211 if (iOutstanding==KNumMessageSlots-1)
217 aMessage.Complete(KErrNotSupported);
222 void CMySession::Process(const RMessage2& aMessage)
224 TUint x=Random(iSeed)&16383;
226 User::Exit(0); // exit the server
228 aMessage.Terminate(0); // terminate the client
230 aMessage.Complete(KErrNone);
233 void CMyActiveScheduler::Error(TInt anError) const
235 // Called if any Run() method leaves.
239 User::Panic(_L("Server Error"),anError);
242 TInt RStressSvr::Connect()
244 // Connect to the server
248 TInt r=CreateSession(KServerName,Version(),KNumMessageSlots);
254 TInt RStressSvr::Test()
256 // Send a message and wait for completion.
260 return SendReceive(CMyServer::ETest);
263 void RStressSvr::Test(TRequestStatus& aStatus)
265 // Send a message asynchronously
269 SendReceive(CMyServer::ETest,aStatus);
272 TVersion RStressSvr::Version()
274 // Return the current version.
278 TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
282 LOCAL_C TInt ServerThread(TAny*)
285 CMyActiveScheduler* pR=new CMyActiveScheduler;
288 CActiveScheduler::Install(pR);
289 CMyServer* pS=CMyServer::New(0);
292 TInt r=pS->Start(KServerName);
296 CActiveScheduler::Start();
303 LOCAL_C TInt ClientThread(TAny* aPtr)
305 CClientThread* pT=(CClientThread*)aPtr;
306 CClientThread* pP=pT->iPrimary;
307 TBool primary=(pP==pT);
308 RStressSvr& d=pP->iSession;
310 seed[0]=User::TickCount();
327 pT->iConnected=ETrue;
328 TRequestStatus s[KNumMessageSlots];
329 for (i=0; i<KNumMessageSlots-1; i++)
331 TInt n=Random(seed)&16383;
332 for (i=0; i<n && r==KErrNone; i++)
334 pT->iConnected=EFalse;
341 TRequestStatus s[KNumMessageSlots];
342 for (i=0; i<KNumMessageSlots-1; i++)
349 dd.SetHandle(pP->iSession.Handle());
350 TInt n=Random(seed)&16383;
351 for (i=0; i<n && r==KErrNone; i++)
354 TInt ms=(Random(seed)&7)+1;
355 User::AfterHighRes(ms*1000);
360 CThread::CThread(TInt aPriority)
372 _LIT(KLitKernExec,"KERN-EXEC");
375 TExitType exitType=iThread.ExitType();
376 TInt exitReason=iThread.ExitReason();
377 TBuf<32> exitCat=iThread.ExitCategory();
379 if (exitType==EExitKill)
381 if (exitReason!=KErrNone && exitReason!=KErrServerTerminated)
384 else if (exitType==EExitPanic)
386 if (!PanicBadHandleAllowed() || exitCat!=KLitKernExec || exitReason!=EBadHandle)
389 RegisterAllowedPanic();
393 TFullName n(iThread.FullName());
394 test.Printf(_L("Thread %S exited %d,%d,%S\n"),&n,exitType,exitReason,&exitCat);
395 CActiveScheduler::Stop();
400 if (exitType==EExitTerminate)
402 else if (exitType==EExitKill && exitReason==KErrNone)
404 else if (exitReason==KErrServerTerminated)
405 ++iServerTerminatedCount;
409 test.Printf(_L("Start thread error %d\n"),r);
410 CActiveScheduler::Stop();
414 void CThread::DoCancel()
416 iThread.LogonCancel(iStatus);
419 const TInt KThreadStartAttempts=3;
420 TInt CThread::Start()
423 TInt n=KThreadStartAttempts;
429 if (r!=KErrAlreadyExists)
435 iThread.Logon(iStatus);
438 return ProcessStartError(r);
441 TBool CThread::PanicBadHandleAllowed()
446 void CThread::RegisterAllowedPanic()
450 void CThread::Cleanup()
454 TInt CThread::ProcessStartError(TInt anError)
459 CServerThread::CServerThread()
464 TInt CServerThread::StartThread()
468 seed[0]=User::TickCount();
469 TInt heapMin=TInt(Random(seed)&0x0f)+1;
471 TInt r=iThread.Create(KNullDesC(),ServerThread,KStackSize,heapMin,KHeapMaxSize,this); // use unnamed thread
478 void CServerThread::NewL()
480 CServerThread* pT=new (ELeave) CServerThread;
482 CActiveScheduler::Add(pT);
483 User::LeaveIfError(pT->Start());
486 void CServerThread::DisplayStats()
488 test.Printf(_L("Svr : X:%9d ST:%9d T:%9d RX:%9d\n"),iExitCount,iServerTerminatedCount,iTerminateCount,iMessagesReceived);
491 CClientThread::CClientThread(TInt anId)
492 : CThread(0), iId(anId)
496 TInt CClientThread::StartThread()
498 TInt r=iThread.Create(KNullDesC(),ClientThread,KStackSize,NULL,this); // use unnamed threads
501 iSession.SetHandle(0);
506 void CClientThread::NewL(TInt anId, TInt aPrimaryId)
508 CClientThread* pT=new (ELeave) CClientThread(anId);
510 pT->iPrimary=TheClients[aPrimaryId];
511 CActiveScheduler::Add(pT);
512 User::LeaveIfError(pT->Start());
515 void CClientThread::DisplayStats()
517 test.Printf(_L("Cli %1d: X:%9d ST:%9d T:%9d CL:%9d\n"),iId,iExitCount,iServerTerminatedCount,iTerminateCount,iCloses);
520 TBool CClientThread::PanicBadHandleAllowed()
522 return (iPrimary!=this);
525 void CClientThread::RegisterAllowedPanic()
530 void CClientThread::Cleanup()
535 if (!IsLocalHandle(iSession.Handle())) // don't close if not shared yet
537 CClientThread* pS1=TheClients[iId+1];
538 CClientThread* pS2=TheClients[iId+2];
539 if (pS1->iWaitingToRestart)
541 if (r==KErrNone && pS2->iWaitingToRestart)
545 test.Printf(_L("Start thread error %d\n"),r);
546 CActiveScheduler::Stop();
551 TInt CClientThread::ProcessStartError(TInt anError)
553 if (anError==KErrAlreadyExists && iPrimary!=this && !iWaitingToRestart)
555 iWaitingToRestart=ETrue;
558 iWaitingToRestart=EFalse;
562 void CRandomTimer::NewL()
564 CRandomTimer* pR=new (ELeave) CRandomTimer(20);
565 User::LeaveIfError(pR->iTimer.CreateLocal());
566 CActiveScheduler::Add(pR);
571 CRandomTimer::CRandomTimer(TInt aPriority)
574 iSeed[0]=User::TickCount();
577 CRandomTimer::~CRandomTimer()
583 void CRandomTimer::RunL()
586 TUint x=Random(iSeed)&15;
593 if (((CClientThread*)pT)->iWaitingToRestart)
601 void CRandomTimer::Start()
603 TUint x=Random(iSeed)&63;
605 iTimer.HighRes(iStatus, x*1000);
609 void CRandomTimer::DoCancel()
614 void CStatsTimer::NewL()
616 CStatsTimer* pT=new (ELeave) CStatsTimer(-10);
617 User::LeaveIfError(pT->iTimer.CreateLocal());
618 CActiveScheduler::Add(pT);
622 CStatsTimer::CStatsTimer(TInt aPriority)
625 iInitFreeRam = FreeRam();
628 CStatsTimer::~CStatsTimer()
634 void CStatsTimer::RunL()
636 TheServer->DisplayStats();
638 for (i=0; i<KNumClients; i++)
639 TheClients[i]->DisplayStats();
640 test.Printf(_L("RndTm: %9d\n"),TheRandomTimer->iCount);
641 TInt free_ram = FreeRam();
642 TInt delta_ram = iInitFreeRam - free_ram;
643 if (delta_ram > iMaxDelta)
644 iMaxDelta = delta_ram;
647 test.Printf(_L("Max RAM delta %dK Free RAM %08x\n"), iMaxDelta/1024, free_ram);
653 void CStatsTimer::Start()
655 iTimer.After(iStatus, 1000000);
659 void CStatsTimer::DoCancel()
666 CActiveScheduler* pA=new (ELeave) CActiveScheduler;
667 CActiveScheduler::Install(pA);
668 CServerThread::NewL();
672 for (p=0; p<KNumClients; p+=KNumSecondariesPerPrimary)
674 for (s=0; s<KNumSecondariesPerPrimary; s++)
676 CClientThread::NewL(id,p);
680 CRandomTimer::NewL();
684 GLDEF_C TInt E32Main()
692 User::SetCritical(User::ESystemCritical);
693 RThread().SetPriority(EPriorityMore);
694 User::SetJustInTime(EFalse); // prevent the debugger picking up expected thread panics.
696 TRAPD(r,InitialiseL());
699 CActiveScheduler::Start();
706 // Override heap creation for this process
707 // This function runs at the beginning of every thread
708 // Initial heap is shared but subsequent heaps are single threaded
709 TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
712 if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0)
716 r = CreateThreadHeap(aInfo, pH, 0, aNotFirst);
718 else if (aInfo.iAllocator)
721 RAllocator* pA = aInfo.iAllocator;
723 User::SwitchAllocator(pA);