os/kernelhwsrv/kerneltest/e32test/misc/t_svr6.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
// Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of the License "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// e32test\misc\t_svr6.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#define __E32TEST_EXTENSION__
sl@0
    19
#include <e32base.h>
sl@0
    20
#include <e32base_private.h>
sl@0
    21
#include <e32test.h>
sl@0
    22
#include <e32svr.h>
sl@0
    23
#include "u32std.h"
sl@0
    24
#include "../misc/prbs.h"
sl@0
    25
#include "../mmu/freeram.h"
sl@0
    26
sl@0
    27
const TInt KStackSize=0x1000;
sl@0
    28
const TInt KHeapMaxSize=0x100000;
sl@0
    29
const TInt KMajorVersionNumber=1;
sl@0
    30
const TInt KMinorVersionNumber=0;
sl@0
    31
const TInt KBuildVersionNumber=1;
sl@0
    32
const TInt KNumMessageSlots=10;
sl@0
    33
sl@0
    34
_LIT(KServerName,"StressSvr");
sl@0
    35
sl@0
    36
LOCAL_D RTest test(_L("T_SVR6"));
sl@0
    37
sl@0
    38
class CMySession : public CSession2
sl@0
    39
	{
sl@0
    40
public:
sl@0
    41
	CMySession();
sl@0
    42
	virtual void ServiceL(const RMessage2& aMessage);			 //pure virtual fns.
sl@0
    43
	void Process(const RMessage2& aMessage);
sl@0
    44
public:
sl@0
    45
	TInt iOutstanding;
sl@0
    46
	TUint iSeed[2];
sl@0
    47
	};
sl@0
    48
sl@0
    49
class CMyServer : public CServer2
sl@0
    50
	{
sl@0
    51
public:
sl@0
    52
	enum {ETest};
sl@0
    53
public:
sl@0
    54
	CMyServer(TInt aPriority);
sl@0
    55
	static CMyServer* New(TInt aPriority);
sl@0
    56
	virtual CSession2* NewSessionL(const TVersion& aVersion, const RMessage2&) const;//Overloading
sl@0
    57
	};
sl@0
    58
sl@0
    59
class CMyActiveScheduler : public CActiveScheduler
sl@0
    60
	{
sl@0
    61
public:
sl@0
    62
	virtual void Error(TInt anError) const;  //Overloading pure virtual function
sl@0
    63
	};
sl@0
    64
sl@0
    65
class RStressSvr : public RSessionBase
sl@0
    66
	{
sl@0
    67
public:
sl@0
    68
	TInt Connect();
sl@0
    69
	TInt Test();
sl@0
    70
	void Test(TRequestStatus& aStatus);
sl@0
    71
	TVersion Version();
sl@0
    72
	};
sl@0
    73
sl@0
    74
class CThread : public CActive
sl@0
    75
	{
sl@0
    76
public:
sl@0
    77
	CThread(TInt aPriority);
sl@0
    78
	~CThread();
sl@0
    79
	virtual void RunL();
sl@0
    80
	virtual void DoCancel();
sl@0
    81
	virtual void DisplayStats()=0;
sl@0
    82
	virtual TBool PanicBadHandleAllowed();
sl@0
    83
	virtual void RegisterAllowedPanic();
sl@0
    84
	virtual void Cleanup();
sl@0
    85
	virtual TInt ProcessStartError(TInt anError);
sl@0
    86
	TInt Start();
sl@0
    87
public:
sl@0
    88
	virtual TInt StartThread()=0;
sl@0
    89
public:
sl@0
    90
	RThread iThread;
sl@0
    91
	TInt iExitCount;
sl@0
    92
	TInt iServerTerminatedCount;
sl@0
    93
	TInt iTerminateCount;
sl@0
    94
	};
sl@0
    95
sl@0
    96
class CServerThread : public CThread
sl@0
    97
	{
sl@0
    98
public:
sl@0
    99
	static void NewL();
sl@0
   100
	CServerThread();
sl@0
   101
	virtual TInt StartThread();
sl@0
   102
	virtual void DisplayStats();
sl@0
   103
public:
sl@0
   104
	TInt iMessagesReceived;
sl@0
   105
	};
sl@0
   106
sl@0
   107
class CClientThread : public CThread
sl@0
   108
	{
sl@0
   109
public:
sl@0
   110
	static void NewL(TInt anId, TInt aPrimaryId);
sl@0
   111
	CClientThread(TInt anId);
sl@0
   112
	virtual TInt StartThread();
sl@0
   113
	virtual void DisplayStats();
sl@0
   114
	virtual TBool PanicBadHandleAllowed();
sl@0
   115
	virtual void RegisterAllowedPanic();
sl@0
   116
	virtual void Cleanup();
sl@0
   117
	virtual TInt ProcessStartError(TInt anError);
sl@0
   118
public:
sl@0
   119
	TInt iId;
sl@0
   120
	TInt iCloses;
sl@0
   121
	CClientThread* iPrimary;
sl@0
   122
	RStressSvr iSession;
sl@0
   123
	TBool iConnected;
sl@0
   124
	TBool iWaitingToRestart;
sl@0
   125
	};
sl@0
   126
sl@0
   127
class CRandomTimer : public CActive
sl@0
   128
	{
sl@0
   129
public:
sl@0
   130
	static void NewL();
sl@0
   131
	CRandomTimer(TInt aPriority);
sl@0
   132
	~CRandomTimer();
sl@0
   133
	virtual void RunL();
sl@0
   134
	virtual void DoCancel();
sl@0
   135
	void Start();
sl@0
   136
public:
sl@0
   137
	RTimer iTimer;
sl@0
   138
	TUint iSeed[2];
sl@0
   139
	TInt iCount;
sl@0
   140
	};
sl@0
   141
sl@0
   142
class CStatsTimer : public CActive
sl@0
   143
	{
sl@0
   144
public:
sl@0
   145
	static void NewL();
sl@0
   146
	CStatsTimer(TInt aPriority);
sl@0
   147
	~CStatsTimer();
sl@0
   148
	virtual void RunL();
sl@0
   149
	virtual void DoCancel();
sl@0
   150
	void Start();
sl@0
   151
public:
sl@0
   152
	RTimer iTimer;
sl@0
   153
	TInt iInitFreeRam;
sl@0
   154
	TInt iMaxDelta;
sl@0
   155
	TInt iCount;
sl@0
   156
	};
sl@0
   157
sl@0
   158
const TInt KNumPrimaryClients=3;
sl@0
   159
const TInt KNumSecondariesPerPrimary=3;
sl@0
   160
const TInt KNumClients=KNumPrimaryClients*KNumSecondariesPerPrimary;
sl@0
   161
LOCAL_D CServerThread* TheServer;
sl@0
   162
LOCAL_D CClientThread* TheClients[KNumClients];
sl@0
   163
LOCAL_D CRandomTimer* TheRandomTimer;
sl@0
   164
sl@0
   165
CMySession::CMySession()
sl@0
   166
//
sl@0
   167
// Constructor
sl@0
   168
//
sl@0
   169
	{
sl@0
   170
	iSeed[0]=User::TickCount();
sl@0
   171
	}
sl@0
   172
sl@0
   173
CMyServer* CMyServer::New(TInt aPriority)
sl@0
   174
//
sl@0
   175
// Create a new CMyServer.
sl@0
   176
//
sl@0
   177
	{
sl@0
   178
sl@0
   179
	return new CMyServer(aPriority);
sl@0
   180
	}
sl@0
   181
sl@0
   182
CMyServer::CMyServer(TInt aPriority)
sl@0
   183
//
sl@0
   184
// Constructor.
sl@0
   185
//
sl@0
   186
	: CServer2(aPriority, ESharableSessions)
sl@0
   187
	{}
sl@0
   188
sl@0
   189
CSession2* CMyServer::NewSessionL(const TVersion& aVersion, const RMessage2&) const
sl@0
   190
//
sl@0
   191
// Create a new client for this server.
sl@0
   192
//
sl@0
   193
	{
sl@0
   194
sl@0
   195
	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
   196
	if (!User::QueryVersionSupported(v,aVersion))
sl@0
   197
		User::Leave(KErrNotSupported);
sl@0
   198
	return new(ELeave) CMySession;
sl@0
   199
	}
sl@0
   200
sl@0
   201
void CMySession::ServiceL(const RMessage2& aMessage)
sl@0
   202
//
sl@0
   203
// Handle messages for this server.
sl@0
   204
//
sl@0
   205
	{
sl@0
   206
sl@0
   207
	++TheServer->iMessagesReceived;
sl@0
   208
	switch (aMessage.Function())
sl@0
   209
		{
sl@0
   210
		case CMyServer::ETest:
sl@0
   211
			if (iOutstanding==KNumMessageSlots-1)
sl@0
   212
				Process(aMessage);
sl@0
   213
			else
sl@0
   214
				++iOutstanding;
sl@0
   215
			break;
sl@0
   216
		default:
sl@0
   217
			aMessage.Complete(KErrNotSupported);
sl@0
   218
			break;
sl@0
   219
		}
sl@0
   220
	}
sl@0
   221
sl@0
   222
void CMySession::Process(const RMessage2& aMessage)
sl@0
   223
	{
sl@0
   224
	TUint x=Random(iSeed)&16383;
sl@0
   225
	if (x==0)
sl@0
   226
		User::Exit(0);			// exit the server
sl@0
   227
	else if (x<8)
sl@0
   228
		aMessage.Terminate(0);	// terminate the client
sl@0
   229
	else
sl@0
   230
		aMessage.Complete(KErrNone);
sl@0
   231
	}
sl@0
   232
sl@0
   233
void CMyActiveScheduler::Error(TInt anError) const
sl@0
   234
//
sl@0
   235
// Called if any Run() method leaves.
sl@0
   236
//
sl@0
   237
	{
sl@0
   238
sl@0
   239
	User::Panic(_L("Server Error"),anError);
sl@0
   240
	}
sl@0
   241
sl@0
   242
TInt RStressSvr::Connect()
sl@0
   243
//
sl@0
   244
// Connect to the server
sl@0
   245
//
sl@0
   246
	{
sl@0
   247
sl@0
   248
	TInt r=CreateSession(KServerName,Version(),KNumMessageSlots);
sl@0
   249
	if (r==KErrNone)
sl@0
   250
		r=ShareAuto();
sl@0
   251
	return r;
sl@0
   252
	}
sl@0
   253
sl@0
   254
TInt RStressSvr::Test()
sl@0
   255
//
sl@0
   256
// Send a message and wait for completion.
sl@0
   257
//
sl@0
   258
	{
sl@0
   259
sl@0
   260
	return SendReceive(CMyServer::ETest);
sl@0
   261
	}
sl@0
   262
sl@0
   263
void RStressSvr::Test(TRequestStatus& aStatus)
sl@0
   264
//
sl@0
   265
// Send a message asynchronously
sl@0
   266
//
sl@0
   267
	{
sl@0
   268
sl@0
   269
	SendReceive(CMyServer::ETest,aStatus);
sl@0
   270
	}
sl@0
   271
sl@0
   272
TVersion RStressSvr::Version()
sl@0
   273
//
sl@0
   274
// Return the current version.
sl@0
   275
//
sl@0
   276
	{
sl@0
   277
sl@0
   278
	TVersion v(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber);
sl@0
   279
	return(v);
sl@0
   280
	}
sl@0
   281
sl@0
   282
LOCAL_C TInt ServerThread(TAny*)
sl@0
   283
	{
sl@0
   284
sl@0
   285
	CMyActiveScheduler* pR=new CMyActiveScheduler;
sl@0
   286
	if (!pR)
sl@0
   287
		return KErrNoMemory;
sl@0
   288
	CActiveScheduler::Install(pR);
sl@0
   289
	CMyServer* pS=CMyServer::New(0);
sl@0
   290
	if (!pS)
sl@0
   291
		return KErrNoMemory;
sl@0
   292
	TInt r=pS->Start(KServerName);
sl@0
   293
	if (r!=KErrNone)
sl@0
   294
		return r;
sl@0
   295
sl@0
   296
	CActiveScheduler::Start();
sl@0
   297
sl@0
   298
	delete pS;
sl@0
   299
	delete pR;
sl@0
   300
	return KErrNone;
sl@0
   301
	}
sl@0
   302
sl@0
   303
LOCAL_C TInt ClientThread(TAny* aPtr)
sl@0
   304
	{
sl@0
   305
	CClientThread* pT=(CClientThread*)aPtr;
sl@0
   306
	CClientThread* pP=pT->iPrimary;
sl@0
   307
	TBool primary=(pP==pT);
sl@0
   308
	RStressSvr& d=pP->iSession;
sl@0
   309
	TUint seed[2];
sl@0
   310
	seed[0]=User::TickCount();
sl@0
   311
	seed[1]=0;
sl@0
   312
	TInt r=KErrNone;
sl@0
   313
	TInt i;
sl@0
   314
	if (primary)
sl@0
   315
		{
sl@0
   316
		FOREVER
sl@0
   317
			{
sl@0
   318
			FOREVER
sl@0
   319
				{
sl@0
   320
				r=d.Connect();
sl@0
   321
				if (r!=KErrNotFound)
sl@0
   322
					break;
sl@0
   323
				User::After(50000);
sl@0
   324
				}
sl@0
   325
			if (r!=KErrNone)
sl@0
   326
				return r;
sl@0
   327
			pT->iConnected=ETrue;
sl@0
   328
			TRequestStatus s[KNumMessageSlots];
sl@0
   329
			for (i=0; i<KNumMessageSlots-1; i++)
sl@0
   330
				d.Test(s[i]);
sl@0
   331
			TInt n=Random(seed)&16383;
sl@0
   332
			for (i=0; i<n && r==KErrNone; i++)
sl@0
   333
				r=d.Test();
sl@0
   334
			pT->iConnected=EFalse;
sl@0
   335
			d.Close();
sl@0
   336
			++pT->iCloses;
sl@0
   337
			}
sl@0
   338
		}
sl@0
   339
	else
sl@0
   340
		{
sl@0
   341
		TRequestStatus s[KNumMessageSlots];
sl@0
   342
		for (i=0; i<KNumMessageSlots-1; i++)
sl@0
   343
			d.Test(s[i]);
sl@0
   344
		FOREVER
sl@0
   345
			{
sl@0
   346
			if (pP->iConnected)
sl@0
   347
				{
sl@0
   348
				RStressSvr dd;
sl@0
   349
				dd.SetHandle(pP->iSession.Handle());
sl@0
   350
				TInt n=Random(seed)&16383;
sl@0
   351
				for (i=0; i<n && r==KErrNone; i++)
sl@0
   352
					r=dd.Test();
sl@0
   353
				}
sl@0
   354
			TInt ms=(Random(seed)&7)+1;
sl@0
   355
			User::AfterHighRes(ms*1000);
sl@0
   356
			}
sl@0
   357
		}
sl@0
   358
	}
sl@0
   359
sl@0
   360
CThread::CThread(TInt aPriority)
sl@0
   361
	: CActive(aPriority)
sl@0
   362
	{
sl@0
   363
	}
sl@0
   364
sl@0
   365
CThread::~CThread()
sl@0
   366
	{
sl@0
   367
	Cancel();
sl@0
   368
	iThread.Kill(0);
sl@0
   369
	iThread.Close();
sl@0
   370
	}
sl@0
   371
sl@0
   372
_LIT(KLitKernExec,"KERN-EXEC");
sl@0
   373
void CThread::RunL()
sl@0
   374
	{
sl@0
   375
	TExitType exitType=iThread.ExitType();
sl@0
   376
	TInt exitReason=iThread.ExitReason();
sl@0
   377
	TBuf<32> exitCat=iThread.ExitCategory();
sl@0
   378
	TBool bad=EFalse;
sl@0
   379
	if (exitType==EExitKill)
sl@0
   380
		{
sl@0
   381
		if (exitReason!=KErrNone && exitReason!=KErrServerTerminated)
sl@0
   382
			bad=ETrue;
sl@0
   383
		}
sl@0
   384
	else if (exitType==EExitPanic)
sl@0
   385
		{
sl@0
   386
		if (!PanicBadHandleAllowed() || exitCat!=KLitKernExec || exitReason!=EBadHandle)
sl@0
   387
			bad=ETrue;
sl@0
   388
		else
sl@0
   389
			RegisterAllowedPanic();
sl@0
   390
		}
sl@0
   391
	if (bad)
sl@0
   392
		{
sl@0
   393
		TFullName n(iThread.FullName());
sl@0
   394
		test.Printf(_L("Thread %S exited %d,%d,%S\n"),&n,exitType,exitReason,&exitCat);
sl@0
   395
		CActiveScheduler::Stop();
sl@0
   396
		return;
sl@0
   397
		}
sl@0
   398
	Cleanup();
sl@0
   399
	iThread.Close();
sl@0
   400
	if (exitType==EExitTerminate)
sl@0
   401
		++iTerminateCount;
sl@0
   402
	else if (exitType==EExitKill && exitReason==KErrNone)
sl@0
   403
		++iExitCount;
sl@0
   404
	else if (exitReason==KErrServerTerminated)
sl@0
   405
		++iServerTerminatedCount;
sl@0
   406
	TInt r=Start();
sl@0
   407
	if (r!=KErrNone)
sl@0
   408
		{
sl@0
   409
		test.Printf(_L("Start thread error %d\n"),r);
sl@0
   410
		CActiveScheduler::Stop();
sl@0
   411
		}
sl@0
   412
	}
sl@0
   413
sl@0
   414
void CThread::DoCancel()
sl@0
   415
	{
sl@0
   416
	iThread.LogonCancel(iStatus);
sl@0
   417
	}
sl@0
   418
sl@0
   419
const TInt KThreadStartAttempts=3;
sl@0
   420
TInt CThread::Start()
sl@0
   421
	{
sl@0
   422
	TInt r=KErrNone;
sl@0
   423
	TInt n=KThreadStartAttempts;
sl@0
   424
	while(n--)
sl@0
   425
		{
sl@0
   426
		r=StartThread();
sl@0
   427
		if (r==KErrNone)
sl@0
   428
			break;
sl@0
   429
		if (r!=KErrAlreadyExists)
sl@0
   430
			break;
sl@0
   431
		User::After(100000);
sl@0
   432
		}
sl@0
   433
	if (r==KErrNone)
sl@0
   434
		{
sl@0
   435
		iThread.Logon(iStatus);
sl@0
   436
		SetActive();
sl@0
   437
		}
sl@0
   438
	return ProcessStartError(r);
sl@0
   439
	}
sl@0
   440
sl@0
   441
TBool CThread::PanicBadHandleAllowed()
sl@0
   442
	{
sl@0
   443
	return EFalse;
sl@0
   444
	}
sl@0
   445
sl@0
   446
void CThread::RegisterAllowedPanic()
sl@0
   447
	{
sl@0
   448
	}
sl@0
   449
sl@0
   450
void CThread::Cleanup()
sl@0
   451
	{
sl@0
   452
	}
sl@0
   453
sl@0
   454
TInt CThread::ProcessStartError(TInt anError)
sl@0
   455
	{
sl@0
   456
	return anError;
sl@0
   457
	}
sl@0
   458
sl@0
   459
CServerThread::CServerThread()
sl@0
   460
	: CThread(0)
sl@0
   461
	{
sl@0
   462
	}
sl@0
   463
sl@0
   464
TInt CServerThread::StartThread()
sl@0
   465
	{
sl@0
   466
	TUint seed[2];
sl@0
   467
	seed[1]=0;
sl@0
   468
	seed[0]=User::TickCount();
sl@0
   469
	TInt heapMin=TInt(Random(seed)&0x0f)+1;
sl@0
   470
	heapMin<<=12;
sl@0
   471
	TInt r=iThread.Create(KNullDesC(),ServerThread,KStackSize,heapMin,KHeapMaxSize,this);	// use unnamed thread
sl@0
   472
	if (r!=KErrNone)
sl@0
   473
		return r;
sl@0
   474
	iThread.Resume();
sl@0
   475
	return KErrNone;
sl@0
   476
	}
sl@0
   477
sl@0
   478
void CServerThread::NewL()
sl@0
   479
	{
sl@0
   480
	CServerThread* pT=new (ELeave) CServerThread;
sl@0
   481
	TheServer=pT;
sl@0
   482
	CActiveScheduler::Add(pT);
sl@0
   483
	User::LeaveIfError(pT->Start());
sl@0
   484
	}
sl@0
   485
sl@0
   486
void CServerThread::DisplayStats()
sl@0
   487
	{
sl@0
   488
	test.Printf(_L("Svr  : X:%9d ST:%9d T:%9d RX:%9d\n"),iExitCount,iServerTerminatedCount,iTerminateCount,iMessagesReceived);
sl@0
   489
	}
sl@0
   490
sl@0
   491
CClientThread::CClientThread(TInt anId)
sl@0
   492
	: CThread(0), iId(anId)
sl@0
   493
	{
sl@0
   494
	}
sl@0
   495
sl@0
   496
TInt CClientThread::StartThread()
sl@0
   497
	{
sl@0
   498
	TInt r=iThread.Create(KNullDesC(),ClientThread,KStackSize,NULL,this);	// use unnamed threads
sl@0
   499
	if (r!=KErrNone)
sl@0
   500
		return r;
sl@0
   501
	iSession.SetHandle(0);
sl@0
   502
	iThread.Resume();
sl@0
   503
	return KErrNone;
sl@0
   504
	}
sl@0
   505
sl@0
   506
void CClientThread::NewL(TInt anId, TInt aPrimaryId)
sl@0
   507
	{
sl@0
   508
	CClientThread* pT=new (ELeave) CClientThread(anId);
sl@0
   509
	TheClients[anId]=pT;
sl@0
   510
	pT->iPrimary=TheClients[aPrimaryId];
sl@0
   511
	CActiveScheduler::Add(pT);
sl@0
   512
	User::LeaveIfError(pT->Start());
sl@0
   513
	}
sl@0
   514
sl@0
   515
void CClientThread::DisplayStats()
sl@0
   516
	{
sl@0
   517
	test.Printf(_L("Cli %1d: X:%9d ST:%9d T:%9d CL:%9d\n"),iId,iExitCount,iServerTerminatedCount,iTerminateCount,iCloses);
sl@0
   518
	}
sl@0
   519
sl@0
   520
TBool CClientThread::PanicBadHandleAllowed()
sl@0
   521
	{
sl@0
   522
	return (iPrimary!=this);
sl@0
   523
	}
sl@0
   524
sl@0
   525
void CClientThread::RegisterAllowedPanic()
sl@0
   526
	{
sl@0
   527
	++iCloses;
sl@0
   528
	}
sl@0
   529
sl@0
   530
void CClientThread::Cleanup()
sl@0
   531
	{
sl@0
   532
	TInt r=KErrNone;
sl@0
   533
	if (iPrimary==this)
sl@0
   534
		{
sl@0
   535
		if (!IsLocalHandle(iSession.Handle()))	// don't close if not shared yet
sl@0
   536
			iSession.Close();
sl@0
   537
		CClientThread* pS1=TheClients[iId+1];
sl@0
   538
		CClientThread* pS2=TheClients[iId+2];
sl@0
   539
		if (pS1->iWaitingToRestart)
sl@0
   540
			r=pS1->Start();
sl@0
   541
		if (r==KErrNone && pS2->iWaitingToRestart)
sl@0
   542
			r=pS2->Start();
sl@0
   543
		if (r!=KErrNone)
sl@0
   544
			{
sl@0
   545
			test.Printf(_L("Start thread error %d\n"),r);
sl@0
   546
			CActiveScheduler::Stop();
sl@0
   547
			}
sl@0
   548
		}
sl@0
   549
	}
sl@0
   550
sl@0
   551
TInt CClientThread::ProcessStartError(TInt anError)
sl@0
   552
	{
sl@0
   553
	if (anError==KErrAlreadyExists && iPrimary!=this && !iWaitingToRestart)
sl@0
   554
		{
sl@0
   555
		iWaitingToRestart=ETrue;
sl@0
   556
		return KErrNone;
sl@0
   557
		}
sl@0
   558
	iWaitingToRestart=EFalse;
sl@0
   559
	return anError;
sl@0
   560
	}
sl@0
   561
sl@0
   562
void CRandomTimer::NewL()
sl@0
   563
	{
sl@0
   564
	CRandomTimer* pR=new (ELeave) CRandomTimer(20);
sl@0
   565
	User::LeaveIfError(pR->iTimer.CreateLocal());
sl@0
   566
	CActiveScheduler::Add(pR);
sl@0
   567
	TheRandomTimer=pR;
sl@0
   568
	pR->Start();
sl@0
   569
	}
sl@0
   570
sl@0
   571
CRandomTimer::CRandomTimer(TInt aPriority)
sl@0
   572
	: CActive(aPriority)
sl@0
   573
	{
sl@0
   574
	iSeed[0]=User::TickCount();
sl@0
   575
	}
sl@0
   576
sl@0
   577
CRandomTimer::~CRandomTimer()
sl@0
   578
	{
sl@0
   579
	Cancel();
sl@0
   580
	iTimer.Close();
sl@0
   581
	}
sl@0
   582
sl@0
   583
void CRandomTimer::RunL()
sl@0
   584
	{
sl@0
   585
	++iCount;
sl@0
   586
	TUint x=Random(iSeed)&15;
sl@0
   587
	CThread* pT=NULL;
sl@0
   588
	if (x==0)
sl@0
   589
		pT=TheServer;
sl@0
   590
	else if (x<10)
sl@0
   591
		{
sl@0
   592
		pT=TheClients[x-1];
sl@0
   593
		if (((CClientThread*)pT)->iWaitingToRestart)
sl@0
   594
			pT=NULL;
sl@0
   595
		}
sl@0
   596
	if (pT)
sl@0
   597
		pT->iThread.Kill(0);
sl@0
   598
	Start();
sl@0
   599
	}
sl@0
   600
sl@0
   601
void CRandomTimer::Start()
sl@0
   602
	{
sl@0
   603
	TUint x=Random(iSeed)&63;
sl@0
   604
	x+=64;
sl@0
   605
	iTimer.HighRes(iStatus, x*1000);
sl@0
   606
	SetActive();
sl@0
   607
	}
sl@0
   608
sl@0
   609
void CRandomTimer::DoCancel()
sl@0
   610
	{
sl@0
   611
	iTimer.Cancel();
sl@0
   612
	}
sl@0
   613
sl@0
   614
void CStatsTimer::NewL()
sl@0
   615
	{
sl@0
   616
	CStatsTimer* pT=new (ELeave) CStatsTimer(-10);
sl@0
   617
	User::LeaveIfError(pT->iTimer.CreateLocal());
sl@0
   618
	CActiveScheduler::Add(pT);
sl@0
   619
	pT->Start();
sl@0
   620
	}
sl@0
   621
sl@0
   622
CStatsTimer::CStatsTimer(TInt aPriority)
sl@0
   623
	: CActive(aPriority)
sl@0
   624
	{
sl@0
   625
	iInitFreeRam = FreeRam();
sl@0
   626
	}
sl@0
   627
sl@0
   628
CStatsTimer::~CStatsTimer()
sl@0
   629
	{
sl@0
   630
	Cancel();
sl@0
   631
	iTimer.Close();
sl@0
   632
	}
sl@0
   633
sl@0
   634
void CStatsTimer::RunL()
sl@0
   635
	{
sl@0
   636
	TheServer->DisplayStats();
sl@0
   637
	TInt i;
sl@0
   638
	for (i=0; i<KNumClients; i++)
sl@0
   639
		TheClients[i]->DisplayStats();
sl@0
   640
	test.Printf(_L("RndTm: %9d\n"),TheRandomTimer->iCount);
sl@0
   641
	TInt free_ram = FreeRam();
sl@0
   642
	TInt delta_ram = iInitFreeRam - free_ram;
sl@0
   643
	if (delta_ram > iMaxDelta)
sl@0
   644
		iMaxDelta = delta_ram;
sl@0
   645
	if (++iCount==10)
sl@0
   646
		{
sl@0
   647
		test.Printf(_L("Max RAM delta %dK Free RAM %08x\n"), iMaxDelta/1024, free_ram);
sl@0
   648
		iCount=0;
sl@0
   649
		}
sl@0
   650
	Start();
sl@0
   651
	}
sl@0
   652
sl@0
   653
void CStatsTimer::Start()
sl@0
   654
	{
sl@0
   655
	iTimer.After(iStatus, 1000000);
sl@0
   656
	SetActive();
sl@0
   657
	}
sl@0
   658
sl@0
   659
void CStatsTimer::DoCancel()
sl@0
   660
	{
sl@0
   661
	iTimer.Cancel();
sl@0
   662
	}
sl@0
   663
sl@0
   664
void InitialiseL()
sl@0
   665
	{
sl@0
   666
	CActiveScheduler* pA=new (ELeave) CActiveScheduler;
sl@0
   667
	CActiveScheduler::Install(pA);
sl@0
   668
	CServerThread::NewL();
sl@0
   669
	TInt p;
sl@0
   670
	TInt s;
sl@0
   671
	TInt id=0;
sl@0
   672
	for (p=0; p<KNumClients; p+=KNumSecondariesPerPrimary)
sl@0
   673
		{
sl@0
   674
		for (s=0; s<KNumSecondariesPerPrimary; s++)
sl@0
   675
			{
sl@0
   676
			CClientThread::NewL(id,p);
sl@0
   677
			id++;
sl@0
   678
			}
sl@0
   679
		}
sl@0
   680
	CRandomTimer::NewL();
sl@0
   681
	CStatsTimer::NewL();
sl@0
   682
	}
sl@0
   683
sl@0
   684
GLDEF_C TInt E32Main()
sl@0
   685
//
sl@0
   686
// Test timers.
sl@0
   687
//
sl@0
   688
	{
sl@0
   689
sl@0
   690
	test.Title();
sl@0
   691
sl@0
   692
	User::SetCritical(User::ESystemCritical);
sl@0
   693
	RThread().SetPriority(EPriorityMore);
sl@0
   694
	User::SetJustInTime(EFalse);	// prevent the debugger picking up expected thread panics.
sl@0
   695
sl@0
   696
	TRAPD(r,InitialiseL());
sl@0
   697
	test(r==KErrNone);
sl@0
   698
sl@0
   699
	CActiveScheduler::Start();
sl@0
   700
sl@0
   701
	test(0);
sl@0
   702
sl@0
   703
	return(0);
sl@0
   704
	}
sl@0
   705
sl@0
   706
// Override heap creation for this process
sl@0
   707
// This function runs at the beginning of every thread
sl@0
   708
// Initial heap is shared but subsequent heaps are single threaded
sl@0
   709
TInt UserHeap::SetupThreadHeap(TBool aNotFirst, SStdEpocThreadCreateInfo& aInfo)
sl@0
   710
	{
sl@0
   711
	TInt r = KErrNone;
sl@0
   712
	if (!aInfo.iAllocator && aInfo.iHeapInitialSize>0)
sl@0
   713
		{
sl@0
   714
		// new heap required
sl@0
   715
		RHeap* pH = NULL;
sl@0
   716
		r = CreateThreadHeap(aInfo, pH, 0, aNotFirst);
sl@0
   717
		}
sl@0
   718
	else if (aInfo.iAllocator)
sl@0
   719
		{
sl@0
   720
		// sharing a heap
sl@0
   721
		RAllocator* pA = aInfo.iAllocator;
sl@0
   722
		pA->Open();
sl@0
   723
		User::SwitchAllocator(pA);
sl@0
   724
		}
sl@0
   725
	return r;
sl@0
   726
	}
sl@0
   727