kerneltest/e32test/benchmark/sync.cpp
changeset 0 a41df078684a
child 39 2bb754abd467
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 #include <e32msgqueue.h>
       
    18 
       
    19 #include "bm_suite.h"
       
    20 
       
    21 class Sync : public BMProgram
       
    22 	{
       
    23 public :
       
    24 	Sync() : BMProgram(_L("Synchronization Primitives"))
       
    25 		{}
       
    26 	virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount);
       
    27 
       
    28 	typedef void (*MeasurementFunc)(TBMResult*, TBMUInt64 aIter, TBool aRemote);
       
    29 	struct Measurement 
       
    30 		{
       
    31 		MeasurementFunc iFunc;
       
    32 		TPtrC			iName;
       
    33 		TBool			iRemote;
       
    34 
       
    35 		Measurement(MeasurementFunc aFunc, const TDesC& aName, TBool aRemote = EFalse) : 
       
    36 					iFunc(aFunc), iName(aName), iRemote(aRemote) {}
       
    37 		};
       
    38 
       
    39 	static TBMResult iResults[];
       
    40 	static Measurement iMeasurements[];
       
    41 
       
    42 	static void MutexPassing(TBMResult*, TBMUInt64 aIter, TBool aRemote);
       
    43 	static void MutexContentionParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote);
       
    44 	static TInt MutexContentionChild(TAny*);
       
    45 	static void SemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote);
       
    46 	static TInt SemaphoreLatencyChild(TAny*);
       
    47 	static void ThreadSemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote);
       
    48 	static TInt ThreadSemaphoreLatencyChild(TAny*);
       
    49 	};
       
    50 
       
    51 Sync::Measurement Sync::iMeasurements[] =
       
    52 	{
       
    53 	Measurement(&Sync::MutexPassing, _L("Mutex Passing Case")),
       
    54 	Measurement(&Sync::MutexContentionParent, _L("Local Mutex Contention")),
       
    55 	Measurement(&Sync::MutexContentionParent, _L("Remote Mutex Contention"), ETrue),
       
    56 	Measurement(&Sync::SemaphoreLatencyParent, _L("Local Semaphore Latency")),
       
    57 	Measurement(&Sync::SemaphoreLatencyParent, _L("Remote Semaphore Latency"), ETrue),
       
    58 	Measurement(&Sync::ThreadSemaphoreLatencyParent, _L("Local Thread Semaphore Latency")),
       
    59 	};
       
    60 TBMResult Sync::iResults[sizeof(Sync::iMeasurements)/sizeof(Sync::iMeasurements[0])];
       
    61 
       
    62 static Sync sync;
       
    63 
       
    64 void Sync::MutexPassing(TBMResult* aResult, TBMUInt64 aIter, TBool)
       
    65 	{
       
    66 	RMutex mutex;
       
    67 	mutex.CreateLocal();
       
    68 
       
    69 	TBMTimeInterval ti;
       
    70 	ti.Begin();
       
    71 	for (TBMUInt64 i = 0; i < aIter; ++i)
       
    72 		{
       
    73 		mutex.Wait();
       
    74 		mutex.Signal();
       
    75 		}
       
    76 	TBMTicks t = ti.End();
       
    77 
       
    78 	mutex.Close();
       
    79 
       
    80 	aResult->Cumulate(t, aIter);
       
    81 	}
       
    82 
       
    83 class MutexContentionArgs : public TBMSpawnArgs
       
    84 	{
       
    85 public:
       
    86 	
       
    87 	RMutex		iMutexA;
       
    88 	RMutex		iMutexB;
       
    89 	RSemaphore	iSem;
       
    90 	TBMUInt64	iIterationCount;
       
    91 
       
    92 	MutexContentionArgs(TInt aRemote, TBMUInt64 aIter);
       
    93 
       
    94 	void ChildOpen();
       
    95 	void ChildClose();
       
    96 
       
    97 	void Close();
       
    98 	};
       
    99 
       
   100 MutexContentionArgs::MutexContentionArgs(TInt aRemote, TBMUInt64 aIter) :
       
   101 		TBMSpawnArgs(Sync::MutexContentionChild, KBMPriorityLow, aRemote, sizeof(*this)),
       
   102 		iIterationCount(aIter)
       
   103 	{
       
   104 	TInt r;
       
   105 	if (aRemote)
       
   106 		{
       
   107 		r = iMutexA.CreateGlobal(_L("MutexA"));
       
   108 		BM_ERROR(r, r == KErrNone);
       
   109 		r = iMutexB.CreateGlobal(_L("MutexB"));
       
   110 		BM_ERROR(r, r == KErrNone);
       
   111 		r = iSem.CreateGlobal(_L("Semaphore"), 0);
       
   112 		BM_ERROR(r, r == KErrNone);
       
   113 		}
       
   114 	else
       
   115 		{
       
   116 		r = iMutexA.CreateLocal();
       
   117 		BM_ERROR(r, r == KErrNone);
       
   118 		r = iMutexB.CreateLocal();
       
   119 		BM_ERROR(r, r == KErrNone);
       
   120 		r = iSem.CreateLocal(0);
       
   121 		BM_ERROR(r, r == KErrNone);
       
   122 		}
       
   123 	}
       
   124 
       
   125 void MutexContentionArgs::ChildOpen()
       
   126 	{
       
   127 	if (iRemote)
       
   128 		{
       
   129 		iMutexA.Duplicate(iParent);
       
   130 		iMutexB.Duplicate(iParent);
       
   131 		iSem.Duplicate(iParent);
       
   132 		}
       
   133 	}
       
   134 
       
   135 void MutexContentionArgs::ChildClose()
       
   136 	{
       
   137 	if (iRemote)
       
   138 		{
       
   139 		iMutexA.Close();
       
   140 		iMutexB.Close();
       
   141 		iSem.Close();
       
   142 		}
       
   143 	}
       
   144 
       
   145 void MutexContentionArgs::Close()
       
   146 	{
       
   147 	iMutexA.Close();
       
   148 	iMutexB.Close();
       
   149 	iSem.Close();
       
   150 	}
       
   151 
       
   152 void Sync::MutexContentionParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
       
   153 	{
       
   154 	MutexContentionArgs mc(aRemote, aIter);
       
   155 
       
   156 	MBMChild* child = sync.SpawnChild(&mc);
       
   157 
       
   158 	mc.iSem.Wait();
       
   159 
       
   160 	TBMTimeInterval ti;
       
   161 	ti.Begin();
       
   162 	for (TBMUInt64 i = 0; i < aIter; ++i)
       
   163 		{
       
   164 		mc.iMutexA.Wait();
       
   165 		mc.iMutexA.Signal();
       
   166 		mc.iMutexB.Wait();
       
   167 		mc.iMutexB.Signal();
       
   168 		}	
       
   169 	TBMTicks t = ti.End();
       
   170 
       
   171 	child->WaitChildExit();
       
   172 	mc.Close();
       
   173 
       
   174 	aResult->Cumulate(t/2, aIter);
       
   175 	}
       
   176 
       
   177 TInt Sync::MutexContentionChild(TAny* ptr)
       
   178 	{
       
   179 	MutexContentionArgs* mc = (MutexContentionArgs*) ptr;
       
   180 	mc->ChildOpen();
       
   181 
       
   182 	mc->iMutexA.Wait();
       
   183 	mc->iSem.Signal();
       
   184 	for (TBMUInt64 i = 0; i < mc->iIterationCount; ++i)
       
   185 		{
       
   186 		mc->iMutexB.Wait();
       
   187 		mc->iMutexA.Signal();
       
   188 		mc->iMutexA.Wait();
       
   189 		mc->iMutexB.Signal();
       
   190 		}
       
   191 	mc->iMutexA.Signal();
       
   192 
       
   193 	mc->ChildClose();
       
   194 	return KErrNone;
       
   195 	}
       
   196 
       
   197 class SemaphoreLatencyArgs : public TBMSpawnArgs
       
   198 	{
       
   199 public:
       
   200 	
       
   201 	RSemaphore			iSem;
       
   202 	TBMUInt64			iIterationCount;
       
   203 	RMsgQueue<TBMTicks>	iSignalTimeQue;
       
   204 
       
   205 	SemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter);
       
   206 
       
   207 	void ChildOpen();
       
   208 	void ChildClose();
       
   209 
       
   210 	TBMTicks SignalTime();
       
   211 	void ChildSignalTime(TBMTicks);
       
   212 
       
   213 	void Close();
       
   214 	};
       
   215 
       
   216 SemaphoreLatencyArgs::SemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter) : 
       
   217 	TBMSpawnArgs(Sync::SemaphoreLatencyChild, KBMPriorityLow, aRemote, sizeof(*this)),
       
   218 	iIterationCount(aIter)
       
   219 	{
       
   220 	TInt r;
       
   221 	if (aRemote)
       
   222 		{
       
   223 		r = iSem.CreateGlobal(_L("BM Semaphore"), 0);
       
   224 		BM_ERROR(r, r == KErrNone);
       
   225 		}
       
   226 	else
       
   227 		{
       
   228 		r = iSem.CreateLocal(0);
       
   229 		BM_ERROR(r, r == KErrNone);
       
   230 		}
       
   231 	r = iSignalTimeQue.CreateGlobal(_L("BM Queue"), 1);
       
   232 	BM_ERROR(r, r == KErrNone);
       
   233 	}	
       
   234 
       
   235 void SemaphoreLatencyArgs::ChildOpen()
       
   236 	{
       
   237 	if (iRemote)
       
   238 		{
       
   239 		iSem.Duplicate(iParent);
       
   240 		TInt r = iSignalTimeQue.OpenGlobal(_L("BM Queue"));
       
   241 		BM_ERROR(r, r == KErrNone);
       
   242 		}
       
   243 	}
       
   244 
       
   245 void SemaphoreLatencyArgs::ChildSignalTime(TBMTicks aTime)
       
   246 	{
       
   247 	TInt r = iSignalTimeQue.Send(aTime);
       
   248 	BM_ERROR(r, r == KErrNone);
       
   249 	}
       
   250 
       
   251 TBMTicks SemaphoreLatencyArgs::SignalTime()
       
   252 	{
       
   253 	TBMTicks time;
       
   254 	iSignalTimeQue.ReceiveBlocking(time);
       
   255 	return time;
       
   256 	}
       
   257 
       
   258 void SemaphoreLatencyArgs::ChildClose()
       
   259 	{
       
   260 	if (iRemote)
       
   261 		{
       
   262 		iSem.Close();
       
   263 		iSignalTimeQue.Close();
       
   264 		}
       
   265 	}
       
   266 
       
   267 void SemaphoreLatencyArgs::Close()
       
   268 	{
       
   269 	iSem.Close();
       
   270 	iSignalTimeQue.Close();
       
   271 	}
       
   272 
       
   273 void Sync::SemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
       
   274 	{
       
   275 	SemaphoreLatencyArgs sl(aRemote, aIter);
       
   276 	MBMChild* child = sync.SpawnChild(&sl);
       
   277 	for (TBMUInt64 i = 0; i < aIter; ++i)
       
   278 		{
       
   279 		sl.iSem.Wait();
       
   280 		TBMTicks now;
       
   281 		::bmTimer.Stamp(&now);
       
   282 		aResult->Cumulate(TBMTicksDelta(sl.SignalTime(), now));
       
   283 		}
       
   284 	child->WaitChildExit();
       
   285 	sl.Close();
       
   286 	}
       
   287 
       
   288 TInt Sync::SemaphoreLatencyChild(TAny* ptr)
       
   289 	{
       
   290 	SemaphoreLatencyArgs* sl = (SemaphoreLatencyArgs*) ptr;
       
   291 	sl->ChildOpen();
       
   292 	for (TBMUInt64 i = 0; i < sl->iIterationCount; ++i)
       
   293 		{
       
   294 		TBMTicks sigTime;
       
   295 		::bmTimer.Stamp(&sigTime);		
       
   296 		sl->iSem.Signal();
       
   297 		sl->ChildSignalTime(sigTime);
       
   298 		}
       
   299 	sl->ChildClose();
       
   300 	return KErrNone;
       
   301 	}
       
   302 
       
   303 class ThreadSemaphoreLatencyArgs : public TBMSpawnArgs
       
   304 	{
       
   305 public:
       
   306 	
       
   307 	TBMUInt64			iIterationCount;
       
   308 	TBMTicks			iSignalTime;
       
   309 	TRequestStatus		iStatus;
       
   310 	TRequestStatus*		iStatusPtr;
       
   311 	RMsgQueue<TBMTicks>	iSignalTimeQue;
       
   312 
       
   313 	ThreadSemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter);
       
   314 
       
   315 	void ChildOpen();
       
   316 	void ChildClose();
       
   317 
       
   318 	TBMTicks SignalTime();
       
   319 	void ChildSignalTime(TBMTicks);
       
   320 
       
   321 	void Close();
       
   322 	};
       
   323 
       
   324 ThreadSemaphoreLatencyArgs::ThreadSemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter) : 
       
   325 	TBMSpawnArgs(Sync::ThreadSemaphoreLatencyChild, KBMPriorityLow, aRemote, sizeof(*this)),
       
   326 	iIterationCount(aIter),
       
   327 	iStatusPtr(&iStatus)
       
   328 
       
   329 	{
       
   330 	TInt r = iSignalTimeQue.CreateGlobal(_L("BM Queue"), 1);
       
   331 	BM_ERROR(r, r == KErrNone);
       
   332 	}
       
   333 
       
   334 void ThreadSemaphoreLatencyArgs::ChildOpen()
       
   335 	{
       
   336 	if (iRemote)
       
   337 		{
       
   338 		TInt r = iSignalTimeQue.OpenGlobal(_L("BM Queue"));
       
   339 		BM_ERROR(r, r == KErrNone);
       
   340 		}
       
   341 	}
       
   342 
       
   343 void ThreadSemaphoreLatencyArgs::ChildSignalTime(TBMTicks aTime)
       
   344 	{
       
   345 	TInt r = iSignalTimeQue.Send(aTime);
       
   346 	BM_ERROR(r, r == KErrNone);
       
   347 	}
       
   348 
       
   349 TBMTicks ThreadSemaphoreLatencyArgs::SignalTime()
       
   350 	{
       
   351 	TBMTicks time;
       
   352 	iSignalTimeQue.ReceiveBlocking(time);
       
   353 	return time;
       
   354 	}
       
   355 
       
   356 void ThreadSemaphoreLatencyArgs::ChildClose()
       
   357 	{
       
   358 	if (iRemote)
       
   359 		{
       
   360 		iSignalTimeQue.Close();
       
   361 		}
       
   362 	}
       
   363 
       
   364 void ThreadSemaphoreLatencyArgs::Close()
       
   365 	{
       
   366 	iSignalTimeQue.Close();
       
   367 	}
       
   368 
       
   369 void Sync::ThreadSemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
       
   370 	{
       
   371 	ThreadSemaphoreLatencyArgs sl(aRemote, aIter);
       
   372 	MBMChild* child = sync.SpawnChild(&sl);
       
   373 	for (TBMUInt64 i = 0; i < aIter; ++i)
       
   374 		{
       
   375 		sl.iStatus = KRequestPending;
       
   376 		User::WaitForRequest(sl.iStatus);
       
   377 		BM_ASSERT(sl.iStatus == KErrNone);
       
   378 		TBMTicks now;
       
   379 		::bmTimer.Stamp(&now);
       
   380 		aResult->Cumulate(TBMTicksDelta(sl.SignalTime(), now));
       
   381 		}
       
   382 	child->WaitChildExit();
       
   383 	sl.Close();
       
   384 	}
       
   385 
       
   386 TInt Sync::ThreadSemaphoreLatencyChild(TAny* ptr)
       
   387 	{
       
   388 	ThreadSemaphoreLatencyArgs* sl = (ThreadSemaphoreLatencyArgs*) ptr;
       
   389 	sl->ChildOpen();
       
   390 	for (TBMUInt64 i = 0; i < sl->iIterationCount; ++i)
       
   391 		{
       
   392 		TRequestStatus* sptr = sl->iStatusPtr;
       
   393 		TBMTicks sigTime;
       
   394 		::bmTimer.Stamp(&sigTime);		
       
   395 		sl->iParent.RequestComplete(sptr, KErrNone);
       
   396 		sl->ChildSignalTime(sigTime);
       
   397 		}
       
   398 	sl->ChildClose();
       
   399 	return KErrNone;
       
   400 	}
       
   401 
       
   402 						
       
   403 TBMResult* Sync::Run(TBMUInt64 aIter, TInt* aCount)
       
   404 	{
       
   405 	TInt count = sizeof(iResults)/sizeof(iResults[0]);
       
   406 
       
   407 	for (TInt i = 0; i < count; ++i)
       
   408 		{
       
   409 		iResults[i].Reset(iMeasurements[i].iName);
       
   410 		iMeasurements[i].iFunc(&iResults[i], aIter, iMeasurements[i].iRemote);
       
   411 		iResults[i].Update();
       
   412 		}
       
   413 	
       
   414 	*aCount = count;
       
   415 	return iResults;
       
   416 	}
       
   417 
       
   418 void AddSync()
       
   419 	{
       
   420 	BMProgram* next = bmSuite;
       
   421 	bmSuite=(BMProgram*)&sync;
       
   422 	bmSuite->Next()=next;
       
   423 	}