--- a/kerneltest/e32test/prime/t_semutx.cpp Wed Jun 23 12:52:28 2010 +0100
+++ b/kerneltest/e32test/prime/t_semutx.cpp Wed Jun 23 12:58:21 2010 +0100
@@ -40,7 +40,9 @@
#define __E32TEST_EXTENSION__
#include <e32test.h>
-#include <u32std.h>
+#include <hal.h>
+#include <e32atomics.h>
+#include <u32hal.h>
#include <e32svr.h>
const TInt KMaxBufferSize=10;
@@ -51,13 +53,352 @@
RTest test(_L("T_SEMUTX"));
RMutex mutex;
-RCriticalSection criticalSn;
+RCriticalSection criticalSn;
TInt thread1Count,thread2Count;
TInt arrayIndex;
-TInt array[KMaxArraySize];
+TInt array[KMaxArraySize];
TInt consumerArray[KNumProducerItems];
-RSemaphore slotAvailable,itemAvailable;
+RSemaphore slotAvailable,itemAvailable;
+TBool doCpuLocking = EFalse;
+
+// return num of cpus in system
+TInt NumCpus()
+ {
+ TInt r = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
+ return r;
+ }
+
+
+TInt LockCurrentThreadToCpu0(TBool aCallingIsMainTestThread = EFalse)
+ {
+ if (aCallingIsMainTestThread)
+ {
+ if (NumCpus() > 1)
+ {
+ doCpuLocking = ETrue;
+ return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, 0, 0);
+ }
+ else
+ {
+ return KErrNone;
+ }
+ }
+ return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, 0, 0);
+ }
+
+TInt UnlockCurrentThreadToCpu0(TBool aCallingIsMainTestThread = EFalse)
+ {
+ if (aCallingIsMainTestThread)
+ {
+ if (NumCpus() > 1)
+ {
+ doCpuLocking = EFalse;
+ return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny*) 0xffffffffu, 0);
+ }
+ else
+ {
+ return KErrNone;
+ }
+ }
+ return UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny*) 0xffffffffu, 0);
+ }
+
+
+/******************************************************************************
+ * Random Number Generation
+ ******************************************************************************/
+void Random(TUint64& a)
+ {
+ TInt i;
+ for (i=64; i>0; --i)
+ {
+ TUint64 x = a<<1;
+ TUint64 y = x<<1;
+ x^=y;
+ a = (y>>1) | (x>>63);
+ }
+ }
+
+// Returns 256*log2(a/2^64)
+TInt Log2(TUint64 a)
+ {
+ const TUint64 KBit63 = UI64LIT(0x8000000000000000);
+ TInt n = __e32_find_ms1_64(a);
+ a <<= (63-n);
+ n -= 64;
+ TInt i;
+ for (i=0; i<8; ++i)
+ {
+ a >>= 32;
+ a *= a;
+ n <<= 1;
+ if (a & KBit63)
+ {
+ ++n;
+ }
+ else
+ {
+ a <<= 1;
+ }
+ }
+ return n;
+ }
+
+TUint32 ExpRV(TUint64 aU, TUint32 aMean, TUint32 aTick)
+ {
+ TInt n = -Log2(aU);
+ TUint64 x = TUint64(n) * TUint64(aMean);
+ x *= TUint64(22713); // 2^15 * ln2
+ TUint64 p(aTick);
+ p <<= 22;
+ x += p;
+ p += p;
+ x /= p;
+ return I64LOW(x);
+ }
+
+
+
+/*----------------------------------------------------------------------------*/
+class MLock
+ {
+public:
+ enum {EPollable=1, ETimeoutAvail=2, ENestable=4, ELimit1=8, ELooseTimeout=16};
+public:
+ virtual TInt Flags()=0;
+ virtual void Release()=0;
+ virtual void Wait()=0;
+ virtual void Signal()=0;
+ virtual TInt Wait(TInt aTimeout);
+ virtual TInt Poll();
+ };
+
+TInt MLock::Wait(TInt)
+ { return KErrNotSupported; }
+TInt MLock::Poll()
+ { return KErrNotSupported; }
+
+/*----------------------------------------------------------------------------*/
+class LockS : public MLock
+ {
+public:
+ LockS();
+ virtual TInt Flags();
+ virtual void Release();
+ virtual void Wait();
+ virtual void Signal();
+ virtual TInt Wait(TInt aTimeout);
+ virtual TInt Poll();
+public:
+ RSemaphore iT;
+ };
+
+LockS::LockS()
+ { test_KErrNone(iT.CreateLocal(1)); }
+TInt LockS::Flags()
+ { return EPollable|ETimeoutAvail; }
+void LockS::Release()
+ { iT.Close(); }
+void LockS::Wait()
+ { iT.Wait(); }
+void LockS::Signal()
+ { iT.Signal(); }
+TInt LockS::Wait(TInt aTimeout)
+ { return iT.Wait(aTimeout); }
+TInt LockS::Poll()
+ { return iT.Poll(); }
+
+/*----------------------------------------------------------------------------*/
+class LockM : public MLock
+ {
+public:
+ LockM();
+ virtual TInt Flags();
+ virtual void Release();
+ virtual void Wait();
+ virtual void Signal();
+ virtual TInt Wait(TInt aTimeout);
+ virtual TInt Poll();
+public:
+ RMutex iT;
+ };
+
+LockM::LockM()
+ { test_KErrNone(iT.CreateLocal()); }
+TInt LockM::Flags()
+ { return EPollable|ETimeoutAvail|ENestable|ELimit1; }
+void LockM::Release()
+ { iT.Close(); }
+void LockM::Wait()
+ { iT.Wait(); }
+void LockM::Signal()
+ { iT.Signal(); }
+TInt LockM::Wait(TInt aTimeout)
+ { return iT.Wait(aTimeout); }
+TInt LockM::Poll()
+ { return iT.Poll(); }
+
+/*----------------------------------------------------------------------------*/
+
+class LockFL : public MLock
+ {
+public:
+ LockFL();
+ virtual TInt Flags();
+ virtual void Release();
+ virtual void Wait();
+ virtual void Signal();
+ virtual TInt Wait(TInt aTimeout);
+ virtual TInt Poll();
+public:
+ RFastLock iT;
+ };
+
+LockFL::LockFL()
+ { test_KErrNone(iT.CreateLocal()); }
+TInt LockFL::Flags()
+ { return ETimeoutAvail|EPollable|ELimit1|ELooseTimeout; }
+void LockFL::Release()
+ { iT.Close(); }
+void LockFL::Wait()
+ { iT.Wait(); }
+void LockFL::Signal()
+ { iT.Signal(); }
+TInt LockFL::Wait(TInt aTimeout)
+ { return iT.Wait(aTimeout); }
+TInt LockFL::Poll()
+ { return iT.Poll(); }
+
+/*----------------------------------------------------------------------------*/
+class LockCS : public MLock
+ {
+public:
+ LockCS();
+ virtual TInt Flags();
+ virtual void Release();
+ virtual void Wait();
+ virtual void Signal();
+public:
+ RCriticalSection iT;
+ };
+
+LockCS::LockCS()
+ { test_KErrNone(iT.CreateLocal()); }
+TInt LockCS::Flags()
+ { return ELimit1; }
+void LockCS::Release()
+ { iT.Close(); }
+void LockCS::Wait()
+ { iT.Wait(); }
+void LockCS::Signal()
+ { iT.Signal(); }
+
+
+/*----------------------------------------------------------------------------*/
+class LFSR
+ {
+public:
+ LFSR(TInt aBits, TInt aTap2, TInt aTap3=0, TInt aTap4=0);
+ ~LFSR();
+ void Step();
+ void Step(TInt aSteps);
+ TBool operator==(const LFSR& a) const;
+public:
+ TUint32* iData;
+ TInt iBits;
+ TInt iTap2;
+ TInt iTap3;
+ TInt iTap4;
+ TInt iNW;
+ TInt iSh1;
+ TInt iIx2;
+ TInt iSh2;
+ TInt iIx3;
+ TInt iSh3;
+ TInt iIx4;
+ TInt iSh4;
+ };
+
+LFSR::LFSR(TInt aBits, TInt aTap2, TInt aTap3, TInt aTap4)
+ {
+ iBits = aBits;
+ iTap2 = aTap2;
+ iTap3 = aTap3;
+ iTap4 = aTap4;
+ iNW = (aBits + 31) >> 5;
+ iData = (TUint32*)User::AllocZ(iNW*sizeof(TUint32));
+ test(iData!=0);
+ iData[0] = 1;
+ iSh1 = (aBits-1)&31;
+ iIx2 = (iTap2-1)>>5;
+ iSh2 = (iTap2-1)&31;
+ if (iTap3)
+ {
+ iIx3 = (iTap3-1)>>5;
+ iSh3 = (iTap3-1)&31;
+ }
+ else
+ {
+ iIx3 = -1;
+ iSh3 = 0;
+ }
+ if (iTap4)
+ {
+ iIx4 = (iTap4-1)>>5;
+ iSh4 = (iTap4-1)&31;
+ }
+ else
+ {
+ iIx4 = -1;
+ iSh4 = 0;
+ }
+ }
+
+LFSR::~LFSR()
+ {
+ User::Free(iData);
+ }
+
+void LFSR::Step(TInt aSteps)
+ {
+ while (aSteps--)
+ Step();
+ }
+
+void LFSR::Step()
+ {
+ TUint32 b = iData[iNW-1]>>iSh1;
+ b ^= (iData[iIx2]>>iSh2);
+ if (iIx3>=0)
+ b ^= (iData[iIx3]>>iSh3);
+ if (iIx4>=0)
+ b ^= (iData[iIx4]>>iSh4);
+ b &= 1;
+ TInt i;
+ for (i=0; i<iNW; ++i)
+ {
+ TUint32 bb = iData[i] >> 31;
+ iData[i] = (iData[i]<<1)|b;
+ b = bb;
+ }
+ iData[iNW-1] &= ((2u<<iSh1)-1u);
+ }
+
+TBool LFSR::operator==(const LFSR& a) const
+ {
+ if (iBits!=a.iBits || iTap2!=a.iTap2 || iTap3!=a.iTap3 || iTap4!=a.iTap4 || iNW!=a.iNW)
+ return EFalse;
+ if (iData==a.iData)
+ return ETrue;
+ if (memcompare((const TUint8*)iData, iNW, (const TUint8*)a.iData, a.iNW))
+ return EFalse;
+ return ETrue;
+ }
+
+
+
+/*----------------------------------------------------------------------------*/
class CStack
{
public:
@@ -118,6 +459,7 @@
// Mutex test thread 1
//
{
+ TInt n = NumCpus();
thread1Count=0;
TBool running=ETrue;
@@ -133,6 +475,16 @@
else
running=EFalse;
mutex.Signal();
+
+ if (n > 1)
+ {
+ // when the mutex is singaled, due to priority balancing, the other
+ // thread will be scheduled to run on a CPU other than this one. The delay
+ // in getting that thread to run means that this one can manage to re-claim the
+ // mutex before the other thread gets to run. So we add a small delay here
+ User::After(100);
+ }
+
} while (running);
return(KErrNone);
}
@@ -142,6 +494,7 @@
// Mutex test thread 2
//
{
+ TInt n = NumCpus();
thread2Count=0;
TBool running=ETrue;
@@ -157,6 +510,17 @@
else
running=EFalse;
mutex.Signal();
+
+ if (n > 1)
+ {
+ // when the mutex is singaled, due to priority balancing, the other
+ // thread will be scheduled to run on a CPU other than this one. The delay
+ // in getting that thread to run means that this one can manage to re-claim the
+ // mutex before the other thread gets to run. So we add a small delay here
+ User::After(100);
+ }
+
+
} while (running);
return(KErrNone);
}
@@ -209,27 +573,80 @@
return(KErrNone);
}
-struct SWaitSem
+
+/*----------------------------------------------------------------------------*/
+struct SWaitLock
{
- RSemaphore iSem;
+ enum {EDummy=-2, EPoll=-1, EInfinite=0};
+
+ static TInt WaitLockThread(TAny*);
+ void Start(RThread& aT, TThreadPriority aP=EPriorityLess);
+ void Wait(RThread& aT, TInt aResult);
+ TInt DoTest2(RThread& aT, TInt aTimeout, TInt aResult, TThreadPriority aP=EPriorityLess);
+ void Test2();
+ void TestSignalled();
+ void TestNotSignalled();
+ void TestState();
+
+
+ MLock* iLock;
TInt iTimeout;
};
-TInt WaitSemThread(TAny* a)
+TInt SWaitLock::WaitLockThread(TAny* a)
{
- SWaitSem& ws = *(SWaitSem*)a;
- return ws.iSem.Wait(ws.iTimeout);
+
+ if (doCpuLocking)
+ {
+ TInt r = LockCurrentThreadToCpu0();
+ if (KErrNone!=r) return r;
+ // Rendevous was requested
+ RThread::Rendezvous(KErrNone);
+ }
+
+ SWaitLock& w = *(SWaitLock*)a;
+ TInt lfl = w.iLock->Flags();
+ TBool limit1 = lfl & MLock::ELimit1;
+ TInt r;
+ switch (w.iTimeout)
+ {
+ case EDummy:
+ return KErrNone;
+ case EPoll:
+ r = w.iLock->Poll();
+ break;
+ case EInfinite:
+ w.iLock->Wait();
+ r = KErrNone;
+ break;
+ default:
+ r = w.iLock->Wait(w.iTimeout);
+ break;
+ }
+ if (limit1 && r==KErrNone)
+ w.iLock->Signal();
+ return r;
}
-void StartWaitSemThread(RThread& aT, SWaitSem& aW, TThreadPriority aP=EPriorityLess)
+void SWaitLock::Start(RThread& aT, TThreadPriority aP)
{
- TInt r = aT.Create(KNullDesC, &WaitSemThread, 0x1000, 0x1000, 0x1000, &aW);
+ TRequestStatus st;
+ TInt r = aT.Create(KNullDesC, &WaitLockThread, 0x1000, 0x1000, 0x1000, this);
test_KErrNone(r);
aT.SetPriority(aP);
+ if (doCpuLocking)
+ {
+ aT.Rendezvous(st);
+ }
aT.Resume();
+ if (doCpuLocking)
+ {
+ User::WaitForRequest(st);
+ test_KErrNone(st.Int());
+ }
}
-void WaitForWaitSemThread(RThread& aT, TInt aResult)
+void SWaitLock::Wait(RThread& aT, TInt aResult)
{
TRequestStatus s;
aT.Logon(s);
@@ -240,32 +657,67 @@
CLOSE_AND_WAIT(aT);
}
-TInt DummyThread(TAny*)
+TInt SWaitLock::DoTest2(RThread& aT, TInt aTimeout, TInt aResult, TThreadPriority aP)
{
- return 0;
+ TTime initial;
+ TTime final;
+ iTimeout = aTimeout;
+ initial.HomeTime();
+ Start(aT, aP);
+ Wait(aT, aResult);
+ final.HomeTime();
+ TInt elapsed = I64INT(final.Int64()-initial.Int64());
+ return elapsed;
+ }
+
+void SWaitLock::TestSignalled()
+ {
+ TInt r = iLock->Poll();
+ if (r == KErrNotSupported)
+ r = iLock->Wait(1);
+ test_KErrNone(r);
}
-void TestSemaphore2()
+void SWaitLock::TestNotSignalled()
+ {
+ TInt r = iLock->Poll();
+ if (r == KErrNotSupported)
+ r = iLock->Wait(1);
+ test_Equal(KErrTimedOut, r);
+ }
+
+void SWaitLock::TestState()
{
- test.Start(_L("Test semaphore wait with timeout"));
- SWaitSem ws;
+ if (iLock->Flags() & MLock::ELimit1)
+ TestSignalled(); // not signalled afterwards
+ else
+ TestNotSignalled();
+ }
+
+void SWaitLock::Test2()
+ {
+ test.Start(_L("SWaitLock::Test2"));
RThread t;
+ RThread t2;
TTime initial;
TTime final;
- TInt elapsed=0;
- TInt r = ws.iSem.CreateLocal(0);
- test_KErrNone(r);
+ TInt elapsed = 0;
+ TInt r = 0;
+ TInt lfl = iLock->Flags();
+ TBool nestable = lfl & MLock::ENestable;
+ TBool limit1 = lfl & MLock::ELimit1;
+ TBool pollable = lfl & MLock::EPollable;
+ TBool to = lfl & MLock::ETimeoutAvail;
+ TBool lto = lfl & MLock::ELooseTimeout;
RThread().SetPriority(EPriorityAbsoluteVeryLow);
TInt threadcount=0;
+ iTimeout = EDummy;
initial.HomeTime();
while (elapsed<1000000)
{
- r = t.Create(KNullDesC, &DummyThread, 0x1000, NULL, NULL);
- test_KErrNone(r);
- t.SetPriority(EPriorityMore);
- t.Resume();
- t.Close();
+ Start(t, EPriorityMore);
+ Wait(t, KErrNone);
++threadcount;
final.HomeTime();
elapsed = I64INT(final.Int64()-initial.Int64());
@@ -275,125 +727,735 @@
TInt overhead = 1000000/threadcount;
test.Printf(_L("overhead = %dus\n"),overhead);
- ws.iTimeout=1000000;
- initial.HomeTime();
- StartWaitSemThread(t, ws);
- WaitForWaitSemThread(t, KErrTimedOut);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- test(elapsed>=900000+overhead && elapsed<1500000+overhead);
+ iLock->Wait();
- ws.iTimeout=-1;
- initial.HomeTime();
- StartWaitSemThread(t, ws);
- WaitForWaitSemThread(t, KErrArgument);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
+ if (to)
+ {
+ elapsed = DoTest2(t, 1000000, KErrTimedOut);
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed>=900000+overhead && elapsed<1500000+overhead);
+ elapsed = DoTest2(t, -99, KErrArgument);
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ }
- ws.iTimeout=2000000;
- initial.HomeTime();
- StartWaitSemThread(t, ws);
- User::After(1000000);
- ws.iSem.Signal();
- WaitForWaitSemThread(t, KErrNone);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- test(elapsed>=900000+overhead && elapsed<1500000+overhead);
+ if (pollable)
+ {
+ test.Printf(_L("Testing Poll() function\n"));
+ r = iLock->Poll();
+ test_Equal((nestable ? KErrNone : KErrTimedOut), r);
+ if (nestable)
+ {
+ iTimeout=EPoll;
+ r = iLock->Poll();
+ test_KErrNone(r);
+ iLock->Signal();
+ Start(t, EPriorityMore);
+ Wait(t, KErrTimedOut);
+ }
+ iLock->Signal();
+ if (nestable)
+ {
+ iTimeout=EPoll;
+ r = iLock->Poll();
+ test_KErrNone(r);
+ iLock->Signal();
+ Start(t, EPriorityMore);
+ Wait(t, KErrTimedOut);
+ iLock->Signal();
+ Start(t, EPriorityMore);
+ Wait(t, KErrNone);
+ }
+ r = iLock->Poll();
+ test_KErrNone(r);
+ if (!nestable)
+ {
+ r = iLock->Poll();
+ test_Equal(KErrTimedOut, r);
+ iLock->Signal();
+ if (!limit1)
+ {
+ iLock->Signal();
+ r = iLock->Poll();
+ test_KErrNone(r);
+ }
+ r = iLock->Poll();
+ test_KErrNone(r);
+ r = iLock->Poll();
+ test_Equal(KErrTimedOut, r);
+ }
+ elapsed = DoTest2(t, EPoll, KErrTimedOut);
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed<=50000+3*overhead);
+ iLock->Signal();
+ elapsed = DoTest2(t, EPoll, KErrNone);
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed<=50000+3*overhead);
+ TestState();
+ iLock->Signal();
+ r = LockCurrentThreadToCpu0(ETrue);
+ test_KErrNone(r);
+ Start(t, EPriorityMuchMore);
+ Start(t2, EPriorityMore);
+ test_Equal(EExitKill, t2.ExitType());
+ test_Equal(EExitKill, t.ExitType());
+ Wait(t2, limit1 ? KErrNone : KErrTimedOut);
+ Wait(t, KErrNone);
+ r = UnlockCurrentThreadToCpu0(ETrue);
+ test_KErrNone(r);
+ TestState();
+ }
+ else
+ {
+ test.Printf(_L("Poll() function not supported\n"));
+ }
- ws.iTimeout=100000;
- StartWaitSemThread(t, ws, EPriorityMore);
- t.Suspend();
- ws.iSem.Signal();
- User::After(200000);
- t.Resume();
- WaitForWaitSemThread(t, KErrTimedOut);
- test_KErrNone(ws.iSem.Wait(1));
+ if (to)
+ {
+ iTimeout=2000000;
+ initial.HomeTime();
+ Start(t);
+ User::After(1000000);
+ iLock->Signal();
+ Wait(t, KErrNone);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed>=900000+overhead && elapsed<1500000+overhead);
+ TestState();
- ws.iTimeout=100000;
- StartWaitSemThread(t, ws, EPriorityMore);
- t.Suspend();
- ws.iSem.Signal();
- User::After(50000);
- t.Resume();
- WaitForWaitSemThread(t, KErrNone);
- test_Equal(KErrTimedOut, ws.iSem.Wait(1));
+ r = LockCurrentThreadToCpu0(ETrue);
+ test_KErrNone(r);
- RThread t2;
- ws.iTimeout=100000;
- StartWaitSemThread(t, ws, EPriorityMuchMore);
- StartWaitSemThread(t2, ws, EPriorityMore);
- t.Suspend();
- ws.iSem.Signal();
- test_Equal(EExitKill, t2.ExitType());
- test_Equal(EExitPending, t.ExitType());
- t.Resume();
- WaitForWaitSemThread(t, KErrTimedOut);
- WaitForWaitSemThread(t2, KErrNone);
- test_Equal(KErrTimedOut, ws.iSem.Wait(1));
+ if (!lto)
+ {
+ iTimeout=100000;
+ Start(t, EPriorityMore);
+ t.Suspend();
+ iLock->Signal();
+ User::After(200000);
+ t.Resume();
+ Wait(t, KErrTimedOut);
+ TestSignalled();
- ws.iTimeout=1000000;
- initial.HomeTime();
- StartWaitSemThread(t2, ws, EPriorityMore);
- StartWaitSemThread(t, ws, EPriorityMuchMore);
- ws.iSem.Signal();
- WaitForWaitSemThread(t, KErrNone);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- WaitForWaitSemThread(t2, KErrTimedOut);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
+ iTimeout=100000;
+ Start(t, EPriorityMore);
+ t.Suspend();
+ iLock->Signal();
+ User::After(50000);
+ t.Resume();
+ Wait(t, KErrNone);
+ TestState();
+
+ iTimeout=100000;
+ Start(t, EPriorityMuchMore);
+ Start(t2, EPriorityMore);
+ t.Suspend();
+ iLock->Signal();
+ test_Equal(EExitKill, t2.ExitType());
+ test_Equal(EExitPending, t.ExitType());
+ t.Resume();
+ Wait(t, limit1 ? KErrNone : KErrTimedOut);
+ Wait(t2, KErrNone);
+ TestState();
+ }
- ws.iTimeout=1000000;
- initial.HomeTime();
- StartWaitSemThread(t2, ws, EPriorityMore);
- StartWaitSemThread(t, ws, EPriorityMuchMore);
- WaitForWaitSemThread(t, KErrTimedOut);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- WaitForWaitSemThread(t2, KErrTimedOut);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
+ iTimeout=1000000;
+ initial.HomeTime();
+ Start(t2, EPriorityMore);
+ Start(t, EPriorityMuchMore);
+ iLock->Signal();
+ Wait(t, KErrNone);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ Wait(t2, limit1 ? KErrNone : KErrTimedOut);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ if (!limit1)
+ {
+ test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
+ }
+ TestState();
+
+ iTimeout=1000000;
+ initial.HomeTime();
+ Start(t2, EPriorityMore);
+ Start(t, EPriorityMuchMore);
+ Wait(t, KErrTimedOut);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ Wait(t2, KErrTimedOut);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
- ws.iTimeout=1000000;
- initial.HomeTime();
- StartWaitSemThread(t2, ws, EPriorityMore);
- StartWaitSemThread(t, ws, EPriorityMuchMore);
- t.Kill(299792458);
- WaitForWaitSemThread(t2, KErrTimedOut);
- WaitForWaitSemThread(t, 299792458);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
+ iTimeout=1000000;
+ initial.HomeTime();
+ Start(t2, EPriorityMore);
+ Start(t, EPriorityMuchMore);
+ t.Kill(299792458);
+ Wait(t2, KErrTimedOut);
+ Wait(t, 299792458);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed>=900000+2*overhead && elapsed<1500000+2*overhead);
- ws.iTimeout=1000000;
- initial.HomeTime();
- StartWaitSemThread(t, ws, EPriorityMore);
- StartWaitSemThread(t2, ws, EPriorityMuchMore);
- test_Equal(EExitPending, t.ExitType());
- test_Equal(EExitPending, t2.ExitType());
- ws.iSem.Close();
- test_Equal(EExitKill, t.ExitType());
- test_Equal(EExitKill, t2.ExitType());
- WaitForWaitSemThread(t2, KErrGeneral);
- WaitForWaitSemThread(t, KErrGeneral);
- final.HomeTime();
- elapsed = I64INT(final.Int64()-initial.Int64());
- test.Printf(_L("Time taken = %dus\n"), elapsed);
- test(elapsed<=50000+3*overhead);
-
+ iTimeout=1000000;
+ initial.HomeTime();
+ Start(t, EPriorityMore);
+ Start(t2, EPriorityMuchMore);
+ test_Equal(EExitPending, t.ExitType());
+ test_Equal(EExitPending, t2.ExitType());
+ iLock->Release();
+ test_Equal(EExitKill, t.ExitType());
+ test_Equal(EExitKill, t2.ExitType());
+ Wait(t2, KErrGeneral);
+ Wait(t, KErrGeneral);
+ final.HomeTime();
+ elapsed = I64INT(final.Int64()-initial.Int64());
+ test.Printf(_L("Time taken = %dus\n"), elapsed);
+ test(elapsed<=50000+3*overhead);
+ r = UnlockCurrentThreadToCpu0(ETrue);
+ test_KErrNone(r);
+ }
+ else
+ {
+ test.Printf(_L("Timed waits not supported\n"));
+ iLock->Release();
+ }
test.End();
}
+volatile TBool NoRepeat = EFalse;
+void TestPollTimeout()
+ {
+ SWaitLock w;
+ do {
+ test.Printf(_L("TestPollTimeout - RSemaphore\n"));
+ LockS ls;
+ w.iLock = &ls;
+ w.Test2(); // Release()s ls
+ } while(NoRepeat);
+ do {
+ test.Printf(_L("TestPollTimeout - RMutex\n"));
+ LockM lm;
+ w.iLock = &lm;
+ w.Test2(); // Release()s lm
+ } while(NoRepeat);
+ do {
+ test.Printf(_L("TestPollTimeout - RFastLock\n"));
+ LockFL fl;
+ w.iLock = &fl;
+ w.Test2(); // Release()s fl
+ } while(NoRepeat);
+ }
+
+
+/*----------------------------------------------------------------------------*/
+class CMXThreadGrp;
+
+struct SStats
+ {
+ SStats();
+ void Add(TInt aValue);
+ void Add(const SStats& aS);
+ TInt Count() const {return iN;}
+ TInt Min() const;
+ TInt Max() const;
+ TInt Mean() const;
+
+ TInt64 iSum;
+ TInt iMin;
+ TInt iMax;
+ TInt iN;
+ TInt iSp;
+ };
+
+SStats::SStats()
+ {
+ iSum = 0;
+ iMax = KMinTInt;
+ iMin = ~iMax;
+ iN = 0;
+ iSp = 0;
+ }
+
+void SStats::Add(TInt aValue)
+ {
+ TInt64 v = aValue;
+ iSum += v;
+ ++iN;
+ if (aValue > iMax)
+ iMax = aValue;
+ if (aValue < iMin)
+ iMin = aValue;
+ }
+
+void SStats::Add(const SStats& a)
+ {
+ iN += a.iN;
+ iSum += a.iSum;
+ if (a.iMax > iMax)
+ iMax = a.iMax;
+ if (a.iMin < iMin)
+ iMin = a.iMin;
+ }
+
+TInt SStats::Min() const
+ {return iN ? iMin : 0;}
+
+TInt SStats::Max() const
+ {return iN ? iMax : 0;}
+
+TInt SStats::Mean() const
+ {
+ if (iN==0)
+ return 0;
+ return (TInt)(iSum/TInt64(iN));
+ }
+
+TUint32 ticks_to_us(TUint32 aTicks, TUint32 aF)
+ {
+ TUint64 x = aTicks;
+ TUint64 f = aF;
+ x *= TUint64(1000000);
+ x += (f>>1);
+ x /= f;
+ return I64LOW(x);
+ }
+
+class CMXThread : public CBase
+ {
+private:
+ CMXThread();
+ ~CMXThread();
+ static CMXThread* New(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD);
+ void Start();
+ void Wait();
+ TInt Construct(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD);
+ TInt Steps();
+ TInt Action();
+ TInt Run();
+ static TInt ThreadFunc(TAny*);
+ void PrintStats();
+private:
+ TUint64 iSeed;
+ RThread iThread;
+ TRequestStatus iExitStatus;
+ CMXThreadGrp* iG;
+ LFSR* iDummyLfsr;
+ TUint32 iId;
+ TUint32 iLambda;
+ TUint32 iDummySteps;
+ TInt iTotalSteps;
+ TInt iIterations;
+ TInt iPolls;
+ TInt iPollFails;
+ SStats iStats;
+ SStats iTimeoutStats;
+private:
+ friend class CMXThreadGrp;
+ };
+
+class CMXThreadGrp : public CBase
+ {
+public:
+ static CMXThreadGrp* New(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime);
+ CMXThreadGrp();
+ ~CMXThreadGrp();
+ TBool Run();
+ void PrintStats();
+private:
+ TInt Construct(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime);
+private:
+ TInt iNThreads;
+ CMXThread** iThreads;
+ MLock* iLock;
+ LFSR* iLfsr;
+ LFSR* iLfsr0;
+ TUint32 iNTickPeriod;
+ TUint32 iFCF;
+ TUint32 iNTicks;
+ TInt iTotalSteps;
+ TInt iIterations;
+ TInt iPolls;
+ TInt iPollFails;
+ SStats iStats;
+ SStats iTimeoutStats;
+private:
+ friend class CMXThread;
+ };
+
+CMXThread::CMXThread()
+ {
+ iThread.SetHandle(0);
+ }
+
+CMXThread::~CMXThread()
+ {
+ delete iDummyLfsr;
+ if (iThread.Handle())
+ {
+ if (iThread.ExitType() == EExitPending)
+ {
+ iThread.Kill(0);
+ Wait();
+ }
+ CLOSE_AND_WAIT(iThread);
+ }
+ }
+
+void CMXThread::PrintStats()
+ {
+ test.Printf(_L("Thread %d:\n"), iId);
+ test.Printf(_L(" ST:%10d IT:%10d P:%10d PF:%10d TO:%10d\n"), iTotalSteps, iIterations, iPolls, iPollFails, iTimeoutStats.Count());
+ TUint32 min, max, mean;
+ min = ticks_to_us(iStats.Min(), iG->iFCF);
+ max = ticks_to_us(iStats.Max(), iG->iFCF);
+ mean = ticks_to_us(iStats.Mean(), iG->iFCF);
+ test.Printf(_L(" Lock acquire times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
+ min = ticks_to_us(iTimeoutStats.Min(), iG->iFCF);
+ max = ticks_to_us(iTimeoutStats.Max(), iG->iFCF);
+ mean = ticks_to_us(iTimeoutStats.Mean(), iG->iFCF);
+ test.Printf(_L(" Lock timeout times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
+ }
+
+TInt CMXThread::Construct(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD)
+ {
+ iG = aG;
+ iId = aId;
+ iLambda = aL;
+ iDummySteps = aD;
+ iSeed = iId + 1;
+ iDummyLfsr = new LFSR(785,693);
+ if (!iDummyLfsr)
+ return KErrNoMemory;
+ TBuf<16> name = _L("TSThrd");
+ name.AppendNum(iId);
+ TInt r = iThread.Create(name, &ThreadFunc, 0x1000, NULL, this);
+ if (r!=KErrNone)
+ return r;
+ iThread.Logon(iExitStatus);
+ if (iExitStatus != KRequestPending)
+ {
+ iThread.Kill(0);
+ iThread.Close();
+ iThread.SetHandle(0);
+ return iExitStatus.Int();
+ }
+ iThread.SetPriority(EPriorityLess);
+ return KErrNone;
+ }
+
+CMXThread* CMXThread::New(CMXThreadGrp* aG, TUint32 aId, TUint32 aL, TUint32 aD)
+ {
+ CMXThread* p = new CMXThread;
+ if (p)
+ {
+ TInt r = p->Construct(aG, aId, aL, aD);
+ if (r != KErrNone)
+ {
+ delete p;
+ p = 0;
+ }
+ }
+ return p;
+ }
+
+void CMXThread::Start()
+ {
+ iThread.Resume();
+ }
+
+void CMXThread::Wait()
+ {
+ User::WaitForRequest(iExitStatus);
+ }
+
+TInt CMXThread::ThreadFunc(TAny* aPtr)
+ {
+ CMXThread& a = *(CMXThread*)aPtr;
+ return a.Run();
+ }
+
+TInt CMXThread::Steps()
+ {
+ Random(iSeed);
+ return ExpRV(iSeed, iLambda, 1);
+ }
+
+TInt CMXThread::Action()
+ {
+ Random(iSeed);
+ return I64LOW(iSeed)%3;
+ }
+
+TInt CMXThread::Run()
+ {
+ MLock* lock = iG->iLock;
+ LFSR* lfsr = iG->iLfsr;
+ TInt lfl = lock->Flags();
+ TBool pollable = lfl & MLock::EPollable;
+ TBool to = lfl & MLock::ETimeoutAvail;
+ TUint32 start_time = User::NTickCount();
+ TInt r;
+
+ FOREVER
+ {
+ TUint32 now = User::NTickCount();
+ if (now - start_time >= iG->iNTicks)
+ break;
+ ++iIterations;
+ iDummyLfsr->Step(iDummySteps);
+ TInt action = Action();
+ TInt steps = Steps();
+ TUint32 initial = User::FastCounter();
+ if (action==2 && to)
+ {
+ r = lock->Wait(1000);
+ if (r!=KErrNone)
+ {
+ TUint32 final = User::FastCounter();
+ TInt elapsed = TInt(final - initial);
+ iTimeoutStats.Add(elapsed);
+ }
+ }
+ else if (action==1 && pollable)
+ {
+ ++iPolls;
+ r = lock->Poll();
+ if (r!=KErrNone)
+ ++iPollFails;
+ }
+ else
+ {
+ lock->Wait();
+ r = KErrNone;
+ }
+ if (r == KErrNone)
+ {
+ TUint32 final = User::FastCounter();
+ lfsr->Step(steps);
+ lock->Signal();
+ TInt elapsed = TInt(final - initial);
+ iTotalSteps += steps;
+ iStats.Add(elapsed);
+ }
+ }
+
+ return KErrNone;
+ }
+
+CMXThreadGrp* CMXThreadGrp::New(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime)
+ {
+ CMXThreadGrp* p = new CMXThreadGrp;
+ if (p)
+ {
+ TInt r = p->Construct(aLock, aNThreads, aLambda, aDummySteps, aTime);
+ if (r != KErrNone)
+ {
+ delete p;
+ p = 0;
+ }
+ }
+ return p;
+ }
+
+CMXThreadGrp::CMXThreadGrp()
+ {
+ }
+
+TInt CMXThreadGrp::Construct(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime)
+ {
+ iNThreads = aNThreads;
+ iLock = aLock;
+ TInt r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)iFCF);
+ if (r!=KErrNone)
+ return r;
+ r = HAL::Get(HAL::ENanoTickPeriod, (TInt&)iNTickPeriod);
+ if (r!=KErrNone)
+ return r;
+ iNTicks = (aTime+iNTickPeriod-1)/iNTickPeriod;
+ iLfsr = new LFSR(785,693);
+ iLfsr0 = new LFSR(785,693);
+ if (!iLfsr || !iLfsr0)
+ return KErrNoMemory;
+ iThreads = (CMXThread**)User::AllocZ(iNThreads*sizeof(CMXThread*));
+ if (!iThreads)
+ return KErrNoMemory;
+ TInt i;
+ for (i=0; i<iNThreads; ++i)
+ {
+ iThreads[i] = CMXThread::New(this, i, aLambda, aDummySteps);
+ if (!iThreads[i])
+ return KErrNoMemory;
+ }
+ return KErrNone;
+ }
+
+CMXThreadGrp::~CMXThreadGrp()
+ {
+ delete iLfsr;
+ delete iLfsr0;
+ if (iThreads)
+ {
+ TInt i;
+ for (i=0; i<iNThreads; ++i)
+ delete iThreads[i];
+ }
+ User::Free(iThreads);
+ }
+
+TBool CMXThreadGrp::Run()
+ {
+ TInt i;
+ test.Printf(_L("Starting test with N=%d L=%d D=%d T=%d\n"), iNThreads, iThreads[0]->iLambda, iThreads[0]->iDummySteps, iNTicks);
+ for (i=0; i<iNThreads; ++i)
+ iThreads[i]->Start();
+ for (i=0; i<iNThreads; ++i)
+ iThreads[i]->Wait();
+ for (i=0; i<iNThreads; ++i)
+ {
+ iTotalSteps += iThreads[i]->iTotalSteps;
+ iIterations += iThreads[i]->iIterations;
+ iPolls += iThreads[i]->iPolls;
+ iPollFails += iThreads[i]->iPollFails;
+ iStats.Add(iThreads[i]->iStats);
+ iTimeoutStats.Add(iThreads[i]->iTimeoutStats);
+ }
+ test.Printf(_L("Total LFSR steps %d\n"), iTotalSteps);
+ iLfsr0->Step(iTotalSteps);
+ TBool ok = (*iLfsr == *iLfsr0);
+ return ok;
+ }
+
+void CMXThreadGrp::PrintStats()
+ {
+ TInt i;
+ for (i=0; i<iNThreads; ++i)
+ {
+ iThreads[i]->PrintStats();
+ }
+ test.Printf(_L("TOTALS:\n"));
+ test.Printf(_L(" ST:%10d IT:%10d P:%10d PF:%10d TO:%10d\n"), iTotalSteps, iIterations, iPolls, iPollFails, iTimeoutStats.Count());
+ TUint32 min, max, mean;
+ min = ticks_to_us(iStats.Min(), iFCF);
+ max = ticks_to_us(iStats.Max(), iFCF);
+ mean = ticks_to_us(iStats.Mean(), iFCF);
+ test.Printf(_L(" Lock acquire times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
+ min = ticks_to_us(iTimeoutStats.Min(), iFCF);
+ max = ticks_to_us(iTimeoutStats.Max(), iFCF);
+ mean = ticks_to_us(iTimeoutStats.Mean(), iFCF);
+ test.Printf(_L(" Lock timeout times MIN %10d MAX %10d AVG %10d\n"), min, max, mean);
+ }
+
+TUint32 Calibrate()
+ {
+ TUint32 fcf;
+ TInt r = HAL::Get(HAL::EFastCounterFrequency, (TInt&)fcf);
+ test_KErrNone(r);
+ LFSR* d = new LFSR(785,693);
+ test(d!=0);
+ TInt steps = 2;
+ TUint32 ticks = fcf/10;
+ TUint32 elapsed;
+ FOREVER
+ {
+ TUint32 h0 = User::FastCounter();
+ d->Step(steps);
+ TUint32 h1 = User::FastCounter();
+ elapsed = h1 - h0;
+ if (elapsed > ticks)
+ break;
+ steps *= 2;
+ }
+ delete d;
+ test.Printf(_L("%d steps in %d fast ticks\n"), steps, elapsed);
+ TUint64 x = elapsed;
+ TUint64 s = steps;
+ TUint64 y = fcf;
+ y /= x;
+ s *= y; // steps per second
+ TUint32 res = I64LOW(s);
+ test.Printf(_L("%d steps per second\n"), res);
+ return res;
+ }
+
+void DoTMX(MLock* aLock, TInt aNThreads, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime, TBool aShouldFail=EFalse)
+ {
+ CMXThreadGrp* g = CMXThreadGrp::New(aLock, aNThreads, aLambda, aDummySteps, aTime);
+ test(g!=0);
+ TBool ok = g->Run();
+ if (aShouldFail)
+ {
+ test(!ok);
+ }
+ else
+ {
+ test(ok);
+ }
+ g->PrintStats();
+ delete g;
+ }
+
+void DoTMX(MLock* aLock, TUint32 aLambda, TUint32 aDummySteps, TUint32 aTime)
+ {
+ TInt n;
+ for (n=1; n<=4; ++n)
+ {
+ TUint32 l = (n<2) ? aLambda : (aLambda/(n-1));
+ DoTMX(aLock, n, l, aDummySteps, aTime);
+ }
+ aLock->Release();
+ }
+
+
+void TestMutualExclusion()
+ {
+ TInt ntp;
+ TInt r = HAL::Get(HAL::ENanoTickPeriod, ntp);
+ test_KErrNone(r);
+ test.Printf(_L("Nanokernel tick period = %dus\n"), ntp);
+ TUint32 sps = Calibrate();
+ TUint32 lambda = sps/2000;
+ TUint32 dummy = sps/2000;
+ TUint32 time = 5000000;
+ do {
+ test.Printf(_L("TestMutualExclusion - RSemaphore\n"));
+ LockS ls;
+ DoTMX(&ls, lambda, dummy, time);
+ } while(NoRepeat);
+ do {
+ test.Printf(_L("TestMutualExclusion - RSemaphore init=2\n"));
+ LockS ls2;
+ ls2.Signal(); // count=2
+ DoTMX(&ls2, 4, lambda, dummy, time, ETrue);
+ } while(NoRepeat);
+ do {
+ test.Printf(_L("TestMutualExclusion - RMutex\n"));
+ LockM lm;
+ DoTMX(&lm, lambda, dummy, time);
+ } while(NoRepeat);
+ do {
+ test.Printf(_L("TestMutualExclusion - RFastLock\n"));
+ LockFL fl;
+ DoTMX(&fl, lambda, dummy, time);
+ } while(NoRepeat);
+ do {
+ test.Printf(_L("TestMutualExclusion - RCriticalSection\n"));
+ LockCS cs;
+ DoTMX(&cs, lambda, dummy, time);
+ } while(NoRepeat);
+ }
+
+
+
+
+/*----------------------------------------------------------------------------*/
void TestSemaphore()
{
/*********** TO DO ************/
@@ -417,23 +1479,23 @@
test.Next(_L("Producer/Consumer scenario"));
// Test Rsemaphore with the producer/consumer scenario RThread thread1, thread2;
TRequestStatus stat1, stat2;
- test_KErrNone(mutex.CreateLocal());
- test_KErrNone(slotAvailable.CreateLocal(KMaxBufferSize));
- test_KErrNone(itemAvailable.CreateLocal(0));
- test_KErrNone(thread1.Create(_L("Thread1"),Producer,KDefaultStackSize,0x200,0x200,NULL));
- test_KErrNone(thread2.Create(_L("Thread2"),Consumer,KDefaultStackSize,0x200,0x200,NULL));
+ test(mutex.CreateLocal()==KErrNone);
+ test(slotAvailable.CreateLocal(KMaxBufferSize)==KErrNone);
+ test(itemAvailable.CreateLocal(0)==KErrNone);
+ test(thread1.Create(_L("Thread1"),Producer,KDefaultStackSize,0x200,0x200,NULL)==KErrNone);
+ test(thread2.Create(_L("Thread2"),Consumer,KDefaultStackSize,0x200,0x200,NULL)==KErrNone);
thread1.Logon(stat1);
thread2.Logon(stat2);
- test_Equal(KRequestPending, stat1.Int());
- test_Equal(KRequestPending, stat2.Int());
+ test(stat1==KRequestPending);
+ test(stat2==KRequestPending);
thread1.Resume();
thread2.Resume();
User::WaitForRequest(stat1);
User::WaitForRequest(stat2);
- test_KErrNone(stat1.Int());
- test_KErrNone(stat2.Int());
+ test(stat1==KErrNone);
+ test(stat2==KErrNone);
for(TInt jj=0;jj<KNumProducerItems;jj++)
- test_Equal(jj, consumerArray[jj]);
+ test(consumerArray[jj]==jj);
test.Next(_L("Close"));
mutex.Close();
@@ -446,7 +1508,7 @@
{
RMutex m;
test.Start(_L("Create"));
- test_KErrNone(m.CreateLocal());
+ test(m.CreateLocal()==KErrNone);
// Test RMutex::IsHeld()
test.Next(_L("IsHeld ?"));
@@ -466,7 +1528,7 @@
void TestMutex()
{
test.Start(_L("Create"));
- test_KErrNone(mutex.CreateLocal());
+ test(mutex.CreateLocal()==KErrNone);
test.Next(_L("Threads writing to arrays test"));
//
@@ -480,19 +1542,19 @@
//
arrayIndex=0;
RThread thread1,thread2;
- test_KErrNone(thread1.Create(_L("Thread1"),MutexThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL));
- test_KErrNone(thread2.Create(_L("Thread2"),MutexThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL));
+ test(thread1.Create(_L("Thread1"),MutexThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
+ test(thread2.Create(_L("Thread2"),MutexThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
TRequestStatus stat1,stat2;
thread1.Logon(stat1);
thread2.Logon(stat2);
- test_Equal(KRequestPending, stat1.Int());
- test_Equal(KRequestPending, stat2.Int());
+ test(stat1==KRequestPending);
+ test(stat2==KRequestPending);
thread1.Resume();
thread2.Resume();
User::WaitForRequest(stat1);
User::WaitForRequest(stat2);
- test_KErrNone(stat1.Int());
- test_KErrNone(stat2.Int());
+ test(stat1==KErrNone);
+ test(stat2==KErrNone);
TInt thread1ActualCount=0;
TInt thread2ActualCount=0;
TInt ii=0;
@@ -504,11 +1566,11 @@
thread2ActualCount++;
ii++;
}
- test.Printf(_L("T1 %d T1ACT %d T2 %d T2ACT %d"),thread1Count,thread1ActualCount,thread2Count,thread2ActualCount);
- test_Equal(thread1Count, thread1ActualCount);
- test_Equal(thread2Count, thread2ActualCount);
- test_Equal(thread2Count, thread1Count);
- test_Equal((KMaxArraySize>>1), thread1Count);
+ test.Printf(_L("T1 %d T1ACT %d T2 %d T2ACT %d\n"),thread1Count,thread1ActualCount,thread2Count,thread2ActualCount);
+ test(thread1ActualCount==thread1Count);
+ test(thread2ActualCount==thread2Count);
+ test(thread1Count==thread2Count);
+ test(thread1Count==(KMaxArraySize>>1));
test.Next(_L("Close"));
CLOSE_AND_WAIT(thread1);
@@ -524,7 +1586,7 @@
{
test.Start(_L("Create"));
- test_KErrNone(criticalSn.CreateLocal());
+ test(criticalSn.CreateLocal()==KErrNone);
/***************** TO DO ***********************
@@ -553,20 +1615,21 @@
// threads think.
//
arrayIndex=0;
+
RThread thread1,thread2;
- test_KErrNone(thread1.Create(_L("Thread1"),CriticalSnThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL));
- test_KErrNone(thread2.Create(_L("Thread2"),CriticalSnThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL));
+ test(thread1.Create(_L("Thread1"),CriticalSnThreadEntryPoint1,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
+ test(thread2.Create(_L("Thread2"),CriticalSnThreadEntryPoint2,KDefaultStackSize,0x2000,0x2000,NULL)==KErrNone);
TRequestStatus stat1,stat2;
thread1.Logon(stat1);
thread2.Logon(stat2);
- test_Equal(KRequestPending, stat1.Int());
- test_Equal(KRequestPending, stat2.Int());
+ test(stat1==KRequestPending);
+ test(stat2==KRequestPending);
thread1.Resume();
thread2.Resume();
User::WaitForRequest(stat1);
User::WaitForRequest(stat2);
- test_KErrNone(stat1.Int());
- test_KErrNone(stat2.Int());
+ test(stat1==KErrNone);
+ test(stat2==KErrNone);
TInt thread1ActualCount=0;
TInt thread2ActualCount=0;
TInt ii=0;
@@ -578,10 +1641,10 @@
thread2ActualCount++;
ii++;
}
- test_Equal(thread1Count, thread1ActualCount);
- test_Equal(thread2Count, thread2ActualCount);
- test_Equal(thread2Count, thread1Count);
- test_Equal((KMaxArraySize>>1), thread1Count);
+ test(thread1ActualCount==thread1Count);
+ test(thread2ActualCount==thread2Count);
+ test(thread1Count==thread2Count);
+ test(thread1Count==(KMaxArraySize>>1));
test.Next(_L("Close"));
CLOSE_AND_WAIT(thread1);
@@ -593,22 +1656,13 @@
GLDEF_C TInt E32Main()
{
- TInt cpus = UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0);
- if (cpus != 1)
- {
- test(cpus>1);
- // This test will require compatibility mode (and probably other changes)
- // to work on SMP - it depends on explicit scheduling order.
- test.Printf(_L("T_SEMUTX skipped, does not work on SMP\n"));
- return KErrNone;
- }
-
test.Title();
__UHEAP_MARK;
+ TestMutualExclusion();
+ TestPollTimeout();
test.Start(_L("Test RSemaphore"));
TestSemaphore();
- TestSemaphore2();
test.Next(_L("Test RMutex"));
TestMutex();
TestMutex2();