os/kernelhwsrv/kerneltest/e32test/benchmark/ipc.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2002-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".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 //
    15 
    16 #include <e32test.h>
    17 
    18 #include "bm_suite.h"
    19 
    20 class RIpcSession : public RSessionBase
    21 	{
    22 public:
    23 	TInt CreateSession(TDesC& aName, TVersion aVer, TInt aSlots)
    24 		{
    25 		return RSessionBase::CreateSession(aName, aVer, aSlots);
    26 		}
    27 	void SendReceive(TInt aService, TIpcArgs& args, TRequestStatus& aStatus)
    28 		{
    29 		RSessionBase::SendReceive(aService, args, aStatus);
    30 		}
    31 	TInt SendReceive(TInt aService, TIpcArgs& args)
    32 		{
    33 		return RSessionBase::SendReceive(aService, args);
    34 		}
    35 	};
    36 
    37 class CIpcScheduler : public CActiveScheduler
    38 	{
    39 public:
    40 	CIpcScheduler()
    41 		{
    42 		CActiveScheduler::Install(this);
    43 		}
    44 	};
    45 
    46 class CIpcServer : public CServer2
    47 	{
    48 public:
    49 
    50 	enum TService 
    51 		{
    52 		ERunTest,
    53 		EGetTimes,
    54 		EStop
    55 		};
    56 
    57 	struct TServerTimes
    58 		{
    59 		TBMTicks iNewSessionEntryTime;
    60 		TBMTicks iNewSessionLeaveTime;
    61 		TBMTicks iServiceLTime;
    62 		};
    63 
    64 	CIpcServer() : CServer2(0)
    65 		{
    66 		}
    67 	virtual CSession2* NewSessionL(const TVersion& aVer, const RMessage2&) const;
    68 
    69 	TServerTimes	iTimes;
    70 
    71 	static TInt Entry(TAny* ptr);
    72 	};
    73 
    74 class CIpcSession : public CSession2
    75 	{
    76 public:
    77 	CIpcSession(CIpcServer* aServer)
    78 		{
    79 		iServer = aServer;
    80 		}
    81 	virtual void ServiceL(const RMessage2& aMessage);
    82 
    83 	CIpcServer*	iServer;
    84 	};
    85 
    86 class SpawnArgs : public TBMSpawnArgs
    87 	{
    88 public:
    89 
    90 	TBuf<16>	iServerName;
    91 	TVersion	iVersion;
    92 
    93 	RSemaphore	iSem;
    94 	TInt		iIterationCount;
    95 
    96 	SpawnArgs(const TPtrC& aServerName, TInt aPrio, TInt aRemote, TInt aIter);
    97 
    98 	void Close();
    99 	void ServerOpen();
   100 	void ServerClose();
   101 
   102 	};
   103 
   104 SpawnArgs::SpawnArgs(const TPtrC& aServerName, TInt aPrio, TInt aRemote, TInt aIter) :
   105 	TBMSpawnArgs(CIpcServer::Entry, aPrio, aRemote, sizeof(*this)),
   106 		iServerName(aServerName),
   107 		iVersion(1,0,1), 
   108 		iIterationCount(aIter)
   109 	{
   110 	TInt r;
   111 	if (aRemote)
   112 		{
   113 		r = iSem.CreateGlobal(_L("Semaphore"), 0);
   114 		BM_ERROR(r, r == KErrNone);
   115 		}
   116 	else
   117 		{
   118 		r = iSem.CreateLocal(0);
   119 		BM_ERROR(r, r == KErrNone);
   120 		}
   121 	}
   122 
   123 void SpawnArgs::ServerOpen()
   124 	{
   125 	if (iRemote)
   126 		{
   127 		iSem.Duplicate(iParent);
   128 		}
   129 	}
   130 
   131 void SpawnArgs::ServerClose()
   132 	{
   133 	if (iRemote)
   134 		{
   135 		iSem.Close();
   136 		}
   137 	}
   138 
   139 void SpawnArgs::Close()
   140 	{
   141 	iSem.Close();
   142 	}
   143 
   144 void CIpcSession::ServiceL(const RMessage2& aMessage)
   145 	{
   146 	CIpcServer::TService f = (CIpcServer::TService) aMessage.Function();
   147 	switch (f) 
   148 		{
   149 	case CIpcServer::ERunTest:
   150 		::bmTimer.Stamp(&iServer->iTimes.iServiceLTime);
   151 		break;
   152 	case CIpcServer::EGetTimes:
   153 		aMessage.WriteL(0, TPtrC8((TUint8*) &iServer->iTimes, sizeof(iServer->iTimes)));
   154 		break;
   155 	case CIpcServer::EStop:
   156 		CActiveScheduler::Stop();
   157 		break;
   158 	default:
   159 		BM_ASSERT(0);
   160 		}
   161 	aMessage.Complete(KErrNone);
   162 	}
   163 	
   164 CSession2* CIpcServer::NewSessionL(const TVersion&, const RMessage2&) const
   165 	{
   166 	CIpcServer* srv = (CIpcServer*) this;
   167 	::bmTimer.Stamp(&srv->iTimes.iNewSessionEntryTime);
   168 	CSession2* s  = new CIpcSession(srv);
   169 	BM_ERROR(KErrNoMemory, s);
   170 	::bmTimer.Stamp(&srv->iTimes.iNewSessionLeaveTime);
   171 	return s;
   172 	}
   173 
   174 TInt CIpcServer::Entry(TAny* ptr)
   175 	{
   176 	SpawnArgs* sa = (SpawnArgs*) ptr;
   177 
   178 	sa->ServerOpen();
   179 
   180 	CIpcScheduler* sched = new CIpcScheduler();
   181 	BM_ERROR(KErrNoMemory, sched);
   182 
   183 	CIpcServer* srv = new CIpcServer();
   184 	BM_ERROR(KErrNoMemory, srv);
   185 	TInt r = srv->Start(sa->iServerName);
   186 	BM_ERROR(r, r == KErrNone);
   187 	
   188 		// signal to the parent the end of the server intialization
   189 	sa->iSem.Signal();
   190 		
   191 	sched->Start();
   192 
   193 	delete srv;
   194 	delete sched;
   195 
   196 	sa->ServerClose();
   197 
   198 	return KErrNone;
   199 }
   200 
   201 static const TInt KMaxIpcLatencyResults = 5;
   202 
   203 class IpcLatency : public BMProgram
   204 	{
   205 public :
   206 
   207 	TBool		iRemote;
   208 	TInt		iPriority;
   209 	TBMResult	iResults[KMaxIpcLatencyResults];
   210 
   211 	IpcLatency(TBool aRemote, TInt aPriority) : 
   212 		BMProgram(
   213 			aRemote 
   214 				? ((aPriority == KBMPriorityHigh) 
   215 					? _L("Client-server Framework[Remote High Prioirty Server]")
   216 					: _L("Client-server Framework[Remote Low Prioirty Server]"))
   217 				: ((aPriority == KBMPriorityHigh) 
   218 					? _L("Client-server Framework[Local High Prioirty Server]")
   219 					: _L("Client-server Framework[Local Low Prioirty Server]")))
   220 		{
   221 		iPriority = aPriority;
   222 		iRemote = aRemote;
   223 		}
   224 
   225 	virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount);
   226 	};
   227 
   228 TBMResult* IpcLatency::Run(TBMUInt64 aIter, TInt* aCount)
   229 	{
   230 	SpawnArgs sa(_L("BMServer"), iPriority, iRemote, (TInt) aIter);
   231 
   232 		// spawn the server
   233 	MBMChild* child = SpawnChild(&sa);
   234 
   235 	TInt n = 0;
   236 	iResults[n++].Reset(_L("Connection Request Latency"));
   237 	iResults[n++].Reset(_L("Connection Reply Latency"));
   238 	iResults[n++].Reset(_L("Request Latency"));
   239 	iResults[n++].Reset(_L("Request Response Time"));
   240 	iResults[n++].Reset(_L("Reply Latency"));
   241 	BM_ASSERT(KMaxIpcLatencyResults >= n);
   242 
   243 		// wait for the srever intialization
   244 	sa.iSem.Wait();
   245 		// wait 2ms (ie more than one tick) to allow the server to complete its ActiveScheduler intialization ...
   246 	User::After(2000);
   247 
   248 	RIpcSession s;
   249 
   250 	for (TBMUInt64 i = 0; i < aIter; ++i)
   251 		{	
   252 		TBMTicks t1;
   253 		::bmTimer.Stamp(&t1);
   254 		TInt r = s.CreateSession(sa.iServerName, sa.iVersion, 1);
   255 		BM_ERROR(r, r == KErrNone);
   256 		TBMTicks t2;
   257 		::bmTimer.Stamp(&t2);
   258 
   259 		TRequestStatus st;
   260 
   261 		TBMTicks t3;
   262 		::bmTimer.Stamp(&t3);
   263 
   264 			{
   265 			TIpcArgs args;
   266 			s.SendReceive(CIpcServer::ERunTest, args, st);
   267 			}
   268 
   269 		TBMTicks t4;
   270 		::bmTimer.Stamp(&t4);
   271 
   272 		User::WaitForRequest(st);
   273 		BM_ERROR(r, st == KErrNone);
   274 
   275 		TBMTicks t5;
   276 		::bmTimer.Stamp(&t5);
   277 
   278 		CIpcServer::TServerTimes serverTimes;
   279 		TPtr8 serverTimesDes((TUint8*) &serverTimes, sizeof(serverTimes), sizeof(serverTimes));
   280 
   281 			{
   282 			TIpcArgs args(&serverTimesDes);
   283 			r = s.SendReceive(CIpcServer::EGetTimes, args);
   284 			BM_ERROR(r, r == KErrNone);
   285 			}
   286 
   287 		s.Close();	
   288 		
   289 		n = 0;
   290 		iResults[n++].Cumulate(TBMTicksDelta(t1, serverTimes.iNewSessionEntryTime));
   291 		iResults[n++].Cumulate(TBMTicksDelta(serverTimes.iNewSessionLeaveTime, t2));
   292 		iResults[n++].Cumulate(TBMTicksDelta(t3, serverTimes.iServiceLTime));
   293 		iResults[n++].Cumulate(TBMTicksDelta(t3, t4));
   294 		iResults[n++].Cumulate(TBMTicksDelta(serverTimes.iServiceLTime, t5));
   295 		BM_ASSERT(KMaxIpcLatencyResults >= n);	
   296 
   297 			// wait 2ms (ie more than one tick) to allow the server to complete.
   298 		User::After(2000);
   299 		}
   300 
   301 	TInt r = s.CreateSession(sa.iServerName, sa.iVersion, 1);
   302 	BM_ERROR(r, r == KErrNone);
   303 		{
   304 		TIpcArgs args;
   305 		s.SendReceive(CIpcServer::EStop, args);
   306 		}
   307 	s.Close();
   308 		
   309 	child->WaitChildExit();
   310 
   311 	sa.Close();
   312 
   313 	for (TInt j = 0; j < KMaxIpcLatencyResults; ++j)
   314 		{
   315 		iResults[j].Update();
   316 		}
   317 
   318 	*aCount = KMaxIpcLatencyResults;
   319 	return iResults;
   320 	}
   321 
   322 IpcLatency test1(EFalse,KBMPriorityHigh);
   323 IpcLatency test2(EFalse,KBMPriorityLow );
   324 IpcLatency test3(ETrue, KBMPriorityHigh);
   325 IpcLatency test4(ETrue, KBMPriorityLow );
   326 
   327 void AddIpc()
   328 	{
   329 	BMProgram* next = bmSuite;
   330 	bmSuite=(BMProgram*)&test4;
   331 	bmSuite->Next()=next;
   332 	bmSuite=(BMProgram*)&test3;
   333 	bmSuite->Next()=&test4;
   334 	bmSuite=(BMProgram*)&test2;
   335 	bmSuite->Next()=&test3;
   336 	bmSuite=(BMProgram*)&test1;
   337 	bmSuite->Next()=&test2;
   338 	}