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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
17 #include <e32msgqueue.h>
21 class Sync : public BMProgram
24 Sync() : BMProgram(_L("Synchronization Primitives"))
26 virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount);
28 typedef void (*MeasurementFunc)(TBMResult*, TBMUInt64 aIter, TBool aRemote);
31 MeasurementFunc iFunc;
35 Measurement(MeasurementFunc aFunc, const TDesC& aName, TBool aRemote = EFalse) :
36 iFunc(aFunc), iName(aName), iRemote(aRemote) {}
39 static TBMResult iResults[];
40 static Measurement iMeasurements[];
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*);
51 Sync::Measurement Sync::iMeasurements[] =
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")),
60 TBMResult Sync::iResults[sizeof(Sync::iMeasurements)/sizeof(Sync::iMeasurements[0])];
64 void Sync::MutexPassing(TBMResult* aResult, TBMUInt64 aIter, TBool)
71 for (TBMUInt64 i = 0; i < aIter; ++i)
76 TBMTicks t = ti.End();
80 aResult->Cumulate(t, aIter);
83 class MutexContentionArgs : public TBMSpawnArgs
90 TBMUInt64 iIterationCount;
92 MutexContentionArgs(TInt aRemote, TBMUInt64 aIter);
100 MutexContentionArgs::MutexContentionArgs(TInt aRemote, TBMUInt64 aIter) :
101 TBMSpawnArgs(Sync::MutexContentionChild, KBMPriorityLow, aRemote, sizeof(*this)),
102 iIterationCount(aIter)
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);
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);
125 void MutexContentionArgs::ChildOpen()
129 iMutexA.Duplicate(iParent);
130 iMutexB.Duplicate(iParent);
131 iSem.Duplicate(iParent);
135 void MutexContentionArgs::ChildClose()
145 void MutexContentionArgs::Close()
152 void Sync::MutexContentionParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
154 MutexContentionArgs mc(aRemote, aIter);
156 MBMChild* child = sync.SpawnChild(&mc);
162 for (TBMUInt64 i = 0; i < aIter; ++i)
169 TBMTicks t = ti.End();
171 child->WaitChildExit();
174 aResult->Cumulate(t/2, aIter);
177 TInt Sync::MutexContentionChild(TAny* ptr)
179 MutexContentionArgs* mc = (MutexContentionArgs*) ptr;
184 for (TBMUInt64 i = 0; i < mc->iIterationCount; ++i)
187 mc->iMutexA.Signal();
189 mc->iMutexB.Signal();
191 mc->iMutexA.Signal();
197 class SemaphoreLatencyArgs : public TBMSpawnArgs
202 TBMUInt64 iIterationCount;
203 RMsgQueue<TBMTicks> iSignalTimeQue;
205 SemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter);
210 TBMTicks SignalTime();
211 void ChildSignalTime(TBMTicks);
216 SemaphoreLatencyArgs::SemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter) :
217 TBMSpawnArgs(Sync::SemaphoreLatencyChild, KBMPriorityLow, aRemote, sizeof(*this)),
218 iIterationCount(aIter)
223 r = iSem.CreateGlobal(_L("BM Semaphore"), 0);
224 BM_ERROR(r, r == KErrNone);
228 r = iSem.CreateLocal(0);
229 BM_ERROR(r, r == KErrNone);
231 r = iSignalTimeQue.CreateGlobal(_L("BM Queue"), 1);
232 BM_ERROR(r, r == KErrNone);
235 void SemaphoreLatencyArgs::ChildOpen()
239 iSem.Duplicate(iParent);
240 TInt r = iSignalTimeQue.OpenGlobal(_L("BM Queue"));
241 BM_ERROR(r, r == KErrNone);
245 void SemaphoreLatencyArgs::ChildSignalTime(TBMTicks aTime)
247 TInt r = iSignalTimeQue.Send(aTime);
248 BM_ERROR(r, r == KErrNone);
251 TBMTicks SemaphoreLatencyArgs::SignalTime()
254 iSignalTimeQue.ReceiveBlocking(time);
258 void SemaphoreLatencyArgs::ChildClose()
263 iSignalTimeQue.Close();
267 void SemaphoreLatencyArgs::Close()
270 iSignalTimeQue.Close();
273 void Sync::SemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
275 SemaphoreLatencyArgs sl(aRemote, aIter);
276 MBMChild* child = sync.SpawnChild(&sl);
277 for (TBMUInt64 i = 0; i < aIter; ++i)
281 ::bmTimer.Stamp(&now);
282 aResult->Cumulate(TBMTicksDelta(sl.SignalTime(), now));
284 child->WaitChildExit();
288 TInt Sync::SemaphoreLatencyChild(TAny* ptr)
290 SemaphoreLatencyArgs* sl = (SemaphoreLatencyArgs*) ptr;
292 for (TBMUInt64 i = 0; i < sl->iIterationCount; ++i)
295 ::bmTimer.Stamp(&sigTime);
297 sl->ChildSignalTime(sigTime);
303 class ThreadSemaphoreLatencyArgs : public TBMSpawnArgs
307 TBMUInt64 iIterationCount;
308 TBMTicks iSignalTime;
309 TRequestStatus iStatus;
310 TRequestStatus* iStatusPtr;
311 RMsgQueue<TBMTicks> iSignalTimeQue;
313 ThreadSemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter);
318 TBMTicks SignalTime();
319 void ChildSignalTime(TBMTicks);
324 ThreadSemaphoreLatencyArgs::ThreadSemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter) :
325 TBMSpawnArgs(Sync::ThreadSemaphoreLatencyChild, KBMPriorityLow, aRemote, sizeof(*this)),
326 iIterationCount(aIter),
330 TInt r = iSignalTimeQue.CreateGlobal(_L("BM Queue"), 1);
331 BM_ERROR(r, r == KErrNone);
334 void ThreadSemaphoreLatencyArgs::ChildOpen()
338 TInt r = iSignalTimeQue.OpenGlobal(_L("BM Queue"));
339 BM_ERROR(r, r == KErrNone);
343 void ThreadSemaphoreLatencyArgs::ChildSignalTime(TBMTicks aTime)
345 TInt r = iSignalTimeQue.Send(aTime);
346 BM_ERROR(r, r == KErrNone);
349 TBMTicks ThreadSemaphoreLatencyArgs::SignalTime()
352 iSignalTimeQue.ReceiveBlocking(time);
356 void ThreadSemaphoreLatencyArgs::ChildClose()
360 iSignalTimeQue.Close();
364 void ThreadSemaphoreLatencyArgs::Close()
366 iSignalTimeQue.Close();
369 void Sync::ThreadSemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
371 ThreadSemaphoreLatencyArgs sl(aRemote, aIter);
372 MBMChild* child = sync.SpawnChild(&sl);
373 for (TBMUInt64 i = 0; i < aIter; ++i)
375 sl.iStatus = KRequestPending;
376 User::WaitForRequest(sl.iStatus);
377 BM_ASSERT(sl.iStatus == KErrNone);
379 ::bmTimer.Stamp(&now);
380 aResult->Cumulate(TBMTicksDelta(sl.SignalTime(), now));
382 child->WaitChildExit();
386 TInt Sync::ThreadSemaphoreLatencyChild(TAny* ptr)
388 ThreadSemaphoreLatencyArgs* sl = (ThreadSemaphoreLatencyArgs*) ptr;
390 for (TBMUInt64 i = 0; i < sl->iIterationCount; ++i)
392 TRequestStatus* sptr = sl->iStatusPtr;
394 ::bmTimer.Stamp(&sigTime);
395 sl->iParent.RequestComplete(sptr, KErrNone);
396 sl->ChildSignalTime(sigTime);
403 TBMResult* Sync::Run(TBMUInt64 aIter, TInt* aCount)
405 TInt count = sizeof(iResults)/sizeof(iResults[0]);
407 for (TInt i = 0; i < count; ++i)
409 iResults[i].Reset(iMeasurements[i].iName);
410 iMeasurements[i].iFunc(&iResults[i], aIter, iMeasurements[i].iRemote);
411 iResults[i].Update();
420 BMProgram* next = bmSuite;
421 bmSuite=(BMProgram*)&sync;
422 bmSuite->Next()=next;