diff -r 000000000000 -r bde4ae8d615e os/kernelhwsrv/kerneltest/e32test/nkernsa/fastsem.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/os/kernelhwsrv/kerneltest/e32test/nkernsa/fastsem.cpp Fri Jun 15 03:10:57 2012 +0200 @@ -0,0 +1,198 @@ +// Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32test\nkernsa\fastsem.cpp +// +// + +#define __INCLUDE_NTHREADBASE_DEFINES__ + +#include + +void CheckSemaphoreCount(NFastSemaphore* aS, TInt aExpected) + { + TInt w = 0; + TInt r; + do { + r = WaitWithTimeout(aS, KMinTimeout); + TEST_RESULT1(r==KErrNone || r==KErrTimedOut, "Invalid return code %d", r); + if (r == KErrNone) + ++w; + } while(r == KErrNone); + TEST_RESULT2(w==aExpected, "Signalled %d, Waited %d", aExpected, w); + } + +void FSTest1(TAny* a) + { + TInt n = (TInt)a; + NFastSemaphore s(0); + + TInt i; + for (i=0; iiWaitState.ThreadIsBlocked(); } + }; +#endif + +void FSTest2Signaller(TAny* a) + { + SFSTest2Info& info = *(SFSTest2Info*)a; + while (!info.iStart) + { + } + NThreadBase* t = info.iSem.iOwningThread; + TInt count0=0; + TInt countneg=0; + TInt blocked=0; + TInt prev_block_count = info.iBlockCount; + TInt tries = 1; + TUint32 seed[2]; + seed[0] = NKern::CurrentCpu()+1; + seed[1] = 0; + while (!info.iStop) + { + TInt c = info.iSem.iCount; + if (c>=1) + continue; + if (--tries==0) + { + TInt bc; + do { + bc = info.iBlockCount; + } while (bc<=prev_block_count); + prev_block_count = bc; + tries = random(seed) & 127; + tries += 71; + } + TUint32 x = random(seed) & 63; + while (x) + --x; + c = info.iSem.iCount; + NKern::FSSignal(&info.iSem); + __e32_atomic_add_ord32(&info.iSignals, 1); + if (c==0) ++count0; + if (c<0) ++countneg; +#ifdef __SMP__ + if (NKTest::ThreadIsBlocked(t)) ++blocked; +#else + if (t->iNState == NThread::EWaitFastSemaphore) ++blocked; +#endif + } + TEST_PRINT1("Count =0 %d times", count0); + TEST_PRINT1("Count <0 %d times", countneg); + TEST_PRINT1("Blocked %d times", blocked); + } + +void FSTest2(TAny* a) + { + SFSTest2Info& info = *(SFSTest2Info*)a; + NFastSemaphore exitSem(0); + NKern::FSSetOwner(&info.iSem, 0); + info.iBlockCount = 0; + info.iWaits = 0; + info.iSignals = 0; + info.iStart = FALSE; + info.iStop = FALSE; + TInt cpu; + TInt threads = 0; + TInt this_cpu = NKern::CurrentCpu(); + for_each_cpu(cpu) + { + if (cpu==this_cpu) + CreateThreadSignalOnExit("FSTest2Sig0", &FSTest2Signaller0, 11, a, 0, KSmallTimeslice, &exitSem, cpu); + else + CreateThreadSignalOnExit("FSTest2Sig", &FSTest2Signaller, 12, a, 0, KSmallTimeslice, &exitSem, cpu); + ++threads; + } + + info.iStart = TRUE; + while(info.iWaits < 1048576) + { + NKern::FSWait(&info.iSem); + ++info.iWaits; + } + + info.iStop = TRUE; + while (threads--) + NKern::FSWait(&exitSem); + TEST_PRINT1("Leftover signals %d", info.iSignals-info.iWaits); + TInt r; + do { + r = WaitWithTimeout(&info.iSem, KMinTimeout); + TEST_RESULT1(r==KErrNone || r==KErrTimedOut, "Invalid return code %d", r); + if (r == KErrNone) + ++info.iWaits; + } while(r == KErrNone); + TEST_PRINT2("Signalled %d, Waited %d", info.iSignals, info.iWaits); + TEST_RESULT(info.iWaits==info.iSignals, "MISMATCH!"); + } + +void DoFsTest2() + { + SFSTest2Info info; + CreateThreadAndWaitForExit("FSTest2", &FSTest2, 12, (TAny*)&info, 0, KSmallTimeslice, 0); + } + + +void TestFastSemaphore() + { + TEST_PRINT("Testing Fast Semaphores..."); + + TInt cpu; + for_each_cpu(cpu) + { + DO_FS_TEST1(0,cpu); + DO_FS_TEST1(1,cpu); + DO_FS_TEST1(2,cpu); + DO_FS_TEST1(13,cpu); + } + + DoFsTest2(); + }