1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/misc/t_svr3.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,599 @@
1.4 +// Copyright (c) 1995-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\misc\t_svr3.cpp
1.18 +//
1.19 +//
1.20 +
1.21 +#define __E32TEST_EXTENSION__
1.22 +
1.23 +#include <e32base.h>
1.24 +#include <e32base_private.h>
1.25 +#include <e32test.h>
1.26 +#include <e32svr.h>
1.27 +#include "u32std.h"
1.28 +#include "../misc/prbs.h"
1.29 +#include "../mmu/freeram.h"
1.30 +
1.31 +const TInt KStackSize=0x1000;
1.32 +const TInt KHeapMaxSize=0x100000;
1.33 +const TInt KMajorVersionNumber=1;
1.34 +const TInt KMinorVersionNumber=0;
1.35 +const TInt KBuildVersionNumber=1;
1.36 +const TInt KNumMessageSlots=20;
1.37 +
1.38 +_LIT(KServerName,"StressSvr");
1.39 +
1.40 +LOCAL_D RTest test(_L("T_SVR3"));
1.41 +
1.42 +class CMySession : public CSession2
1.43 + {
1.44 +public:
1.45 + CMySession();
1.46 + virtual void ServiceL(const RMessage2& aMessage); //pure virtual fns.
1.47 + void Process(const RMessage2& aMessage);
1.48 +public:
1.49 + TInt iOutstanding;
1.50 + TUint iSeed[2];
1.51 + };
1.52 +
1.53 +class CMyServer : public CServer2
1.54 + {
1.55 +public:
1.56 + enum {ETest};
1.57 +public:
1.58 + CMyServer(TInt aPriority);
1.59 + static CMyServer* New(TInt aPriority);
1.60 + virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2& aMessage) const;//Overloading
1.61 + };
1.62 +
1.63 +class CMyActiveScheduler : public CActiveScheduler
1.64 + {
1.65 +public:
1.66 + virtual void Error(TInt anError) const; //Overloading pure virtual function
1.67 + };
1.68 +
1.69 +class RStressSvr : public RSessionBase
1.70 + {
1.71 +public:
1.72 + TInt Connect();
1.73 + TInt Test();
1.74 + void Test(TRequestStatus& aStatus);
1.75 + TVersion Version();
1.76 + };
1.77 +
1.78 +class CThread : public CActive
1.79 + {
1.80 +public:
1.81 + CThread(TInt aPriority);
1.82 + ~CThread();
1.83 + virtual void RunL();
1.84 + virtual void DoCancel();
1.85 + virtual void DisplayStats()=0;
1.86 + TInt Start();
1.87 +public:
1.88 + virtual TInt StartThread()=0;
1.89 +public:
1.90 + RThread iThread;
1.91 + TInt iExitCount;
1.92 + TInt iServerTerminatedCount;
1.93 + TInt iTerminateCount;
1.94 + };
1.95 +
1.96 +class CServerThread : public CThread
1.97 + {
1.98 +public:
1.99 + static void NewL();
1.100 + CServerThread();
1.101 + virtual TInt StartThread();
1.102 + virtual void DisplayStats();
1.103 +public:
1.104 + TInt iMessagesReceived;
1.105 + };
1.106 +
1.107 +class CClientThread : public CThread
1.108 + {
1.109 +public:
1.110 + static void NewL(TInt anId);
1.111 + CClientThread(TInt anId);
1.112 + virtual TInt StartThread();
1.113 + virtual void DisplayStats();
1.114 +public:
1.115 + TInt iId;
1.116 + TInt iCloses;
1.117 + };
1.118 +
1.119 +class CRandomTimer : public CActive
1.120 + {
1.121 +public:
1.122 + static void NewL();
1.123 + CRandomTimer(TInt aPriority);
1.124 + ~CRandomTimer();
1.125 + virtual void RunL();
1.126 + virtual void DoCancel();
1.127 + void Start();
1.128 +public:
1.129 + RTimer iTimer;
1.130 + TUint iSeed[2];
1.131 + TInt iCount;
1.132 + };
1.133 +
1.134 +class CStatsTimer : public CActive
1.135 + {
1.136 +public:
1.137 + static void NewL();
1.138 + CStatsTimer(TInt aPriority);
1.139 + ~CStatsTimer();
1.140 + virtual void RunL();
1.141 + virtual void DoCancel();
1.142 + void Start();
1.143 +public:
1.144 + RTimer iTimer;
1.145 + TInt iInitFreeRam;
1.146 + TInt iMaxDelta;
1.147 + TInt iCount;
1.148 + };
1.149 +
1.150 +const TInt KNumClients=3;
1.151 +LOCAL_D CServerThread* TheServer;
1.152 +LOCAL_D CClientThread* TheClients[KNumClients];
1.153 +LOCAL_D CRandomTimer* TheRandomTimer;
1.154 +
1.155 +CMySession::CMySession()
1.156 +//
1.157 +// Constructor
1.158 +//
1.159 + {
1.160 + iSeed[0]=User::TickCount();
1.161 + }
1.162 +
1.163 +CMyServer* CMyServer::New(TInt aPriority)
1.164 +//
1.165 +// Create a new CMyServer.
1.166 +//
1.167 + {
1.168 +
1.169 + return new CMyServer(aPriority);
1.170 + }
1.171 +
1.172 +CMyServer::CMyServer(TInt aPriority)
1.173 +//
1.174 +// Constructor.
1.175 +//
1.176 + : CServer2(aPriority)
1.177 + {}
1.178 +
1.179 +CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
1.180 +//
1.181 +// Create a new client for this server.
1.182 +//
1.183 + {
1.184 +
1.185 + TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.186 + if (!User::QueryVersionSupported(v,aVersion))
1.187 + User::Leave(KErrNotSupported);
1.188 + return new(ELeave) CMySession;
1.189 + }
1.190 +
1.191 +void CMySession::ServiceL(const RMessage2& aMessage)
1.192 +//
1.193 +// Handle messages for this server.
1.194 +//
1.195 + {
1.196 +
1.197 + ++TheServer->iMessagesReceived;
1.198 + switch (aMessage.Function())
1.199 + {
1.200 + case CMyServer::ETest:
1.201 + if (iOutstanding==KNumMessageSlots-1)
1.202 + Process(aMessage);
1.203 + else
1.204 + ++iOutstanding;
1.205 + break;
1.206 + default:
1.207 + aMessage.Complete(KErrNotSupported);
1.208 + break;
1.209 + }
1.210 + }
1.211 +
1.212 +void CMySession::Process(const RMessage2& aMessage)
1.213 + {
1.214 + TUint x=Random(iSeed)&16383;
1.215 + if (x==0)
1.216 + User::Exit(0); // exit the server
1.217 + else if (x<8)
1.218 + aMessage.Terminate(0); // terminate the client
1.219 + else
1.220 + aMessage.Complete(KErrNone);
1.221 + }
1.222 +
1.223 +void CMyActiveScheduler::Error(TInt anError) const
1.224 +//
1.225 +// Called if any Run() method leaves.
1.226 +//
1.227 + {
1.228 +
1.229 + User::Panic(_L("Server Error"),anError);
1.230 + }
1.231 +
1.232 +TInt RStressSvr::Connect()
1.233 +//
1.234 +// Connect to the server
1.235 +//
1.236 + {
1.237 +
1.238 + return CreateSession(KServerName,Version(),KNumMessageSlots);
1.239 + }
1.240 +
1.241 +TInt RStressSvr::Test()
1.242 +//
1.243 +// Send a message and wait for completion.
1.244 +//
1.245 + {
1.246 +
1.247 + return SendReceive(CMyServer::ETest);
1.248 + }
1.249 +
1.250 +void RStressSvr::Test(TRequestStatus& aStatus)
1.251 +//
1.252 +// Send a message asynchronously
1.253 +//
1.254 + {
1.255 +
1.256 + SendReceive(CMyServer::ETest,aStatus);
1.257 + }
1.258 +
1.259 +TVersion RStressSvr::Version()
1.260 +//
1.261 +// Return the current version.
1.262 +//
1.263 + {
1.264 +
1.265 + TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
1.266 + return(v);
1.267 + }
1.268 +
1.269 +LOCAL_C TInt ServerThread(TAny*)
1.270 + {
1.271 +
1.272 + CMyActiveScheduler* pR=new CMyActiveScheduler;
1.273 + if (!pR)
1.274 + return KErrNoMemory;
1.275 + CActiveScheduler::Install(pR);
1.276 + CMyServer* pS=CMyServer::New(0);
1.277 + if (!pS)
1.278 + return KErrNoMemory;
1.279 + TInt r=pS->Start(KServerName);
1.280 + if (r!=KErrNone)
1.281 + return r;
1.282 +
1.283 + CActiveScheduler::Start();
1.284 +
1.285 + delete pS;
1.286 + delete pR;
1.287 + return KErrNone;
1.288 + }
1.289 +
1.290 +LOCAL_C TInt ClientThread(TAny* aPtr)
1.291 + {
1.292 + CClientThread* pT=(CClientThread*)aPtr;
1.293 + RStressSvr d;
1.294 + TUint seed[2];
1.295 + seed[0]=User::TickCount();
1.296 + seed[1]=0;
1.297 + FOREVER
1.298 + {
1.299 + TInt r;
1.300 + FOREVER
1.301 + {
1.302 + r=d.Connect();
1.303 + if (r!=KErrNotFound)
1.304 + break;
1.305 + User::After(50000);
1.306 + }
1.307 + if (r!=KErrNone)
1.308 + return r;
1.309 + TRequestStatus s[KNumMessageSlots];
1.310 + TInt i;
1.311 + for (i=0; i<KNumMessageSlots-1; i++)
1.312 + d.Test(s[i]);
1.313 + TInt n=Random(seed)&16383;
1.314 + for (i=0; i<n; i++)
1.315 + d.Test();
1.316 + d.Close();
1.317 + ++pT->iCloses;
1.318 + }
1.319 + }
1.320 +
1.321 +CThread::CThread(TInt aPriority)
1.322 + : CActive(aPriority)
1.323 + {
1.324 + }
1.325 +
1.326 +CThread::~CThread()
1.327 + {
1.328 + Cancel();
1.329 + iThread.Kill(0);
1.330 + iThread.Close();
1.331 + }
1.332 +
1.333 +void CThread::RunL()
1.334 + {
1.335 + TExitType exitType=iThread.ExitType();
1.336 + TInt exitReason=iThread.ExitReason();
1.337 + TBuf<32> exitCat=iThread.ExitCategory();
1.338 + TBool bad=EFalse;
1.339 + if (exitType==EExitKill)
1.340 + {
1.341 + if (exitReason!=KErrNone && exitReason!=KErrServerTerminated)
1.342 + bad=ETrue;
1.343 + }
1.344 + else if (exitType==EExitPanic)
1.345 + bad=ETrue;
1.346 + if (bad)
1.347 + {
1.348 + TFullName n(iThread.FullName());
1.349 + test.Printf(_L("Thread %S exited %d,%d,%S\n"),&n,exitType,exitReason,&exitCat);
1.350 + CActiveScheduler::Stop();
1.351 + return;
1.352 + }
1.353 + iThread.Close();
1.354 + if (exitType==EExitTerminate)
1.355 + ++iTerminateCount;
1.356 + else if (exitReason==KErrNone)
1.357 + ++iExitCount;
1.358 + else if (exitReason==KErrServerTerminated)
1.359 + ++iServerTerminatedCount;
1.360 + TInt r=Start();
1.361 + if (r!=KErrNone)
1.362 + {
1.363 + test.Printf(_L("Start thread error %d\n"),r);
1.364 + CActiveScheduler::Stop();
1.365 + }
1.366 + }
1.367 +
1.368 +void CThread::DoCancel()
1.369 + {
1.370 + iThread.LogonCancel(iStatus);
1.371 + }
1.372 +
1.373 +TInt CThread::Start()
1.374 + {
1.375 + TInt r;
1.376 + FOREVER
1.377 + {
1.378 + r=StartThread();
1.379 + if (r==KErrNone)
1.380 + break;
1.381 + if (r!=KErrAlreadyExists)
1.382 + break;
1.383 + User::After(100000);
1.384 + }
1.385 + if (r==KErrNone)
1.386 + {
1.387 + iThread.Logon(iStatus);
1.388 + SetActive();
1.389 + }
1.390 + return r;
1.391 + }
1.392 +
1.393 +CServerThread::CServerThread()
1.394 + : CThread(0)
1.395 + {
1.396 + }
1.397 +
1.398 +TInt CServerThread::StartThread()
1.399 + {
1.400 + TUint seed[2];
1.401 + seed[1]=0;
1.402 + seed[0]=User::TickCount();
1.403 + TInt heapMin=TInt(Random(seed)&0x0f)+1;
1.404 + heapMin<<=12;
1.405 + TInt r=iThread.Create(KNullDesC(),ServerThread,KStackSize,heapMin,KHeapMaxSize,this); // use unnamed thread
1.406 + if (r!=KErrNone)
1.407 + return r;
1.408 + iThread.Resume();
1.409 + return KErrNone;
1.410 + }
1.411 +
1.412 +void CServerThread::NewL()
1.413 + {
1.414 + CServerThread* pT=new (ELeave) CServerThread;
1.415 + TheServer=pT;
1.416 + CActiveScheduler::Add(pT);
1.417 + User::LeaveIfError(pT->Start());
1.418 + }
1.419 +
1.420 +void CServerThread::DisplayStats()
1.421 + {
1.422 + test.Printf(_L("Svr : X:%9d ST:%9d T:%9d RX:%9d\n"),iExitCount,iServerTerminatedCount,iTerminateCount,iMessagesReceived);
1.423 + }
1.424 +
1.425 +CClientThread::CClientThread(TInt anId)
1.426 + : CThread(0), iId(anId)
1.427 + {
1.428 + }
1.429 +
1.430 +TInt CClientThread::StartThread()
1.431 + {
1.432 + TInt r=iThread.Create(KNullDesC(),ClientThread,KStackSize,NULL,this); // use unnamed thread
1.433 + if (r!=KErrNone)
1.434 + return r;
1.435 + iThread.Resume();
1.436 + return KErrNone;
1.437 + }
1.438 +
1.439 +void CClientThread::NewL(TInt anId)
1.440 + {
1.441 + CClientThread* pT=new (ELeave) CClientThread(anId);
1.442 + TheClients[anId]=pT;
1.443 + CActiveScheduler::Add(pT);
1.444 + User::LeaveIfError(pT->Start());
1.445 + }
1.446 +
1.447 +void CClientThread::DisplayStats()
1.448 + {
1.449 + test.Printf(_L("Cli %1d: X:%9d ST:%9d T:%9d CL:%9d\n"),iId,iExitCount,iServerTerminatedCount,iTerminateCount,iCloses);
1.450 + }
1.451 +
1.452 +void CRandomTimer::NewL()
1.453 + {
1.454 + CRandomTimer* pR=new (ELeave) CRandomTimer(20);
1.455 + User::LeaveIfError(pR->iTimer.CreateLocal());
1.456 + CActiveScheduler::Add(pR);
1.457 + TheRandomTimer=pR;
1.458 + pR->Start();
1.459 + }
1.460 +
1.461 +CRandomTimer::CRandomTimer(TInt aPriority)
1.462 + : CActive(aPriority)
1.463 + {
1.464 + iSeed[0]=User::TickCount();
1.465 + }
1.466 +
1.467 +CRandomTimer::~CRandomTimer()
1.468 + {
1.469 + Cancel();
1.470 + iTimer.Close();
1.471 + }
1.472 +
1.473 +void CRandomTimer::RunL()
1.474 + {
1.475 + ++iCount;
1.476 + TUint x=Random(iSeed)&3;
1.477 + CThread* pT;
1.478 + if (x==0)
1.479 + pT=TheServer;
1.480 + else
1.481 + pT=TheClients[x-1];
1.482 + pT->iThread.Kill(0);
1.483 + Start();
1.484 + }
1.485 +
1.486 +void CRandomTimer::Start()
1.487 + {
1.488 + TUint x=Random(iSeed)&63;
1.489 + x+=32;
1.490 + iTimer.HighRes(iStatus, x*1000);
1.491 + SetActive();
1.492 + }
1.493 +
1.494 +void CRandomTimer::DoCancel()
1.495 + {
1.496 + iTimer.Cancel();
1.497 + }
1.498 +
1.499 +void CStatsTimer::NewL()
1.500 + {
1.501 + CStatsTimer* pT=new (ELeave) CStatsTimer(-10);
1.502 + User::LeaveIfError(pT->iTimer.CreateLocal());
1.503 + CActiveScheduler::Add(pT);
1.504 + pT->Start();
1.505 + }
1.506 +
1.507 +CStatsTimer::CStatsTimer(TInt aPriority)
1.508 + : CActive(aPriority)
1.509 + {
1.510 + iInitFreeRam = FreeRam();
1.511 + }
1.512 +
1.513 +CStatsTimer::~CStatsTimer()
1.514 + {
1.515 + Cancel();
1.516 + iTimer.Close();
1.517 + }
1.518 +
1.519 +void CStatsTimer::RunL()
1.520 + {
1.521 + TheServer->DisplayStats();
1.522 + TInt i;
1.523 + for (i=0; i<KNumClients; i++)
1.524 + TheClients[i]->DisplayStats();
1.525 + test.Printf(_L("RndTm: %9d\n"),TheRandomTimer->iCount);
1.526 + TInt free_ram = FreeRam();
1.527 + TInt delta_ram = iInitFreeRam - free_ram;
1.528 + if (delta_ram > iMaxDelta)
1.529 + iMaxDelta = delta_ram;
1.530 + if (++iCount==10)
1.531 + {
1.532 + test.Printf(_L("Max RAM delta %dK Free RAM %08x\n"), iMaxDelta/1024, free_ram);
1.533 + iCount=0;
1.534 + }
1.535 + Start();
1.536 + }
1.537 +
1.538 +void CStatsTimer::Start()
1.539 + {
1.540 + iTimer.After(iStatus, 1000000);
1.541 + SetActive();
1.542 + }
1.543 +
1.544 +void CStatsTimer::DoCancel()
1.545 + {
1.546 + iTimer.Cancel();
1.547 + }
1.548 +
1.549 +void InitialiseL()
1.550 + {
1.551 + CActiveScheduler* pA=new (ELeave) CActiveScheduler;
1.552 + CActiveScheduler::Install(pA);
1.553 + CServerThread::NewL();
1.554 + TInt id;
1.555 + for (id=0; id<KNumClients; id++)
1.556 + CClientThread::NewL(id);
1.557 + CRandomTimer::NewL();
1.558 + CStatsTimer::NewL();
1.559 + }
1.560 +
1.561 +GLDEF_C TInt E32Main()
1.562 +//
1.563 +// Test timers.
1.564 +//
1.565 + {
1.566 +
1.567 + test.Title();
1.568 +
1.569 + RThread().SetPriority(EPriorityMore);
1.570 +
1.571 + TRAPD(r,InitialiseL());
1.572 + test(r==KErrNone);
1.573 +
1.574 + CActiveScheduler::Start();
1.575 +
1.576 + test(0);
1.577 +
1.578 + return(0);
1.579 + }
1.580 +
1.581 +// Override heap creation for this process
1.582 +// This function runs at the beginning of every thread
1.583 +// Initial heap is shared but subsequent heaps are single threaded
1.584 +TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
1.585 + {
1.586 + TInt r = KErrNone;
1.587 + if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0)
1.588 + {
1.589 + // new heap required
1.590 + RHeap* pH = NULL;
1.591 + r = CreateThreadHeap(aInfo, pH, 0, aNotFirst);
1.592 + }
1.593 + else if (aInfo.iAllocator)
1.594 + {
1.595 + // sharing a heap
1.596 + RAllocator* pA = aInfo.iAllocator;
1.597 + pA->Open();
1.598 + User::SwitchAllocator(pA);
1.599 + }
1.600 + return r;
1.601 + }
1.602 +