1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/benchmark/sync.cpp Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,423 @@
1.4 +// Copyright (c) 2002-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 +//
1.18 +
1.19 +#include <e32test.h>
1.20 +#include <e32msgqueue.h>
1.21 +
1.22 +#include "bm_suite.h"
1.23 +
1.24 +class Sync : public BMProgram
1.25 + {
1.26 +public :
1.27 + Sync() : BMProgram(_L("Synchronization Primitives"))
1.28 + {}
1.29 + virtual TBMResult* Run(TBMUInt64 aIter, TInt* aCount);
1.30 +
1.31 + typedef void (*MeasurementFunc)(TBMResult*, TBMUInt64 aIter, TBool aRemote);
1.32 + struct Measurement
1.33 + {
1.34 + MeasurementFunc iFunc;
1.35 + TPtrC iName;
1.36 + TBool iRemote;
1.37 +
1.38 + Measurement(MeasurementFunc aFunc, const TDesC& aName, TBool aRemote = EFalse) :
1.39 + iFunc(aFunc), iName(aName), iRemote(aRemote) {}
1.40 + };
1.41 +
1.42 + static TBMResult iResults[];
1.43 + static Measurement iMeasurements[];
1.44 +
1.45 + static void MutexPassing(TBMResult*, TBMUInt64 aIter, TBool aRemote);
1.46 + static void MutexContentionParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote);
1.47 + static TInt MutexContentionChild(TAny*);
1.48 + static void SemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote);
1.49 + static TInt SemaphoreLatencyChild(TAny*);
1.50 + static void ThreadSemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote);
1.51 + static TInt ThreadSemaphoreLatencyChild(TAny*);
1.52 + };
1.53 +
1.54 +Sync::Measurement Sync::iMeasurements[] =
1.55 + {
1.56 + Measurement(&Sync::MutexPassing, _L("Mutex Passing Case")),
1.57 + Measurement(&Sync::MutexContentionParent, _L("Local Mutex Contention")),
1.58 + Measurement(&Sync::MutexContentionParent, _L("Remote Mutex Contention"), ETrue),
1.59 + Measurement(&Sync::SemaphoreLatencyParent, _L("Local Semaphore Latency")),
1.60 + Measurement(&Sync::SemaphoreLatencyParent, _L("Remote Semaphore Latency"), ETrue),
1.61 + Measurement(&Sync::ThreadSemaphoreLatencyParent, _L("Local Thread Semaphore Latency")),
1.62 + };
1.63 +TBMResult Sync::iResults[sizeof(Sync::iMeasurements)/sizeof(Sync::iMeasurements[0])];
1.64 +
1.65 +static Sync sync;
1.66 +
1.67 +void Sync::MutexPassing(TBMResult* aResult, TBMUInt64 aIter, TBool)
1.68 + {
1.69 + RMutex mutex;
1.70 + mutex.CreateLocal();
1.71 +
1.72 + TBMTimeInterval ti;
1.73 + ti.Begin();
1.74 + for (TBMUInt64 i = 0; i < aIter; ++i)
1.75 + {
1.76 + mutex.Wait();
1.77 + mutex.Signal();
1.78 + }
1.79 + TBMTicks t = ti.End();
1.80 +
1.81 + mutex.Close();
1.82 +
1.83 + aResult->Cumulate(t, aIter);
1.84 + }
1.85 +
1.86 +class MutexContentionArgs : public TBMSpawnArgs
1.87 + {
1.88 +public:
1.89 +
1.90 + RMutex iMutexA;
1.91 + RMutex iMutexB;
1.92 + RSemaphore iSem;
1.93 + TBMUInt64 iIterationCount;
1.94 +
1.95 + MutexContentionArgs(TInt aRemote, TBMUInt64 aIter);
1.96 +
1.97 + void ChildOpen();
1.98 + void ChildClose();
1.99 +
1.100 + void Close();
1.101 + };
1.102 +
1.103 +MutexContentionArgs::MutexContentionArgs(TInt aRemote, TBMUInt64 aIter) :
1.104 + TBMSpawnArgs(Sync::MutexContentionChild, KBMPriorityLow, aRemote, sizeof(*this)),
1.105 + iIterationCount(aIter)
1.106 + {
1.107 + TInt r;
1.108 + if (aRemote)
1.109 + {
1.110 + r = iMutexA.CreateGlobal(_L("MutexA"));
1.111 + BM_ERROR(r, r == KErrNone);
1.112 + r = iMutexB.CreateGlobal(_L("MutexB"));
1.113 + BM_ERROR(r, r == KErrNone);
1.114 + r = iSem.CreateGlobal(_L("Semaphore"), 0);
1.115 + BM_ERROR(r, r == KErrNone);
1.116 + }
1.117 + else
1.118 + {
1.119 + r = iMutexA.CreateLocal();
1.120 + BM_ERROR(r, r == KErrNone);
1.121 + r = iMutexB.CreateLocal();
1.122 + BM_ERROR(r, r == KErrNone);
1.123 + r = iSem.CreateLocal(0);
1.124 + BM_ERROR(r, r == KErrNone);
1.125 + }
1.126 + }
1.127 +
1.128 +void MutexContentionArgs::ChildOpen()
1.129 + {
1.130 + if (iRemote)
1.131 + {
1.132 + iMutexA.Duplicate(iParent);
1.133 + iMutexB.Duplicate(iParent);
1.134 + iSem.Duplicate(iParent);
1.135 + }
1.136 + }
1.137 +
1.138 +void MutexContentionArgs::ChildClose()
1.139 + {
1.140 + if (iRemote)
1.141 + {
1.142 + iMutexA.Close();
1.143 + iMutexB.Close();
1.144 + iSem.Close();
1.145 + }
1.146 + }
1.147 +
1.148 +void MutexContentionArgs::Close()
1.149 + {
1.150 + iMutexA.Close();
1.151 + iMutexB.Close();
1.152 + iSem.Close();
1.153 + }
1.154 +
1.155 +void Sync::MutexContentionParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
1.156 + {
1.157 + MutexContentionArgs mc(aRemote, aIter);
1.158 +
1.159 + MBMChild* child = sync.SpawnChild(&mc);
1.160 +
1.161 + mc.iSem.Wait();
1.162 +
1.163 + TBMTimeInterval ti;
1.164 + ti.Begin();
1.165 + for (TBMUInt64 i = 0; i < aIter; ++i)
1.166 + {
1.167 + mc.iMutexA.Wait();
1.168 + mc.iMutexA.Signal();
1.169 + mc.iMutexB.Wait();
1.170 + mc.iMutexB.Signal();
1.171 + }
1.172 + TBMTicks t = ti.End();
1.173 +
1.174 + child->WaitChildExit();
1.175 + mc.Close();
1.176 +
1.177 + aResult->Cumulate(t/2, aIter);
1.178 + }
1.179 +
1.180 +TInt Sync::MutexContentionChild(TAny* ptr)
1.181 + {
1.182 + MutexContentionArgs* mc = (MutexContentionArgs*) ptr;
1.183 + mc->ChildOpen();
1.184 +
1.185 + mc->iMutexA.Wait();
1.186 + mc->iSem.Signal();
1.187 + for (TBMUInt64 i = 0; i < mc->iIterationCount; ++i)
1.188 + {
1.189 + mc->iMutexB.Wait();
1.190 + mc->iMutexA.Signal();
1.191 + mc->iMutexA.Wait();
1.192 + mc->iMutexB.Signal();
1.193 + }
1.194 + mc->iMutexA.Signal();
1.195 +
1.196 + mc->ChildClose();
1.197 + return KErrNone;
1.198 + }
1.199 +
1.200 +class SemaphoreLatencyArgs : public TBMSpawnArgs
1.201 + {
1.202 +public:
1.203 +
1.204 + RSemaphore iSem;
1.205 + TBMUInt64 iIterationCount;
1.206 + RMsgQueue<TBMTicks> iSignalTimeQue;
1.207 +
1.208 + SemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter);
1.209 +
1.210 + void ChildOpen();
1.211 + void ChildClose();
1.212 +
1.213 + TBMTicks SignalTime();
1.214 + void ChildSignalTime(TBMTicks);
1.215 +
1.216 + void Close();
1.217 + };
1.218 +
1.219 +SemaphoreLatencyArgs::SemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter) :
1.220 + TBMSpawnArgs(Sync::SemaphoreLatencyChild, KBMPriorityLow, aRemote, sizeof(*this)),
1.221 + iIterationCount(aIter)
1.222 + {
1.223 + TInt r;
1.224 + if (aRemote)
1.225 + {
1.226 + r = iSem.CreateGlobal(_L("BM Semaphore"), 0);
1.227 + BM_ERROR(r, r == KErrNone);
1.228 + }
1.229 + else
1.230 + {
1.231 + r = iSem.CreateLocal(0);
1.232 + BM_ERROR(r, r == KErrNone);
1.233 + }
1.234 + r = iSignalTimeQue.CreateGlobal(_L("BM Queue"), 1);
1.235 + BM_ERROR(r, r == KErrNone);
1.236 + }
1.237 +
1.238 +void SemaphoreLatencyArgs::ChildOpen()
1.239 + {
1.240 + if (iRemote)
1.241 + {
1.242 + iSem.Duplicate(iParent);
1.243 + TInt r = iSignalTimeQue.OpenGlobal(_L("BM Queue"));
1.244 + BM_ERROR(r, r == KErrNone);
1.245 + }
1.246 + }
1.247 +
1.248 +void SemaphoreLatencyArgs::ChildSignalTime(TBMTicks aTime)
1.249 + {
1.250 + TInt r = iSignalTimeQue.Send(aTime);
1.251 + BM_ERROR(r, r == KErrNone);
1.252 + }
1.253 +
1.254 +TBMTicks SemaphoreLatencyArgs::SignalTime()
1.255 + {
1.256 + TBMTicks time;
1.257 + iSignalTimeQue.ReceiveBlocking(time);
1.258 + return time;
1.259 + }
1.260 +
1.261 +void SemaphoreLatencyArgs::ChildClose()
1.262 + {
1.263 + if (iRemote)
1.264 + {
1.265 + iSem.Close();
1.266 + iSignalTimeQue.Close();
1.267 + }
1.268 + }
1.269 +
1.270 +void SemaphoreLatencyArgs::Close()
1.271 + {
1.272 + iSem.Close();
1.273 + iSignalTimeQue.Close();
1.274 + }
1.275 +
1.276 +void Sync::SemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
1.277 + {
1.278 + SemaphoreLatencyArgs sl(aRemote, aIter);
1.279 + MBMChild* child = sync.SpawnChild(&sl);
1.280 + for (TBMUInt64 i = 0; i < aIter; ++i)
1.281 + {
1.282 + sl.iSem.Wait();
1.283 + TBMTicks now;
1.284 + ::bmTimer.Stamp(&now);
1.285 + aResult->Cumulate(TBMTicksDelta(sl.SignalTime(), now));
1.286 + }
1.287 + child->WaitChildExit();
1.288 + sl.Close();
1.289 + }
1.290 +
1.291 +TInt Sync::SemaphoreLatencyChild(TAny* ptr)
1.292 + {
1.293 + SemaphoreLatencyArgs* sl = (SemaphoreLatencyArgs*) ptr;
1.294 + sl->ChildOpen();
1.295 + for (TBMUInt64 i = 0; i < sl->iIterationCount; ++i)
1.296 + {
1.297 + TBMTicks sigTime;
1.298 + ::bmTimer.Stamp(&sigTime);
1.299 + sl->iSem.Signal();
1.300 + sl->ChildSignalTime(sigTime);
1.301 + }
1.302 + sl->ChildClose();
1.303 + return KErrNone;
1.304 + }
1.305 +
1.306 +class ThreadSemaphoreLatencyArgs : public TBMSpawnArgs
1.307 + {
1.308 +public:
1.309 +
1.310 + TBMUInt64 iIterationCount;
1.311 + TBMTicks iSignalTime;
1.312 + TRequestStatus iStatus;
1.313 + TRequestStatus* iStatusPtr;
1.314 + RMsgQueue<TBMTicks> iSignalTimeQue;
1.315 +
1.316 + ThreadSemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter);
1.317 +
1.318 + void ChildOpen();
1.319 + void ChildClose();
1.320 +
1.321 + TBMTicks SignalTime();
1.322 + void ChildSignalTime(TBMTicks);
1.323 +
1.324 + void Close();
1.325 + };
1.326 +
1.327 +ThreadSemaphoreLatencyArgs::ThreadSemaphoreLatencyArgs(TInt aRemote, TBMUInt64 aIter) :
1.328 + TBMSpawnArgs(Sync::ThreadSemaphoreLatencyChild, KBMPriorityLow, aRemote, sizeof(*this)),
1.329 + iIterationCount(aIter),
1.330 + iStatusPtr(&iStatus)
1.331 +
1.332 + {
1.333 + TInt r = iSignalTimeQue.CreateGlobal(_L("BM Queue"), 1);
1.334 + BM_ERROR(r, r == KErrNone);
1.335 + }
1.336 +
1.337 +void ThreadSemaphoreLatencyArgs::ChildOpen()
1.338 + {
1.339 + if (iRemote)
1.340 + {
1.341 + TInt r = iSignalTimeQue.OpenGlobal(_L("BM Queue"));
1.342 + BM_ERROR(r, r == KErrNone);
1.343 + }
1.344 + }
1.345 +
1.346 +void ThreadSemaphoreLatencyArgs::ChildSignalTime(TBMTicks aTime)
1.347 + {
1.348 + TInt r = iSignalTimeQue.Send(aTime);
1.349 + BM_ERROR(r, r == KErrNone);
1.350 + }
1.351 +
1.352 +TBMTicks ThreadSemaphoreLatencyArgs::SignalTime()
1.353 + {
1.354 + TBMTicks time;
1.355 + iSignalTimeQue.ReceiveBlocking(time);
1.356 + return time;
1.357 + }
1.358 +
1.359 +void ThreadSemaphoreLatencyArgs::ChildClose()
1.360 + {
1.361 + if (iRemote)
1.362 + {
1.363 + iSignalTimeQue.Close();
1.364 + }
1.365 + }
1.366 +
1.367 +void ThreadSemaphoreLatencyArgs::Close()
1.368 + {
1.369 + iSignalTimeQue.Close();
1.370 + }
1.371 +
1.372 +void Sync::ThreadSemaphoreLatencyParent(TBMResult* aResult, TBMUInt64 aIter, TBool aRemote)
1.373 + {
1.374 + ThreadSemaphoreLatencyArgs sl(aRemote, aIter);
1.375 + MBMChild* child = sync.SpawnChild(&sl);
1.376 + for (TBMUInt64 i = 0; i < aIter; ++i)
1.377 + {
1.378 + sl.iStatus = KRequestPending;
1.379 + User::WaitForRequest(sl.iStatus);
1.380 + BM_ASSERT(sl.iStatus == KErrNone);
1.381 + TBMTicks now;
1.382 + ::bmTimer.Stamp(&now);
1.383 + aResult->Cumulate(TBMTicksDelta(sl.SignalTime(), now));
1.384 + }
1.385 + child->WaitChildExit();
1.386 + sl.Close();
1.387 + }
1.388 +
1.389 +TInt Sync::ThreadSemaphoreLatencyChild(TAny* ptr)
1.390 + {
1.391 + ThreadSemaphoreLatencyArgs* sl = (ThreadSemaphoreLatencyArgs*) ptr;
1.392 + sl->ChildOpen();
1.393 + for (TBMUInt64 i = 0; i < sl->iIterationCount; ++i)
1.394 + {
1.395 + TRequestStatus* sptr = sl->iStatusPtr;
1.396 + TBMTicks sigTime;
1.397 + ::bmTimer.Stamp(&sigTime);
1.398 + sl->iParent.RequestComplete(sptr, KErrNone);
1.399 + sl->ChildSignalTime(sigTime);
1.400 + }
1.401 + sl->ChildClose();
1.402 + return KErrNone;
1.403 + }
1.404 +
1.405 +
1.406 +TBMResult* Sync::Run(TBMUInt64 aIter, TInt* aCount)
1.407 + {
1.408 + TInt count = sizeof(iResults)/sizeof(iResults[0]);
1.409 +
1.410 + for (TInt i = 0; i < count; ++i)
1.411 + {
1.412 + iResults[i].Reset(iMeasurements[i].iName);
1.413 + iMeasurements[i].iFunc(&iResults[i], aIter, iMeasurements[i].iRemote);
1.414 + iResults[i].Update();
1.415 + }
1.416 +
1.417 + *aCount = count;
1.418 + return iResults;
1.419 + }
1.420 +
1.421 +void AddSync()
1.422 + {
1.423 + BMProgram* next = bmSuite;
1.424 + bmSuite=(BMProgram*)&sync;
1.425 + bmSuite->Next()=next;
1.426 + }