kerneltest/e32test/prime/t_semutx.cpp
changeset 201 43365a9b78a3
parent 152 657f875b013e
child 257 3e88ff8f41d5
equal deleted inserted replaced
200:73ea206103e6 201:43365a9b78a3
    38 // 
    38 // 
    39 //
    39 //
    40 
    40 
    41 #define __E32TEST_EXTENSION__
    41 #define __E32TEST_EXTENSION__
    42 #include <e32test.h>
    42 #include <e32test.h>
    43 #include <u32std.h>
    43 #include <hal.h>
       
    44 #include <e32atomics.h>
       
    45 #include <u32hal.h>
    44 #include <e32svr.h>
    46 #include <e32svr.h>
    45 
    47 
    46 const TInt KMaxBufferSize=10;
    48 const TInt KMaxBufferSize=10;
    47 const TInt KMaxArraySize=10;
    49 const TInt KMaxArraySize=10;
    48 const TInt KNumProducerItems=100;
    50 const TInt KNumProducerItems=100;
    49 
    51 
    50 enum {EThread1ID=1,EThread2ID};
    52 enum {EThread1ID=1,EThread2ID};
    51 
    53 
    52 RTest test(_L("T_SEMUTX"));
    54 RTest test(_L("T_SEMUTX"));
    53 RMutex mutex;
    55 RMutex mutex;
    54 RCriticalSection criticalSn;	
    56 RCriticalSection criticalSn;
    55 TInt thread1Count,thread2Count;
    57 TInt thread1Count,thread2Count;
    56 TInt arrayIndex;
    58 TInt arrayIndex;
    57 TInt array[KMaxArraySize];  
    59 TInt array[KMaxArraySize];
    58 TInt consumerArray[KNumProducerItems];
    60 TInt consumerArray[KNumProducerItems];
    59 RSemaphore slotAvailable,itemAvailable;  
    61 RSemaphore slotAvailable,itemAvailable;
       
    62 TBool doCpuLocking = EFalse;
       
    63 
       
    64 // return num of cpus in system
       
    65 TInt NumCpus()
       
    66 	{
       
    67 	TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
       
    68 	return r;
       
    69 	}
       
    70 
       
    71 
       
    72 TInt LockCurrentThreadToCpu0(TBool aCallingIsMainTestThread = EFalse)
       
    73 	{
       
    74 	if (aCallingIsMainTestThread) 
       
    75 		{
       
    76 		if (NumCpus() > 1) 
       
    77 			{
       
    78 			doCpuLocking = ETrue;
       
    79 			return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, 0, 0); 
       
    80 			}
       
    81 		else
       
    82 			{
       
    83 			return KErrNone;
       
    84 			}
       
    85 		}
       
    86 	return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, 0, 0); 
       
    87 	}
       
    88 
       
    89 TInt UnlockCurrentThreadToCpu0(TBool aCallingIsMainTestThread = EFalse)
       
    90 	{
       
    91 	if (aCallingIsMainTestThread) 
       
    92 		{
       
    93 		if (NumCpus() > 1) 
       
    94 			{
       
    95 			doCpuLocking = EFalse;
       
    96 			return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny*) 0xffffffffu, 0); 
       
    97 			}
       
    98 		else
       
    99 			{
       
   100 			return KErrNone;
       
   101 			}
       
   102 		}
       
   103 	return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny*) 0xffffffffu, 0); 
       
   104 	}
       
   105 
       
   106 
       
   107 /******************************************************************************
       
   108  * Random Number Generation
       
   109  ******************************************************************************/
       
   110 void Random(TUint64& a)
       
   111 	{
       
   112 	TInt i;
       
   113 	for (i=64; i>0; --i)
       
   114 		{
       
   115 		TUint64 x = a<<1;
       
   116 		TUint64 y = x<<1;
       
   117 		x^=y;
       
   118 		a = (y>>1) | (x>>63);
       
   119 		}
       
   120 	}
       
   121 
       
   122 // Returns 256*log2(a/2^64)
       
   123 TInt Log2(TUint64 a)
       
   124 	{
       
   125 	const TUint64 KBit63 = UI64LIT(0x8000000000000000);
       
   126 	TInt n = __e32_find_ms1_64(a);
       
   127 	a <<= (63-n);
       
   128 	n -= 64;
       
   129 	TInt i;
       
   130 	for (i=0; i<8; ++i)
       
   131 		{
       
   132 		a >>= 32;
       
   133 		a *= a;
       
   134 		n <<= 1;
       
   135 		if (a & KBit63)
       
   136 			{
       
   137 			++n;
       
   138 			}
       
   139 		else
       
   140 			{
       
   141 			a <<= 1;
       
   142 			}
       
   143 		}
       
   144 	return n;
       
   145 	}
       
   146 
       
   147 TUint32 ExpRV(TUint64 aU, TUint32 aMean, TUint32 aTick)
       
   148 	{
       
   149 	TInt n = -Log2(aU);
       
   150 	TUint64 x = TUint64(n) * TUint64(aMean);
       
   151 	x *= TUint64(22713);	// 2^15 * ln2
       
   152 	TUint64 p(aTick);
       
   153 	p <<= 22;
       
   154 	x += p;
       
   155 	p += p;
       
   156 	x /= p;
       
   157 	return I64LOW(x);
       
   158 	}
       
   159 
       
   160 
       
   161 
       
   162 /*----------------------------------------------------------------------------*/
       
   163 class MLock
       
   164 	{
       
   165 public:
       
   166 	enum {EPollable=1, ETimeoutAvail=2, ENestable=4, ELimit1=8, ELooseTimeout=16};
       
   167 public:
       
   168 	virtual TInt Flags()=0;
       
   169 	virtual void Release()=0;
       
   170 	virtual void Wait()=0;
       
   171 	virtual void Signal()=0;
       
   172 	virtual TInt Wait(TInt aTimeout);
       
   173 	virtual TInt Poll();
       
   174 	};
       
   175 
       
   176 TInt MLock::Wait(TInt)
       
   177 	{ return KErrNotSupported; }
       
   178 TInt MLock::Poll()
       
   179 	{ return KErrNotSupported; }
       
   180 
       
   181 /*----------------------------------------------------------------------------*/
       
   182 class LockS : public MLock
       
   183 	{
       
   184 public:
       
   185 	LockS();
       
   186 	virtual TInt Flags();
       
   187 	virtual void Release();
       
   188 	virtual void Wait();
       
   189 	virtual void Signal();
       
   190 	virtual TInt Wait(TInt aTimeout);
       
   191 	virtual TInt Poll();
       
   192 public:
       
   193 	RSemaphore	iT;
       
   194 	};
       
   195 
       
   196 LockS::LockS()
       
   197 	{ test_KErrNone(iT.CreateLocal(1)); }
       
   198 TInt LockS::Flags()
       
   199 	{ return EPollable|ETimeoutAvail; }
       
   200 void LockS::Release()
       
   201 	{ iT.Close(); }
       
   202 void LockS::Wait()
       
   203 	{ iT.Wait(); }
       
   204 void LockS::Signal()
       
   205 	{ iT.Signal(); }
       
   206 TInt LockS::Wait(TInt aTimeout)
       
   207 	{ return iT.Wait(aTimeout); }
       
   208 TInt LockS::Poll()
       
   209 	{ return iT.Poll(); }
       
   210 
       
   211 /*----------------------------------------------------------------------------*/
       
   212 class LockM : public MLock
       
   213 	{
       
   214 public:
       
   215 	LockM();
       
   216 	virtual TInt Flags();
       
   217 	virtual void Release();
       
   218 	virtual void Wait();
       
   219 	virtual void Signal();
       
   220 	virtual TInt Wait(TInt aTimeout);
       
   221 	virtual TInt Poll();
       
   222 public:
       
   223 	RMutex		iT;
       
   224 	};
       
   225 
       
   226 LockM::LockM()
       
   227 	{ test_KErrNone(iT.CreateLocal()); }
       
   228 TInt LockM::Flags()
       
   229 	{ return EPollable|ETimeoutAvail|ENestable|ELimit1; }
       
   230 void LockM::Release()
       
   231 	{ iT.Close(); }
       
   232 void LockM::Wait()
       
   233 	{ iT.Wait(); }
       
   234 void LockM::Signal()
       
   235 	{ iT.Signal(); }
       
   236 TInt LockM::Wait(TInt aTimeout)
       
   237 	{ return iT.Wait(aTimeout); }
       
   238 TInt LockM::Poll()
       
   239 	{ return iT.Poll(); }
       
   240 
       
   241 /*----------------------------------------------------------------------------*/
       
   242 
       
   243 class LockFL : public MLock
       
   244 	{
       
   245 public:
       
   246 	LockFL();
       
   247 	virtual TInt Flags();
       
   248 	virtual void Release();
       
   249 	virtual void Wait();
       
   250 	virtual void Signal();
       
   251 	virtual TInt Wait(TInt aTimeout);
       
   252 	virtual TInt Poll();
       
   253 public:
       
   254 	RFastLock	iT;
       
   255 	};
       
   256 
       
   257 LockFL::LockFL()
       
   258 	{ test_KErrNone(iT.CreateLocal()); }
       
   259 TInt LockFL::Flags()
       
   260 	{ return ETimeoutAvail|EPollable|ELimit1|ELooseTimeout; }
       
   261 void LockFL::Release()
       
   262 	{ iT.Close(); }
       
   263 void LockFL::Wait()
       
   264 	{ iT.Wait(); }
       
   265 void LockFL::Signal()
       
   266 	{ iT.Signal(); }
       
   267 TInt LockFL::Wait(TInt aTimeout)
       
   268 	{ return iT.Wait(aTimeout); }
       
   269 TInt LockFL::Poll()
       
   270 	{ return iT.Poll(); }
       
   271 
       
   272 /*----------------------------------------------------------------------------*/
       
   273 class LockCS : public MLock
       
   274 	{
       
   275 public:
       
   276 	LockCS();
       
   277 	virtual TInt Flags();
       
   278 	virtual void Release();
       
   279 	virtual void Wait();
       
   280 	virtual void Signal();
       
   281 public:
       
   282 	RCriticalSection iT;
       
   283 	};
       
   284 
       
   285 LockCS::LockCS()
       
   286 	{ test_KErrNone(iT.CreateLocal()); }
       
   287 TInt LockCS::Flags()
       
   288 	{ return ELimit1; }
       
   289 void LockCS::Release()
       
   290 	{ iT.Close(); }
       
   291 void LockCS::Wait()
       
   292 	{ iT.Wait(); }
       
   293 void LockCS::Signal()
       
   294 	{ iT.Signal(); }
       
   295 
       
   296 
    60 			 
   297 			 
       
   298 /*----------------------------------------------------------------------------*/
       
   299 class LFSR
       
   300 	{
       
   301 public:
       
   302 	LFSR(TInt aBits, TInt aTap2, TInt aTap3=0, TInt aTap4=0);
       
   303 	~LFSR();
       
   304 	void Step();
       
   305 	void Step(TInt aSteps);
       
   306 	TBool operator==(const LFSR& a) const;
       
   307 public:
       
   308 	TUint32* iData;
       
   309 	TInt iBits;
       
   310 	TInt iTap2;
       
   311 	TInt iTap3;
       
   312 	TInt iTap4;
       
   313 	TInt iNW;
       
   314 	TInt iSh1;
       
   315 	TInt iIx2;
       
   316 	TInt iSh2;
       
   317 	TInt iIx3;
       
   318 	TInt iSh3;
       
   319 	TInt iIx4;
       
   320 	TInt iSh4;
       
   321 	};
       
   322 
       
   323 LFSR::LFSR(TInt aBits, TInt aTap2, TInt aTap3, TInt aTap4)
       
   324 	{
       
   325 	iBits = aBits;
       
   326 	iTap2 = aTap2;
       
   327 	iTap3 = aTap3;
       
   328 	iTap4 = aTap4;
       
   329 	iNW = (aBits + 31) >> 5;
       
   330 	iData = (TUint32*)User::AllocZ(iNW*sizeof(TUint32));
       
   331 	test(iData!=0);
       
   332 	iData[0] = 1;
       
   333 	iSh1 = (aBits-1)&31;
       
   334 	iIx2 = (iTap2-1)>>5;
       
   335 	iSh2 = (iTap2-1)&31;
       
   336 	if (iTap3)
       
   337 		{
       
   338 		iIx3 = (iTap3-1)>>5;
       
   339 		iSh3 = (iTap3-1)&31;
       
   340 		}
       
   341 	else
       
   342 		{
       
   343 		iIx3 = -1;
       
   344 		iSh3 = 0;
       
   345 		}
       
   346 	if (iTap4)
       
   347 		{
       
   348 		iIx4 = (iTap4-1)>>5;
       
   349 		iSh4 = (iTap4-1)&31;
       
   350 		}
       
   351 	else
       
   352 		{
       
   353 		iIx4 = -1;
       
   354 		iSh4 = 0;
       
   355 		}
       
   356 	}
       
   357 
       
   358 LFSR::~LFSR()
       
   359 	{
       
   360 	User::Free(iData);
       
   361 	}
       
   362 
       
   363 void LFSR::Step(TInt aSteps)
       
   364 	{
       
   365 	while (aSteps--)
       
   366 		Step();
       
   367 	}
       
   368 
       
   369 void LFSR::Step()
       
   370 	{
       
   371 	TUint32 b = iData[iNW-1]>>iSh1;
       
   372 	b ^= (iData[iIx2]>>iSh2);
       
   373 	if (iIx3>=0)
       
   374 		b ^= (iData[iIx3]>>iSh3);
       
   375 	if (iIx4>=0)
       
   376 		b ^= (iData[iIx4]>>iSh4);
       
   377 	b &= 1;
       
   378 	TInt i;
       
   379 	for (i=0; i<iNW; ++i)
       
   380 		{
       
   381 		TUint32 bb = iData[i] >> 31;
       
   382 		iData[i] = (iData[i]<<1)|b;
       
   383 		b = bb;
       
   384 		}
       
   385 	iData[iNW-1] &= ((2u<<iSh1)-1u);
       
   386 	}
       
   387 
       
   388 TBool LFSR::operator==(const LFSR& a) const
       
   389 	{
       
   390 	if (iBits!=a.iBits || iTap2!=a.iTap2 || iTap3!=a.iTap3 || iTap4!=a.iTap4 || iNW!=a.iNW)
       
   391 		return EFalse;
       
   392 	if (iData==a.iData)
       
   393 		return ETrue;
       
   394 	if (memcompare((const TUint8*)iData, iNW, (const TUint8*)a.iData, a.iNW))
       
   395 		return EFalse;
       
   396 	return ETrue;
       
   397 	}
       
   398 
       
   399 
       
   400 
       
   401 /*----------------------------------------------------------------------------*/
    61 class CStack
   402 class CStack
    62 	{
   403 	{
    63 public:	   
   404 public:	   
    64 	CStack() {iCount=0;};
   405 	CStack() {iCount=0;};
    65 	void Push(TInt aItem) {iStack[iCount++]=aItem;};
   406 	void Push(TInt aItem) {iStack[iCount++]=aItem;};
   116 TInt MutexThreadEntryPoint1(TAny*)
   457 TInt MutexThreadEntryPoint1(TAny*)
   117 //
   458 //
   118 // Mutex test thread 1
   459 // Mutex test thread 1
   119 //
   460 //
   120 	{	
   461 	{	
       
   462 	TInt n = NumCpus();
   121 
   463 
   122 	thread1Count=0;
   464 	thread1Count=0;
   123 	TBool running=ETrue;
   465 	TBool running=ETrue;
   124 	do
   466 	do
   125 		{
   467 		{
   131 			thread1Count++;
   473 			thread1Count++;
   132 			}
   474 			}
   133 		else
   475 		else
   134 			running=EFalse;
   476 			running=EFalse;
   135 		mutex.Signal();
   477 		mutex.Signal();
       
   478 
       
   479 		if (n > 1) 
       
   480 			{
       
   481 			// when the mutex is singaled, due to priority balancing, the other
       
   482 			// thread will be scheduled to run on a CPU other than this one. The delay
       
   483 			// in getting that thread to run means that this one can manage to re-claim the 
       
   484 			// mutex before the other thread gets to run. So we add a small delay here 
       
   485 			User::After(100); 
       
   486 			}
       
   487 
   136 		} while (running);
   488 		} while (running);
   137 	return(KErrNone);
   489 	return(KErrNone);
   138 	}
   490 	}
   139 
   491 
   140 TInt MutexThreadEntryPoint2(TAny*)
   492 TInt MutexThreadEntryPoint2(TAny*)
   141 //
   493 //
   142 // Mutex test thread 2
   494 // Mutex test thread 2
   143 //
   495 //
   144 	{
   496 	{
       
   497 	TInt n = NumCpus();
   145 
   498 
   146 	thread2Count=0;
   499 	thread2Count=0;
   147 	TBool running=ETrue;
   500 	TBool running=ETrue;
   148 	do
   501 	do
   149 		{
   502 		{
   155 			thread2Count++;
   508 			thread2Count++;
   156 			}
   509 			}
   157 		else
   510 		else
   158 			running=EFalse;
   511 			running=EFalse;
   159 		mutex.Signal();
   512 		mutex.Signal();
       
   513 
       
   514 		if (n > 1) 
       
   515 			{
       
   516 			// when the mutex is singaled, due to priority balancing, the other
       
   517 			// thread will be scheduled to run on a CPU other than this one. The delay
       
   518 			// in getting that thread to run means that this one can manage to re-claim the 
       
   519 			// mutex before the other thread gets to run. So we add a small delay here 
       
   520 			User::After(100); 
       
   521 			}
       
   522 		
       
   523 
   160 		} while (running);
   524 		} while (running);
   161 	return(KErrNone);
   525 	return(KErrNone);
   162 	}
   526 	}
   163 
   527 
   164 TInt CriticalSnThreadEntryPoint1(TAny*)
   528 TInt CriticalSnThreadEntryPoint1(TAny*)
   207 		criticalSn.Signal();
   571 		criticalSn.Signal();
   208 		} while (running);
   572 		} while (running);
   209 	return(KErrNone);
   573 	return(KErrNone);
   210 	}
   574 	}
   211 
   575 
   212 struct SWaitSem
   576 
   213 	{
   577 /*----------------------------------------------------------------------------*/
   214 	RSemaphore iSem;
   578 struct SWaitLock
       
   579 	{
       
   580 	enum {EDummy=-2, EPoll=-1, EInfinite=0};
       
   581 
       
   582 	static TInt WaitLockThread(TAny*);
       
   583 	void Start(RThread& aT, TThreadPriority aP=EPriorityLess);
       
   584 	void Wait(RThread& aT, TInt aResult);
       
   585 	TInt DoTest2(RThread& aT, TInt aTimeout, TInt aResult, TThreadPriority aP=EPriorityLess);
       
   586 	void Test2();
       
   587 	void TestSignalled();
       
   588 	void TestNotSignalled();
       
   589 	void TestState();
       
   590 
       
   591 
       
   592 	MLock* iLock;
   215 	TInt iTimeout;
   593 	TInt iTimeout;
   216 	};
   594 	};
   217 
   595 
   218 TInt WaitSemThread(TAny* a)
   596 TInt SWaitLock::WaitLockThread(TAny* a)
   219 	{
   597 	{
   220 	SWaitSem& ws = *(SWaitSem*)a;
   598 	
   221 	return ws.iSem.Wait(ws.iTimeout);
   599 	if (doCpuLocking)
   222 	}
   600 		{
   223 
   601 		TInt r = LockCurrentThreadToCpu0();
   224 void StartWaitSemThread(RThread& aT, SWaitSem& aW, TThreadPriority aP=EPriorityLess)
   602 		if (KErrNone!=r) return r;
   225 	{
   603 		// Rendevous was requested
   226 	TInt r = aT.Create(KNullDesC, &WaitSemThread, 0x1000, 0x1000, 0x1000, &aW);
   604 		RThread::Rendezvous(KErrNone);
       
   605 		}
       
   606 	
       
   607 	SWaitLock& w = *(SWaitLock*)a;
       
   608 	TInt lfl = w.iLock->Flags();
       
   609 	TBool limit1 = lfl & MLock::ELimit1;
       
   610 	TInt r;
       
   611 	switch (w.iTimeout)
       
   612 		{
       
   613 		case EDummy:
       
   614 			return KErrNone;
       
   615 		case EPoll:
       
   616 			r = w.iLock->Poll();
       
   617 			break;
       
   618 		case EInfinite:
       
   619 			w.iLock->Wait();
       
   620 			r = KErrNone;
       
   621 			break;
       
   622 		default:
       
   623 			r = w.iLock->Wait(w.iTimeout);
       
   624 			break;
       
   625 		}
       
   626 	if (limit1 && r==KErrNone)
       
   627 		w.iLock->Signal();
       
   628 	return r;
       
   629 	}
       
   630 
       
   631 void SWaitLock::Start(RThread& aT, TThreadPriority aP)
       
   632 	{
       
   633 	TRequestStatus st;
       
   634 	TInt r = aT.Create(KNullDesC, &WaitLockThread, 0x1000, 0x1000, 0x1000, this);
   227 	test_KErrNone(r);
   635 	test_KErrNone(r);
   228 	aT.SetPriority(aP);
   636 	aT.SetPriority(aP);
       
   637 	if (doCpuLocking) 
       
   638 		{
       
   639 		aT.Rendezvous(st);
       
   640 		}
   229 	aT.Resume();
   641 	aT.Resume();
   230 	}
   642 	if (doCpuLocking) 
   231 
   643 		{
   232 void WaitForWaitSemThread(RThread& aT, TInt aResult)
   644 		User::WaitForRequest(st);
       
   645 		test_KErrNone(st.Int());
       
   646 		}
       
   647 	}
       
   648 
       
   649 void SWaitLock::Wait(RThread& aT, TInt aResult)
   233 	{
   650 	{
   234 	TRequestStatus s;
   651 	TRequestStatus s;
   235 	aT.Logon(s);
   652 	aT.Logon(s);
   236 	User::WaitForRequest(s);
   653 	User::WaitForRequest(s);
   237 	test_Equal(EExitKill, aT.ExitType());
   654 	test_Equal(EExitKill, aT.ExitType());
   238 	test_Equal(aResult, aT.ExitReason());
   655 	test_Equal(aResult, aT.ExitReason());
   239 	test_Equal(aResult, s.Int());
   656 	test_Equal(aResult, s.Int());
   240 	CLOSE_AND_WAIT(aT);
   657 	CLOSE_AND_WAIT(aT);
   241 	}
   658 	}
   242 
   659 
   243 TInt DummyThread(TAny*)
   660 TInt SWaitLock::DoTest2(RThread& aT, TInt aTimeout, TInt aResult, TThreadPriority aP)
   244 	{
   661 	{
   245 	return 0;
       
   246 	}
       
   247 
       
   248 void TestSemaphore2()
       
   249 	{
       
   250 	test.Start(_L("Test semaphore wait with timeout"));
       
   251 	SWaitSem ws;
       
   252 	RThread t;
       
   253 	TTime initial;
   662 	TTime initial;
   254 	TTime final;
   663 	TTime final;
   255 	TInt elapsed=0;
   664 	iTimeout = aTimeout;
   256 	TInt r = ws.iSem.CreateLocal(0);
   665 	initial.HomeTime();
       
   666 	Start(aT, aP);
       
   667 	Wait(aT, aResult);
       
   668 	final.HomeTime();
       
   669 	TInt elapsed = I64INT(final.Int64()-initial.Int64());
       
   670 	return elapsed;
       
   671 	}
       
   672 
       
   673 void SWaitLock::TestSignalled()
       
   674 	{
       
   675 	TInt r = iLock->Poll();
       
   676 	if (r == KErrNotSupported)
       
   677 		r = iLock->Wait(1);
   257 	test_KErrNone(r);
   678 	test_KErrNone(r);
       
   679 	}
       
   680 
       
   681 void SWaitLock::TestNotSignalled()
       
   682 	{
       
   683 	TInt r = iLock->Poll();
       
   684 	if (r == KErrNotSupported)
       
   685 		r = iLock->Wait(1);
       
   686 	test_Equal(KErrTimedOut, r);
       
   687 	}
       
   688 
       
   689 void SWaitLock::TestState()
       
   690 	{
       
   691 	if (iLock->Flags() & MLock::ELimit1)
       
   692 		TestSignalled();	// not signalled afterwards
       
   693 	else
       
   694 		TestNotSignalled();
       
   695 	}
       
   696 
       
   697 void SWaitLock::Test2()
       
   698 	{
       
   699 	test.Start(_L("SWaitLock::Test2"));
       
   700 	RThread t;
       
   701 	RThread t2;
       
   702 	TTime initial;
       
   703 	TTime final;
       
   704 	TInt elapsed = 0;
       
   705 	TInt r = 0;
       
   706 	TInt lfl = iLock->Flags();
       
   707 	TBool nestable = lfl & MLock::ENestable;
       
   708 	TBool limit1 = lfl & MLock::ELimit1;
       
   709 	TBool pollable = lfl & MLock::EPollable;
       
   710 	TBool to = lfl & MLock::ETimeoutAvail;
       
   711 	TBool lto = lfl & MLock::ELooseTimeout;
   258 
   712 
   259 	RThread().SetPriority(EPriorityAbsoluteVeryLow);
   713 	RThread().SetPriority(EPriorityAbsoluteVeryLow);
   260 	TInt threadcount=0;
   714 	TInt threadcount=0;
       
   715 	iTimeout = EDummy;
   261 	initial.HomeTime();
   716 	initial.HomeTime();
   262 	while (elapsed<1000000)
   717 	while (elapsed<1000000)
   263 		{
   718 		{
   264 		r = t.Create(KNullDesC, &DummyThread, 0x1000, NULL, NULL);
   719 		Start(t, EPriorityMore);
   265 		test_KErrNone(r);
   720 		Wait(t, KErrNone);
   266 		t.SetPriority(EPriorityMore);
       
   267 		t.Resume();
       
   268 		t.Close();
       
   269 		++threadcount;
   721 		++threadcount;
   270 		final.HomeTime();
   722 		final.HomeTime();
   271 		elapsed = I64INT(final.Int64()-initial.Int64());
   723 		elapsed = I64INT(final.Int64()-initial.Int64());
   272 		}
   724 		}
   273 	RThread().SetPriority(EPriorityNormal);
   725 	RThread().SetPriority(EPriorityNormal);
   274 	test.Printf(_L("%d threads in 1 sec\n"),threadcount);
   726 	test.Printf(_L("%d threads in 1 sec\n"),threadcount);
   275 	TInt overhead = 1000000/threadcount;
   727 	TInt overhead = 1000000/threadcount;
   276 	test.Printf(_L("overhead = %dus\n"),overhead);
   728 	test.Printf(_L("overhead = %dus\n"),overhead);
   277 
   729 
   278 	ws.iTimeout=1000000;
   730 	iLock->Wait();
   279 	initial.HomeTime();
   731 
   280 	StartWaitSemThread(t, ws);
   732 	if (to)
   281 	WaitForWaitSemThread(t, KErrTimedOut);
   733 		{
   282 	final.HomeTime();
   734 		elapsed = DoTest2(t, 1000000, KErrTimedOut);
   283 	elapsed = I64INT(final.Int64()-initial.Int64());
   735 		test.Printf(_L("Time taken = %dus\n"), elapsed);
   284 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   736 		test(elapsed>=900000+overhead && elapsed<1500000+overhead);
   285 	test(elapsed>=900000+overhead && elapsed<1500000+overhead);
   737 		elapsed = DoTest2(t, -99, KErrArgument);
   286 
   738 		test.Printf(_L("Time taken = %dus\n"), elapsed);
   287 	ws.iTimeout=-1;
   739 		}
   288 	initial.HomeTime();
   740 
   289 	StartWaitSemThread(t, ws);
   741 	if (pollable)
   290 	WaitForWaitSemThread(t, KErrArgument);
   742 		{
   291 	final.HomeTime();
   743 		test.Printf(_L("Testing Poll() function\n"));
   292 	elapsed = I64INT(final.Int64()-initial.Int64());
   744 		r = iLock->Poll();
   293 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   745 		test_Equal((nestable ? KErrNone : KErrTimedOut), r);
   294 
   746 		if (nestable)
   295 	ws.iTimeout=2000000;
   747 			{
   296 	initial.HomeTime();
   748 			iTimeout=EPoll;
   297 	StartWaitSemThread(t, ws);
   749 			r = iLock->Poll();
   298 	User::After(1000000);
   750 			test_KErrNone(r);
   299 	ws.iSem.Signal();
   751 			iLock->Signal();
   300 	WaitForWaitSemThread(t, KErrNone);
   752 			Start(t, EPriorityMore);
   301 	final.HomeTime();
   753 			Wait(t, KErrTimedOut);
   302 	elapsed = I64INT(final.Int64()-initial.Int64());
   754 			}
   303 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   755 		iLock->Signal();
   304 	test(elapsed>=900000+overhead && elapsed<1500000+overhead);
   756 		if (nestable)
   305 
   757 			{
   306 	ws.iTimeout=100000;
   758 			iTimeout=EPoll;
   307 	StartWaitSemThread(t, ws, EPriorityMore);
   759 			r = iLock->Poll();
   308 	t.Suspend();
   760 			test_KErrNone(r);
   309 	ws.iSem.Signal();
   761 			iLock->Signal();
   310 	User::After(200000);
   762 			Start(t, EPriorityMore);
   311 	t.Resume();
   763 			Wait(t, KErrTimedOut);
   312 	WaitForWaitSemThread(t, KErrTimedOut);
   764 			iLock->Signal();
   313 	test_KErrNone(ws.iSem.Wait(1));
   765 			Start(t, EPriorityMore);
   314 
   766 			Wait(t, KErrNone);
   315 	ws.iTimeout=100000;
   767 			}
   316 	StartWaitSemThread(t, ws, EPriorityMore);
   768 		r = iLock->Poll();
   317 	t.Suspend();
   769 		test_KErrNone(r);
   318 	ws.iSem.Signal();
   770 		if (!nestable)
   319 	User::After(50000);
   771 			{
   320 	t.Resume();
   772 			r = iLock->Poll();
   321 	WaitForWaitSemThread(t, KErrNone);
   773 			test_Equal(KErrTimedOut, r);
   322 	test_Equal(KErrTimedOut, ws.iSem.Wait(1));
   774 			iLock->Signal();
   323 
   775 			if (!limit1)
   324 	RThread t2;
   776 				{
   325 	ws.iTimeout=100000;
   777 				iLock->Signal();
   326 	StartWaitSemThread(t, ws, EPriorityMuchMore);
   778 				r = iLock->Poll();
   327 	StartWaitSemThread(t2, ws, EPriorityMore);
   779 				test_KErrNone(r);
   328 	t.Suspend();
   780 				}
   329 	ws.iSem.Signal();
   781 			r = iLock->Poll();
   330 	test_Equal(EExitKill, t2.ExitType());
   782 			test_KErrNone(r);
   331 	test_Equal(EExitPending, t.ExitType());
   783 			r = iLock->Poll();
   332 	t.Resume();
   784 			test_Equal(KErrTimedOut, r);
   333 	WaitForWaitSemThread(t, KErrTimedOut);
   785 			}
   334 	WaitForWaitSemThread(t2, KErrNone);
   786 		elapsed = DoTest2(t, EPoll, KErrTimedOut);
   335 	test_Equal(KErrTimedOut, ws.iSem.Wait(1));
   787 		test.Printf(_L("Time taken = %dus\n"), elapsed);
   336 
   788 		test(elapsed<=50000+3*overhead);
   337 	ws.iTimeout=1000000;
   789 		iLock->Signal();
   338 	initial.HomeTime();
   790 		elapsed = DoTest2(t, EPoll, KErrNone);
   339 	StartWaitSemThread(t2, ws, EPriorityMore);
   791 		test.Printf(_L("Time taken = %dus\n"), elapsed);
   340 	StartWaitSemThread(t, ws, EPriorityMuchMore);
   792 		test(elapsed<=50000+3*overhead);
   341 	ws.iSem.Signal();
   793 		TestState();
   342 	WaitForWaitSemThread(t, KErrNone);
   794 		iLock->Signal();
   343 	final.HomeTime();
   795 		r = LockCurrentThreadToCpu0(ETrue);
   344 	elapsed = I64INT(final.Int64()-initial.Int64());
   796 		test_KErrNone(r);
   345 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   797 		Start(t, EPriorityMuchMore);
   346 	WaitForWaitSemThread(t2, KErrTimedOut);
   798 		Start(t2, EPriorityMore);
   347 	final.HomeTime();
   799 		test_Equal(EExitKill, t2.ExitType());
   348 	elapsed = I64INT(final.Int64()-initial.Int64());
   800 		test_Equal(EExitKill, t.ExitType());
   349 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   801 		Wait(t2, limit1 ? KErrNone : KErrTimedOut);
   350 	test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
   802 		Wait(t, KErrNone);
   351 
   803 		r = UnlockCurrentThreadToCpu0(ETrue);
   352 	ws.iTimeout=1000000;
   804 		test_KErrNone(r);
   353 	initial.HomeTime();
   805 		TestState();
   354 	StartWaitSemThread(t2, ws, EPriorityMore);
   806 		}
   355 	StartWaitSemThread(t, ws, EPriorityMuchMore);
   807 	else
   356 	WaitForWaitSemThread(t, KErrTimedOut);
   808 		{
   357 	final.HomeTime();
   809 		test.Printf(_L("Poll() function not supported\n"));
   358 	elapsed = I64INT(final.Int64()-initial.Int64());
   810 		}
   359 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   811 
   360 	WaitForWaitSemThread(t2, KErrTimedOut);
   812 	if (to)
   361 	final.HomeTime();
   813 		{
   362 	elapsed = I64INT(final.Int64()-initial.Int64());
   814 		iTimeout=2000000;
   363 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   815 		initial.HomeTime();
   364 	test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
   816 		Start(t);
   365 
   817 		User::After(1000000);
   366 	ws.iTimeout=1000000;
   818 		iLock->Signal();
   367 	initial.HomeTime();
   819 		Wait(t, KErrNone);
   368 	StartWaitSemThread(t2, ws, EPriorityMore);
   820 		final.HomeTime();
   369 	StartWaitSemThread(t, ws, EPriorityMuchMore);
   821 		elapsed = I64INT(final.Int64()-initial.Int64());
   370 	t.Kill(299792458);
   822 		test.Printf(_L("Time taken = %dus\n"), elapsed);
   371 	WaitForWaitSemThread(t2, KErrTimedOut);
   823 		test(elapsed>=900000+overhead && elapsed<1500000+overhead);
   372 	WaitForWaitSemThread(t, 299792458);
   824 		TestState();
   373 	final.HomeTime();
   825 
   374 	elapsed = I64INT(final.Int64()-initial.Int64());
   826 		r = LockCurrentThreadToCpu0(ETrue);
   375 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   827 		test_KErrNone(r);
   376 	test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
   828 
   377 
   829 		if (!lto)
   378 	ws.iTimeout=1000000;
   830 			{
   379 	initial.HomeTime();
   831 			iTimeout=100000;
   380 	StartWaitSemThread(t, ws, EPriorityMore);
   832 			Start(t, EPriorityMore);
   381 	StartWaitSemThread(t2, ws, EPriorityMuchMore);
   833 			t.Suspend();
   382 	test_Equal(EExitPending, t.ExitType());
   834 			iLock->Signal();
   383 	test_Equal(EExitPending, t2.ExitType());
   835 			User::After(200000);
   384 	ws.iSem.Close();
   836 			t.Resume();
   385 	test_Equal(EExitKill, t.ExitType());
   837 			Wait(t, KErrTimedOut);
   386 	test_Equal(EExitKill, t2.ExitType());
   838 			TestSignalled();
   387 	WaitForWaitSemThread(t2, KErrGeneral);
   839 
   388 	WaitForWaitSemThread(t, KErrGeneral);
   840 			iTimeout=100000;
   389 	final.HomeTime();
   841 			Start(t, EPriorityMore);
   390 	elapsed = I64INT(final.Int64()-initial.Int64());
   842 			t.Suspend();
   391 	test.Printf(_L("Time taken = %dus\n"), elapsed);
   843 			iLock->Signal();
   392 	test(elapsed<=50000+3*overhead);
   844 			User::After(50000);
   393 
   845 			t.Resume();
       
   846 			Wait(t, KErrNone);
       
   847 			TestState();
       
   848 
       
   849 			iTimeout=100000;
       
   850 			Start(t, EPriorityMuchMore);
       
   851 			Start(t2, EPriorityMore);
       
   852 			t.Suspend();
       
   853 			iLock->Signal();
       
   854 			test_Equal(EExitKill, t2.ExitType());
       
   855 			test_Equal(EExitPending, t.ExitType());
       
   856 			t.Resume();
       
   857 			Wait(t, limit1 ? KErrNone : KErrTimedOut);
       
   858 			Wait(t2, KErrNone);
       
   859 			TestState();
       
   860 			}
       
   861 
       
   862 		iTimeout=1000000;
       
   863 		initial.HomeTime();
       
   864 		Start(t2, EPriorityMore);
       
   865 		Start(t, EPriorityMuchMore);
       
   866 		iLock->Signal();
       
   867 		Wait(t, KErrNone);
       
   868 		final.HomeTime();
       
   869 		elapsed = I64INT(final.Int64()-initial.Int64());
       
   870 		test.Printf(_L("Time taken = %dus\n"), elapsed);
       
   871 		Wait(t2, limit1 ? KErrNone : KErrTimedOut);
       
   872 		final.HomeTime();
       
   873 		elapsed = I64INT(final.Int64()-initial.Int64());
       
   874 		test.Printf(_L("Time taken = %dus\n"), elapsed);
       
   875 		if (!limit1)
       
   876 			{
       
   877 			test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
       
   878 			}
       
   879 		TestState();
       
   880 
       
   881 		iTimeout=1000000;
       
   882 		initial.HomeTime();
       
   883 		Start(t2, EPriorityMore);
       
   884 		Start(t, EPriorityMuchMore);
       
   885 		Wait(t, KErrTimedOut);
       
   886 		final.HomeTime();
       
   887 		elapsed = I64INT(final.Int64()-initial.Int64());
       
   888 		test.Printf(_L("Time taken = %dus\n"), elapsed);
       
   889 		Wait(t2, KErrTimedOut);
       
   890 		final.HomeTime();
       
   891 		elapsed = I64INT(final.Int64()-initial.Int64());
       
   892 		test.Printf(_L("Time taken = %dus\n"), elapsed);
       
   893 		test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
       
   894 
       
   895 		iTimeout=1000000;
       
   896 		initial.HomeTime();
       
   897 		Start(t2, EPriorityMore);
       
   898 		Start(t, EPriorityMuchMore);
       
   899 		t.Kill(299792458);
       
   900 		Wait(t2, KErrTimedOut);
       
   901 		Wait(t, 299792458);
       
   902 		final.HomeTime();
       
   903 		elapsed = I64INT(final.Int64()-initial.Int64());
       
   904 		test.Printf(_L("Time taken = %dus\n"), elapsed);
       
   905 		test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
       
   906 
       
   907 		iTimeout=1000000;
       
   908 		initial.HomeTime();
       
   909 		Start(t, EPriorityMore);
       
   910 		Start(t2, EPriorityMuchMore);
       
   911 		test_Equal(EExitPending, t.ExitType());
       
   912 		test_Equal(EExitPending, t2.ExitType());
       
   913 		iLock->Release();
       
   914 		test_Equal(EExitKill, t.ExitType());
       
   915 		test_Equal(EExitKill, t2.ExitType());
       
   916 		Wait(t2, KErrGeneral);
       
   917 		Wait(t, KErrGeneral);
       
   918 		final.HomeTime();
       
   919 		elapsed = I64INT(final.Int64()-initial.Int64());
       
   920 		test.Printf(_L("Time taken = %dus\n"), elapsed);
       
   921 		test(elapsed<=50000+3*overhead);
       
   922 		r = UnlockCurrentThreadToCpu0(ETrue);
       
   923 		test_KErrNone(r);
       
   924 		}
       
   925 	else
       
   926 		{
       
   927 		test.Printf(_L("Timed waits not supported\n"));
       
   928 		iLock->Release();
       
   929 		}
   394 	test.End();
   930 	test.End();
   395 	}
   931 	}
   396 
   932 
       
   933 volatile TBool NoRepeat = EFalse;
       
   934 void TestPollTimeout()
       
   935 	{
       
   936 	SWaitLock w;
       
   937 	do	{
       
   938 		test.Printf(_L("TestPollTimeout - RSemaphore\n"));
       
   939 		LockS ls;
       
   940 		w.iLock = &ls;
       
   941 		w.Test2();	// Release()s ls
       
   942 		} while(NoRepeat);
       
   943 	do	{
       
   944 		test.Printf(_L("TestPollTimeout - RMutex\n"));
       
   945 		LockM lm;
       
   946 		w.iLock = &lm;
       
   947 		w.Test2();	// Release()s lm
       
   948 		} while(NoRepeat);
       
   949 	do	{
       
   950 		test.Printf(_L("TestPollTimeout - RFastLock\n"));
       
   951 		LockFL fl;
       
   952 		w.iLock = &fl;
       
   953 		w.Test2();	// Release()s fl
       
   954 		} while(NoRepeat);
       
   955 	}
       
   956 
       
   957 
       
   958 /*----------------------------------------------------------------------------*/
       
   959 class CMXThreadGrp;
       
   960 
       
   961 struct SStats
       
   962 	{
       
   963 	SStats();
       
   964 	void Add(TInt aValue);
       
   965 	void Add(const SStats& aS);
       
   966 	TInt Count() const {return iN;}
       
   967 	TInt Min() const;
       
   968 	TInt Max() const;
       
   969 	TInt Mean() const;
       
   970 
       
   971 	TInt64	iSum;
       
   972 	TInt	iMin;
       
   973 	TInt	iMax;
       
   974 	TInt	iN;
       
   975 	TInt	iSp;
       
   976 	};
       
   977 
       
   978 SStats::SStats()
       
   979 	{
       
   980 	iSum = 0;
       
   981 	iMax = KMinTInt;
       
   982 	iMin = ~iMax;
       
   983 	iN = 0;
       
   984 	iSp = 0;
       
   985 	}
       
   986 
       
   987 void SStats::Add(TInt aValue)
       
   988 	{
       
   989 	TInt64 v = aValue;
       
   990 	iSum += v;
       
   991 	++iN;
       
   992 	if (aValue > iMax)
       
   993 		iMax = aValue;
       
   994 	if (aValue < iMin)
       
   995 		iMin = aValue;
       
   996 	}
       
   997 
       
   998 void SStats::Add(const SStats& a)
       
   999 	{
       
  1000 	iN += a.iN;
       
  1001 	iSum += a.iSum;
       
  1002 	if (a.iMax > iMax)
       
  1003 		iMax = a.iMax;
       
  1004 	if (a.iMin < iMin)
       
  1005 		iMin = a.iMin;
       
  1006 	}
       
  1007 
       
  1008 TInt SStats::Min() const
       
  1009 	{return iN ? iMin : 0;}
       
  1010 
       
  1011 TInt SStats::Max() const
       
  1012 	{return iN ? iMax : 0;}
       
  1013 
       
  1014 TInt SStats::Mean() const
       
  1015 	{
       
  1016 	if (iN==0)
       
  1017 		return 0;
       
  1018 	return (TInt)(iSum/TInt64(iN));
       
  1019 	}
       
  1020 
       
  1021 TUint32 ticks_to_us(TUint32 aTicks, TUint32 aF)
       
  1022 	{
       
  1023 	TUint64 x = aTicks;
       
  1024 	TUint64 f = aF;
       
  1025 	x *= TUint64(1000000);
       
  1026 	x += (f>>1);
       
  1027 	x /= f;
       
  1028 	return I64LOW(x);
       
  1029 	}
       
  1030 
       
  1031 class CMXThread : public CBase
       
  1032 	{
       
  1033 private:
       
  1034 	CMXThread();
       
  1035 	~CMXThread();
       
  1036 	static CMXThread* New(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD);
       
  1037 	void Start();
       
  1038 	void Wait();
       
  1039 	TInt Construct(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD);
       
  1040 	TInt Steps();
       
  1041 	TInt Action();
       
  1042 	TInt Run();
       
  1043 	static TInt ThreadFunc(TAny*);
       
  1044 	void PrintStats();
       
  1045 private:
       
  1046 	TUint64 iSeed;
       
  1047 	RThread	iThread;
       
  1048 	TRequestStatus iExitStatus;
       
  1049 	CMXThreadGrp* iG;
       
  1050 	LFSR* iDummyLfsr;
       
  1051 	TUint32 iId;
       
  1052 	TUint32 iLambda;
       
  1053 	TUint32 iDummySteps;
       
  1054 	TInt iTotalSteps;
       
  1055 	TInt iIterations;
       
  1056 	TInt iPolls;
       
  1057 	TInt iPollFails;
       
  1058 	SStats iStats;
       
  1059 	SStats iTimeoutStats;
       
  1060 private:
       
  1061 	friend class CMXThreadGrp;
       
  1062 	};
       
  1063 
       
  1064 class CMXThreadGrp : public CBase
       
  1065 	{
       
  1066 public:
       
  1067 	static CMXThreadGrp* New(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime);
       
  1068 	CMXThreadGrp();
       
  1069 	~CMXThreadGrp();
       
  1070 	TBool Run();
       
  1071 	void PrintStats();
       
  1072 private:
       
  1073 	TInt Construct(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime);
       
  1074 private:
       
  1075 	TInt iNThreads;
       
  1076 	CMXThread** iThreads;
       
  1077 	MLock* iLock;
       
  1078 	LFSR* iLfsr;
       
  1079 	LFSR* iLfsr0;
       
  1080 	TUint32 iNTickPeriod;
       
  1081 	TUint32 iFCF;
       
  1082 	TUint32 iNTicks;
       
  1083 	TInt iTotalSteps;
       
  1084 	TInt iIterations;
       
  1085 	TInt iPolls;
       
  1086 	TInt iPollFails;
       
  1087 	SStats iStats;
       
  1088 	SStats iTimeoutStats;
       
  1089 private:
       
  1090 	friend class CMXThread;
       
  1091 	};
       
  1092 
       
  1093 CMXThread::CMXThread()
       
  1094 	{
       
  1095 	iThread.SetHandle(0);
       
  1096 	}
       
  1097 
       
  1098 CMXThread::~CMXThread()
       
  1099 	{
       
  1100 	delete iDummyLfsr;
       
  1101 	if (iThread.Handle())
       
  1102 		{
       
  1103 		if (iThread.ExitType() == EExitPending)
       
  1104 			{
       
  1105 			iThread.Kill(0);
       
  1106 			Wait();
       
  1107 			}
       
  1108 		CLOSE_AND_WAIT(iThread);
       
  1109 		}
       
  1110 	}
       
  1111 
       
  1112 void CMXThread::PrintStats()
       
  1113 	{
       
  1114 	test.Printf(_L("Thread %d:\n"), iId);
       
  1115 	test.Printf(_L(" ST:%10d IT:%10d P:%10d PF:%10d TO:%10d\n"), iTotalSteps, iIterations, iPolls, iPollFails, iTimeoutStats.Count());
       
  1116 	TUint32 min, max, mean;
       
  1117 	min = ticks_to_us(iStats.Min(), iG->iFCF);
       
  1118 	max = ticks_to_us(iStats.Max(), iG->iFCF);
       
  1119 	mean = ticks_to_us(iStats.Mean(), iG->iFCF);
       
  1120 	test.Printf(_L(" Lock acquire times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
       
  1121 	min = ticks_to_us(iTimeoutStats.Min(), iG->iFCF);
       
  1122 	max = ticks_to_us(iTimeoutStats.Max(), iG->iFCF);
       
  1123 	mean = ticks_to_us(iTimeoutStats.Mean(), iG->iFCF);
       
  1124 	test.Printf(_L(" Lock timeout times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
       
  1125 	}
       
  1126 
       
  1127 TInt CMXThread::Construct(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD)
       
  1128 	{
       
  1129 	iG = aG;
       
  1130 	iId = aId;
       
  1131 	iLambda = aL;
       
  1132 	iDummySteps = aD;
       
  1133 	iSeed = iId + 1;
       
  1134 	iDummyLfsr = new LFSR(785,693);
       
  1135 	if (!iDummyLfsr)
       
  1136 		return KErrNoMemory;
       
  1137 	TBuf<16> name = _L("TSThrd");
       
  1138 	name.AppendNum(iId);
       
  1139 	TInt r = iThread.Create(name, &ThreadFunc, 0x1000, NULL, this);
       
  1140 	if (r!=KErrNone)
       
  1141 		return r;
       
  1142 	iThread.Logon(iExitStatus);
       
  1143 	if (iExitStatus != KRequestPending)
       
  1144 		{
       
  1145 		iThread.Kill(0);
       
  1146 		iThread.Close();
       
  1147 		iThread.SetHandle(0);
       
  1148 		return iExitStatus.Int();
       
  1149 		}
       
  1150 	iThread.SetPriority(EPriorityLess);
       
  1151 	return KErrNone;
       
  1152 	}
       
  1153 
       
  1154 CMXThread* CMXThread::New(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD)
       
  1155 	{
       
  1156 	CMXThread* p = new CMXThread;
       
  1157 	if (p)
       
  1158 		{
       
  1159 		TInt r = p->Construct(aG, aId, aL, aD);
       
  1160 		if (r != KErrNone)
       
  1161 			{
       
  1162 			delete p;
       
  1163 			p = 0;
       
  1164 			}
       
  1165 		}
       
  1166 	return p;
       
  1167 	}
       
  1168 
       
  1169 void CMXThread::Start()
       
  1170 	{
       
  1171 	iThread.Resume();
       
  1172 	}
       
  1173 
       
  1174 void CMXThread::Wait()
       
  1175 	{
       
  1176 	User::WaitForRequest(iExitStatus);
       
  1177 	}
       
  1178 
       
  1179 TInt CMXThread::ThreadFunc(TAny* aPtr)
       
  1180 	{
       
  1181 	CMXThread& a = *(CMXThread*)aPtr;
       
  1182 	return a.Run();
       
  1183 	}
       
  1184 
       
  1185 TInt CMXThread::Steps()
       
  1186 	{
       
  1187 	Random(iSeed);
       
  1188 	return ExpRV(iSeed, iLambda, 1);
       
  1189 	}
       
  1190 
       
  1191 TInt CMXThread::Action()
       
  1192 	{
       
  1193 	Random(iSeed);
       
  1194 	return I64LOW(iSeed)%3;
       
  1195 	}
       
  1196 
       
  1197 TInt CMXThread::Run()
       
  1198 	{
       
  1199 	MLock* lock = iG->iLock;
       
  1200 	LFSR* lfsr = iG->iLfsr;
       
  1201 	TInt lfl = lock->Flags();
       
  1202 	TBool pollable = lfl & MLock::EPollable;
       
  1203 	TBool to = lfl & MLock::ETimeoutAvail;
       
  1204 	TUint32 start_time = User::NTickCount();
       
  1205 	TInt r;
       
  1206 
       
  1207 	FOREVER
       
  1208 		{
       
  1209 		TUint32 now = User::NTickCount();
       
  1210 		if (now - start_time >= iG->iNTicks)
       
  1211 			break;
       
  1212 		++iIterations;
       
  1213 		iDummyLfsr->Step(iDummySteps);
       
  1214 		TInt action = Action();
       
  1215 		TInt steps = Steps();
       
  1216 		TUint32 initial = User::FastCounter();
       
  1217 		if (action==2 && to)
       
  1218 			{
       
  1219 			r = lock->Wait(1000);
       
  1220 			if (r!=KErrNone)
       
  1221 				{
       
  1222 				TUint32 final = User::FastCounter();
       
  1223 				TInt elapsed = TInt(final - initial);
       
  1224 				iTimeoutStats.Add(elapsed);
       
  1225 				}
       
  1226 			}
       
  1227 		else if (action==1 && pollable)
       
  1228 			{
       
  1229 			++iPolls;
       
  1230 			r = lock->Poll();
       
  1231 			if (r!=KErrNone)
       
  1232 				++iPollFails;
       
  1233 			}
       
  1234 		else
       
  1235 			{
       
  1236 			lock->Wait();
       
  1237 			r = KErrNone;
       
  1238 			}
       
  1239 		if (r == KErrNone)
       
  1240 			{
       
  1241 			TUint32 final = User::FastCounter();
       
  1242 			lfsr->Step(steps);
       
  1243 			lock->Signal();
       
  1244 			TInt elapsed = TInt(final - initial);
       
  1245 			iTotalSteps += steps;
       
  1246 			iStats.Add(elapsed);
       
  1247 			}
       
  1248 		}
       
  1249 
       
  1250 	return KErrNone;
       
  1251 	}
       
  1252 
       
  1253 CMXThreadGrp* CMXThreadGrp::New(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime)
       
  1254 	{
       
  1255 	CMXThreadGrp* p = new CMXThreadGrp;
       
  1256 	if (p)
       
  1257 		{
       
  1258 		TInt r = p->Construct(aLock, aNThreads, aLambda, aDummySteps, aTime);
       
  1259 		if (r != KErrNone)
       
  1260 			{
       
  1261 			delete p;
       
  1262 			p = 0;
       
  1263 			}
       
  1264 		}
       
  1265 	return p;
       
  1266 	}
       
  1267 
       
  1268 CMXThreadGrp::CMXThreadGrp()
       
  1269 	{
       
  1270 	}
       
  1271 
       
  1272 TInt CMXThreadGrp::Construct(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime)
       
  1273 	{
       
  1274 	iNThreads = aNThreads;
       
  1275 	iLock = aLock;
       
  1276 	TInt r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)iFCF);
       
  1277 	if (r!=KErrNone)
       
  1278 		return r;
       
  1279 	r = HAL::Get(HAL::ENanoTickPeriod, (TInt&)iNTickPeriod);
       
  1280 	if (r!=KErrNone)
       
  1281 		return r;
       
  1282 	iNTicks = (aTime+iNTickPeriod-1)/iNTickPeriod;
       
  1283 	iLfsr = new LFSR(785,693);
       
  1284 	iLfsr0 = new LFSR(785,693);
       
  1285 	if (!iLfsr || !iLfsr0)
       
  1286 		return KErrNoMemory;
       
  1287 	iThreads = (CMXThread**)User::AllocZ(iNThreads*sizeof(CMXThread*));
       
  1288 	if (!iThreads)
       
  1289 		return KErrNoMemory;
       
  1290 	TInt i;
       
  1291 	for (i=0; i<iNThreads; ++i)
       
  1292 		{
       
  1293 		iThreads[i] = CMXThread::New(this, i, aLambda, aDummySteps);
       
  1294 		if (!iThreads[i])
       
  1295 			return KErrNoMemory;
       
  1296 		}
       
  1297 	return KErrNone;
       
  1298 	}
       
  1299 
       
  1300 CMXThreadGrp::~CMXThreadGrp()
       
  1301 	{
       
  1302 	delete iLfsr;
       
  1303 	delete iLfsr0;
       
  1304 	if (iThreads)
       
  1305 		{
       
  1306 		TInt i;
       
  1307 		for (i=0; i<iNThreads; ++i)
       
  1308 			delete iThreads[i];
       
  1309 		}
       
  1310 	User::Free(iThreads);
       
  1311 	}
       
  1312 
       
  1313 TBool CMXThreadGrp::Run()
       
  1314 	{
       
  1315 	TInt i;
       
  1316 	test.Printf(_L("Starting test with N=%d L=%d D=%d T=%d\n"), iNThreads, iThreads[0]->iLambda, iThreads[0]->iDummySteps, iNTicks);
       
  1317 	for (i=0; i<iNThreads; ++i)
       
  1318 		iThreads[i]->Start();
       
  1319 	for (i=0; i<iNThreads; ++i)
       
  1320 		iThreads[i]->Wait();
       
  1321 	for (i=0; i<iNThreads; ++i)
       
  1322 		{
       
  1323 		iTotalSteps += iThreads[i]->iTotalSteps;
       
  1324 		iIterations += iThreads[i]->iIterations;
       
  1325 		iPolls += iThreads[i]->iPolls;
       
  1326 		iPollFails += iThreads[i]->iPollFails;
       
  1327 		iStats.Add(iThreads[i]->iStats);
       
  1328 		iTimeoutStats.Add(iThreads[i]->iTimeoutStats);
       
  1329 		}
       
  1330 	test.Printf(_L("Total LFSR steps %d\n"), iTotalSteps);
       
  1331 	iLfsr0->Step(iTotalSteps);
       
  1332 	TBool ok = (*iLfsr == *iLfsr0);
       
  1333 	return ok;
       
  1334 	}
       
  1335 
       
  1336 void CMXThreadGrp::PrintStats()
       
  1337 	{
       
  1338 	TInt i;
       
  1339 	for (i=0; i<iNThreads; ++i)
       
  1340 		{
       
  1341 		iThreads[i]->PrintStats();
       
  1342 		}
       
  1343 	test.Printf(_L("TOTALS:\n"));
       
  1344 	test.Printf(_L(" ST:%10d IT:%10d P:%10d PF:%10d TO:%10d\n"), iTotalSteps, iIterations, iPolls, iPollFails, iTimeoutStats.Count());
       
  1345 	TUint32 min, max, mean;
       
  1346 	min = ticks_to_us(iStats.Min(), iFCF);
       
  1347 	max = ticks_to_us(iStats.Max(), iFCF);
       
  1348 	mean = ticks_to_us(iStats.Mean(), iFCF);
       
  1349 	test.Printf(_L(" Lock acquire times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
       
  1350 	min = ticks_to_us(iTimeoutStats.Min(), iFCF);
       
  1351 	max = ticks_to_us(iTimeoutStats.Max(), iFCF);
       
  1352 	mean = ticks_to_us(iTimeoutStats.Mean(), iFCF);
       
  1353 	test.Printf(_L(" Lock timeout times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
       
  1354 	}
       
  1355 
       
  1356 TUint32 Calibrate()
       
  1357 	{
       
  1358 	TUint32 fcf;
       
  1359 	TInt r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)fcf);
       
  1360 	test_KErrNone(r);
       
  1361 	LFSR* d = new LFSR(785,693);
       
  1362 	test(d!=0);
       
  1363 	TInt steps = 2;
       
  1364 	TUint32 ticks = fcf/10;
       
  1365 	TUint32 elapsed;
       
  1366 	FOREVER
       
  1367 		{
       
  1368 		TUint32 h0 = User::FastCounter();
       
  1369 		d->Step(steps);
       
  1370 		TUint32 h1 = User::FastCounter();
       
  1371 		elapsed = h1 - h0;
       
  1372 		if (elapsed > ticks)
       
  1373 			break;
       
  1374 		steps *= 2;
       
  1375 		}
       
  1376 	delete d;
       
  1377 	test.Printf(_L("%d steps in %d fast ticks\n"), steps, elapsed);
       
  1378 	TUint64 x = elapsed;
       
  1379 	TUint64 s = steps;
       
  1380 	TUint64 y = fcf;
       
  1381 	y /= x;
       
  1382 	s *= y;	// steps per second
       
  1383 	TUint32 res = I64LOW(s);
       
  1384 	test.Printf(_L("%d steps per second\n"), res);
       
  1385 	return res;
       
  1386 	}
       
  1387 
       
  1388 void DoTMX(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime, TBool aShouldFail=EFalse)
       
  1389 	{
       
  1390 	CMXThreadGrp* g = CMXThreadGrp::New(aLock, aNThreads, aLambda, aDummySteps, aTime);
       
  1391 	test(g!=0);
       
  1392 	TBool ok = g->Run();
       
  1393 	if (aShouldFail)
       
  1394 		{
       
  1395 		test(!ok);
       
  1396 		}
       
  1397 	else
       
  1398 		{
       
  1399 		test(ok);
       
  1400 		}
       
  1401 	g->PrintStats();
       
  1402 	delete g;
       
  1403 	}
       
  1404 
       
  1405 void DoTMX(MLock* aLock, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime)
       
  1406 	{
       
  1407 	TInt n;
       
  1408 	for (n=1; n<=4; ++n)
       
  1409 		{
       
  1410 		TUint32 l = (n<2) ? aLambda : (aLambda/(n-1));
       
  1411 		DoTMX(aLock, n, l, aDummySteps, aTime);
       
  1412 		}
       
  1413 	aLock->Release();
       
  1414 	}
       
  1415 
       
  1416 
       
  1417 void TestMutualExclusion()
       
  1418 	{
       
  1419 	TInt ntp;
       
  1420 	TInt r = HAL::Get(HAL::ENanoTickPeriod, ntp);
       
  1421 	test_KErrNone(r);
       
  1422 	test.Printf(_L("Nanokernel tick period = %dus\n"), ntp);
       
  1423 	TUint32 sps = Calibrate();
       
  1424 	TUint32 lambda = sps/2000;
       
  1425 	TUint32 dummy = sps/2000;
       
  1426 	TUint32 time = 5000000;
       
  1427 	do	{
       
  1428 		test.Printf(_L("TestMutualExclusion - RSemaphore\n"));
       
  1429 		LockS ls;
       
  1430 		DoTMX(&ls, lambda, dummy, time);
       
  1431 		} while(NoRepeat);
       
  1432 	do	{
       
  1433 		test.Printf(_L("TestMutualExclusion - RSemaphore init=2\n"));
       
  1434 		LockS ls2;
       
  1435 		ls2.Signal();	// count=2
       
  1436 		DoTMX(&ls2, 4, lambda, dummy, time, ETrue);
       
  1437 		} while(NoRepeat);
       
  1438 	do	{
       
  1439 		test.Printf(_L("TestMutualExclusion - RMutex\n"));
       
  1440 		LockM lm;
       
  1441 		DoTMX(&lm, lambda, dummy, time);
       
  1442 		} while(NoRepeat);
       
  1443 	do	{
       
  1444 		test.Printf(_L("TestMutualExclusion - RFastLock\n"));
       
  1445 		LockFL fl;
       
  1446 		DoTMX(&fl, lambda, dummy, time);
       
  1447 		} while(NoRepeat);
       
  1448 	do	{
       
  1449 		test.Printf(_L("TestMutualExclusion - RCriticalSection\n"));
       
  1450 		LockCS cs;
       
  1451 		DoTMX(&cs, lambda, dummy, time);
       
  1452 		} while(NoRepeat);
       
  1453 	}
       
  1454 
       
  1455 
       
  1456 
       
  1457 
       
  1458 /*----------------------------------------------------------------------------*/
   397 void TestSemaphore()
  1459 void TestSemaphore()
   398 	{
  1460 	{
   399 /*********** TO DO ************/
  1461 /*********** TO DO ************/
   400 // Check it panics if the count <0
  1462 // Check it panics if the count <0
   401 
  1463 
   415 	test(find.Next(fullName)== KErrNone);	
  1477 	test(find.Next(fullName)== KErrNone);	
   416 */
  1478 */
   417 	test.Next(_L("Producer/Consumer scenario"));
  1479 	test.Next(_L("Producer/Consumer scenario"));
   418 	// Test Rsemaphore with the producer/consumer scenario	RThread thread1, thread2;
  1480 	// Test Rsemaphore with the producer/consumer scenario	RThread thread1, thread2;
   419 	TRequestStatus stat1, stat2;
  1481 	TRequestStatus stat1, stat2;
   420 	test_KErrNone(mutex.CreateLocal());
  1482 	test(mutex.CreateLocal()==KErrNone);
   421 	test_KErrNone(slotAvailable.CreateLocal(KMaxBufferSize));
  1483 	test(slotAvailable.CreateLocal(KMaxBufferSize)==KErrNone);
   422 	test_KErrNone(itemAvailable.CreateLocal(0));
  1484 	test(itemAvailable.CreateLocal(0)==KErrNone);
   423 	test_KErrNone(thread1.Create(_L("Thread1"),Producer,KDefaultStackSize,0x200,0x200,NULL));
  1485 	test(thread1.Create(_L("Thread1"),Producer,KDefaultStackSize,0x200,0x200,NULL)==KErrNone);
   424 	test_KErrNone(thread2.Create(_L("Thread2"),Consumer,KDefaultStackSize,0x200,0x200,NULL));
  1486 	test(thread2.Create(_L("Thread2"),Consumer,KDefaultStackSize,0x200,0x200,NULL)==KErrNone);
   425 	thread1.Logon(stat1);
  1487 	thread1.Logon(stat1);
   426 	thread2.Logon(stat2);
  1488 	thread2.Logon(stat2);
   427 	test_Equal(KRequestPending, stat1.Int());
  1489 	test(stat1==KRequestPending);
   428 	test_Equal(KRequestPending, stat2.Int());
  1490 	test(stat2==KRequestPending);
   429 	thread1.Resume(); 
  1491 	thread1.Resume(); 
   430 	thread2.Resume();
  1492 	thread2.Resume();
   431 	User::WaitForRequest(stat1);
  1493 	User::WaitForRequest(stat1);
   432 	User::WaitForRequest(stat2);
  1494 	User::WaitForRequest(stat2);
   433 	test_KErrNone(stat1.Int());
  1495 	test(stat1==KErrNone);
   434 	test_KErrNone(stat2.Int());
  1496 	test(stat2==KErrNone);
   435 	for(TInt jj=0;jj<KNumProducerItems;jj++)
  1497 	for(TInt jj=0;jj<KNumProducerItems;jj++)
   436 		test_Equal(jj, consumerArray[jj]);		
  1498 		test(consumerArray[jj]==jj);		
   437 	
  1499 	
   438 	test.Next(_L("Close"));
  1500 	test.Next(_L("Close"));
   439 	mutex.Close();
  1501 	mutex.Close();
   440 	CLOSE_AND_WAIT(thread1);
  1502 	CLOSE_AND_WAIT(thread1);
   441 	CLOSE_AND_WAIT(thread2);
  1503 	CLOSE_AND_WAIT(thread2);
   444 
  1506 
   445 void TestMutex2()
  1507 void TestMutex2()
   446 	{
  1508 	{
   447 	RMutex m;
  1509 	RMutex m;
   448 	test.Start(_L("Create"));
  1510 	test.Start(_L("Create"));
   449 	test_KErrNone(m.CreateLocal());
  1511 	test(m.CreateLocal()==KErrNone);
   450 
  1512 
   451 	// Test RMutex::IsHeld()
  1513 	// Test RMutex::IsHeld()
   452 	test.Next(_L("IsHeld ?"));
  1514 	test.Next(_L("IsHeld ?"));
   453 	test(!m.IsHeld());
  1515 	test(!m.IsHeld());
   454 	test.Next(_L("Wait"));
  1516 	test.Next(_L("Wait"));
   464 	}
  1526 	}
   465 
  1527 
   466 void TestMutex()
  1528 void TestMutex()
   467 	{
  1529 	{
   468 	test.Start(_L("Create"));
  1530 	test.Start(_L("Create"));
   469 	test_KErrNone(mutex.CreateLocal());
  1531 	test(mutex.CreateLocal()==KErrNone);
   470 	
  1532 	
   471 	test.Next(_L("Threads writing to arrays test"));
  1533 	test.Next(_L("Threads writing to arrays test"));
   472 //
  1534 //
   473 // Create two threads which write to two arrays. The arrays and indexs
  1535 // Create two threads which write to two arrays. The arrays and indexs
   474 // are global and each thread writes an identifier to the arrays. For
  1536 // are global and each thread writes an identifier to the arrays. For
   478 // each array. For the mutex controlled array the actual instances
  1540 // each array. For the mutex controlled array the actual instances
   479 // written to the array should always be the same as the threads think.
  1541 // written to the array should always be the same as the threads think.
   480 //
  1542 //
   481 	arrayIndex=0;
  1543 	arrayIndex=0;
   482 	RThread thread1,thread2;	
  1544 	RThread thread1,thread2;	
   483 	test_KErrNone(thread1.Create(_L("Thread1"),MutexThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL));
  1545 	test(thread1.Create(_L("Thread1"),MutexThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
   484 	test_KErrNone(thread2.Create(_L("Thread2"),MutexThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL));			 
  1546 	test(thread2.Create(_L("Thread2"),MutexThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);			 
   485 	TRequestStatus stat1,stat2;
  1547 	TRequestStatus stat1,stat2;
   486 	thread1.Logon(stat1);
  1548 	thread1.Logon(stat1);
   487 	thread2.Logon(stat2);
  1549 	thread2.Logon(stat2);
   488 	test_Equal(KRequestPending, stat1.Int());
  1550 	test(stat1==KRequestPending);
   489 	test_Equal(KRequestPending, stat2.Int());
  1551 	test(stat2==KRequestPending);
   490 	thread1.Resume(); 
  1552 	thread1.Resume(); 
   491 	thread2.Resume();
  1553 	thread2.Resume();
   492 	User::WaitForRequest(stat1);
  1554 	User::WaitForRequest(stat1);
   493 	User::WaitForRequest(stat2);
  1555 	User::WaitForRequest(stat2);
   494 	test_KErrNone(stat1.Int());
  1556 	test(stat1==KErrNone);
   495 	test_KErrNone(stat2.Int()); 
  1557 	test(stat2==KErrNone); 
   496 	TInt thread1ActualCount=0; 
  1558 	TInt thread1ActualCount=0; 
   497 	TInt thread2ActualCount=0;
  1559 	TInt thread2ActualCount=0;
   498 	TInt ii=0;
  1560 	TInt ii=0;
   499 	while(ii<KMaxArraySize)
  1561 	while(ii<KMaxArraySize)
   500 		{
  1562 		{
   502 			thread1ActualCount++;
  1564 			thread1ActualCount++;
   503 		if (array[ii]==EThread2ID)
  1565 		if (array[ii]==EThread2ID)
   504 			thread2ActualCount++;
  1566 			thread2ActualCount++;
   505 		ii++;
  1567 		ii++;
   506 		}
  1568 		}
   507 	test.Printf(_L("T1 %d T1ACT %d T2 %d T2ACT %d"),thread1Count,thread1ActualCount,thread2Count,thread2ActualCount);
  1569 	test.Printf(_L("T1 %d T1ACT %d T2 %d T2ACT %d\n"),thread1Count,thread1ActualCount,thread2Count,thread2ActualCount);
   508 	test_Equal(thread1Count, thread1ActualCount);
  1570 	test(thread1ActualCount==thread1Count);
   509 	test_Equal(thread2Count, thread2ActualCount);
  1571 	test(thread2ActualCount==thread2Count);
   510 	test_Equal(thread2Count, thread1Count);
  1572 	test(thread1Count==thread2Count);
   511 	test_Equal((KMaxArraySize>>1), thread1Count);
  1573 	test(thread1Count==(KMaxArraySize>>1));
   512 	
  1574 	
   513 	test.Next(_L("Close"));
  1575 	test.Next(_L("Close"));
   514 	CLOSE_AND_WAIT(thread1);
  1576 	CLOSE_AND_WAIT(thread1);
   515 	CLOSE_AND_WAIT(thread2);
  1577 	CLOSE_AND_WAIT(thread2);
   516 	mutex.Close();
  1578 	mutex.Close();
   522 //As TestMutex, but for RCriticalSection
  1584 //As TestMutex, but for RCriticalSection
   523 //
  1585 //
   524 	{
  1586 	{
   525 	
  1587 	
   526 	test.Start(_L("Create"));
  1588 	test.Start(_L("Create"));
   527 	test_KErrNone(criticalSn.CreateLocal());
  1589 	test(criticalSn.CreateLocal()==KErrNone);
   528 
  1590 
   529 /***************** TO DO ***********************
  1591 /***************** TO DO ***********************
   530 
  1592 
   531 	test.Next(_L("Find"));
  1593 	test.Next(_L("Find"));
   532 //
  1594 //
   551 // "thinks" it wrote to each array. For the mutex controlled array the
  1613 // "thinks" it wrote to each array. For the mutex controlled array the
   552 // actual instances written to the array should always be the same as the
  1614 // actual instances written to the array should always be the same as the
   553 // threads think.
  1615 // threads think.
   554 //
  1616 //
   555 	arrayIndex=0;
  1617 	arrayIndex=0;
       
  1618 
   556 	RThread thread1,thread2;	
  1619 	RThread thread1,thread2;	
   557 	test_KErrNone(thread1.Create(_L("Thread1"),CriticalSnThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL));
  1620 	test(thread1.Create(_L("Thread1"),CriticalSnThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
   558 	test_KErrNone(thread2.Create(_L("Thread2"),CriticalSnThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL));			 
  1621 	test(thread2.Create(_L("Thread2"),CriticalSnThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);			 
   559 	TRequestStatus stat1,stat2;
  1622 	TRequestStatus stat1,stat2;
   560 	thread1.Logon(stat1);
  1623 	thread1.Logon(stat1);
   561 	thread2.Logon(stat2);
  1624 	thread2.Logon(stat2);
   562 	test_Equal(KRequestPending, stat1.Int());
  1625 	test(stat1==KRequestPending);
   563 	test_Equal(KRequestPending, stat2.Int());
  1626 	test(stat2==KRequestPending);
   564 	thread1.Resume(); 
  1627 	thread1.Resume(); 
   565 	thread2.Resume();
  1628 	thread2.Resume();
   566 	User::WaitForRequest(stat1);
  1629 	User::WaitForRequest(stat1);
   567 	User::WaitForRequest(stat2);
  1630 	User::WaitForRequest(stat2);
   568 	test_KErrNone(stat1.Int());
  1631 	test(stat1==KErrNone);
   569 	test_KErrNone(stat2.Int()); 
  1632 	test(stat2==KErrNone); 
   570 	TInt thread1ActualCount=0; 
  1633 	TInt thread1ActualCount=0; 
   571 	TInt thread2ActualCount=0;
  1634 	TInt thread2ActualCount=0;
   572 	TInt ii=0;
  1635 	TInt ii=0;
   573 	while(ii<KMaxArraySize)
  1636 	while(ii<KMaxArraySize)
   574 		{
  1637 		{
   576 			thread1ActualCount++;
  1639 			thread1ActualCount++;
   577 		if (array[ii]==EThread2ID)
  1640 		if (array[ii]==EThread2ID)
   578 			thread2ActualCount++;
  1641 			thread2ActualCount++;
   579 		ii++;
  1642 		ii++;
   580 		}
  1643 		}
   581 	test_Equal(thread1Count, thread1ActualCount);
  1644 	test(thread1ActualCount==thread1Count);
   582 	test_Equal(thread2Count, thread2ActualCount);
  1645 	test(thread2ActualCount==thread2Count);
   583 	test_Equal(thread2Count, thread1Count);
  1646 	test(thread1Count==thread2Count);
   584 	test_Equal((KMaxArraySize>>1), thread1Count);
  1647 	test(thread1Count==(KMaxArraySize>>1));
   585 
  1648 
   586 	test.Next(_L("Close"));
  1649 	test.Next(_L("Close"));
   587 	CLOSE_AND_WAIT(thread1);
  1650 	CLOSE_AND_WAIT(thread1);
   588 	CLOSE_AND_WAIT(thread2);
  1651 	CLOSE_AND_WAIT(thread2);
   589 	criticalSn.Close();
  1652 	criticalSn.Close();
   591 	}
  1654 	}
   592 
  1655 
   593 
  1656 
   594 GLDEF_C TInt E32Main()
  1657 GLDEF_C TInt E32Main()
   595 	{	
  1658 	{	
   596 	TInt cpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
       
   597 	if (cpus != 1)
       
   598 		{
       
   599 		test(cpus>1);
       
   600 		// This test will require compatibility mode (and probably other changes)
       
   601 		// to work on SMP - it depends on explicit scheduling order.
       
   602 		test.Printf(_L("T_SEMUTX skipped, does not work on SMP\n"));
       
   603 		return KErrNone;
       
   604 		}	
       
   605 	
       
   606 
  1659 
   607 	test.Title();
  1660 	test.Title();
   608  	__UHEAP_MARK;
  1661  	__UHEAP_MARK;
       
  1662 	TestMutualExclusion();
       
  1663 	TestPollTimeout();
   609 	test.Start(_L("Test RSemaphore"));
  1664 	test.Start(_L("Test RSemaphore"));
   610 	TestSemaphore();
  1665 	TestSemaphore();
   611 	TestSemaphore2();
       
   612 	test.Next(_L("Test RMutex"));
  1666 	test.Next(_L("Test RMutex"));
   613 	TestMutex();
  1667 	TestMutex();
   614 	TestMutex2();
  1668 	TestMutex2();
   615 	test.Next(_L("Test RCriticalSection"));
  1669 	test.Next(_L("Test RCriticalSection"));
   616 	TestCriticalSection();
  1670 	TestCriticalSection();