sl@0: // Copyright (c) 2007-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // e32test\nkernsa\tiedevents.cpp sl@0: // sl@0: // sl@0: sl@0: #include sl@0: sl@0: //--------------------------------------------------------------------------------------------------------------------- sl@0: //! @SYMTestCaseID KBASE-tiedevents-2448 sl@0: //! @SYMTestType UT sl@0: //! @SYMTestCaseDesc Verifying tied events sl@0: //! @SYMPREQ PREQ2094 sl@0: //! @SYMTestPriority High sl@0: //! @SYMTestActions sl@0: //! 1. TiedEventTest: run a reader thread (or several in a group) accessing a sl@0: //! common data block. A timer, IDFC, or interrupt handler writes to the sl@0: //! data block concurrently - first incrementing all data from 0 to 1 then sl@0: //! decrementing it again. sl@0: //! sl@0: //! @SYMTestExpectedResults sl@0: //! 1. When the timer/IDFC/interrupt is tied to the thread/group, then the sl@0: //! execution of the event should prevent the thread/group from running on sl@0: //! any processor, and thus readers should never be able to observe the sl@0: //! data being 1. When the event is not tied, the reader should observe sl@0: //! the data as being 1 at least some of the time. sl@0: //--------------------------------------------------------------------------------------------------------------------- sl@0: sl@0: #ifdef __SMP__ sl@0: sl@0: extern "C" void HijackSystemTimer(NSchedulable* aTieTo); sl@0: sl@0: const TInt FlagCount = 2048; sl@0: const TInt LoopCount = 100; sl@0: sl@0: volatile TUint32 Flags[FlagCount]; sl@0: volatile TBool Done; sl@0: volatile TUint32 FlagsSet; sl@0: NTimer* Timer; sl@0: TDfc* IDfc; sl@0: NThreadGroup TG; sl@0: NFastSemaphore* DoneSem; sl@0: sl@0: enum TTiedMode sl@0: { sl@0: ETimer, sl@0: EInterrupt, sl@0: EIDFC sl@0: }; sl@0: sl@0: // Used directly as the IDFC, also called by the timer function sl@0: void FiddleFlags(TAny*) sl@0: { sl@0: TInt i; sl@0: for (i=0; iOneShot(10); sl@0: } sl@0: sl@0: // Used for IDFC case as the timer function sl@0: void IDfcQFn(TAny*) sl@0: { sl@0: IDfc->Add(); sl@0: if (!__e32_atomic_load_acq32(&Done)) sl@0: Timer->OneShot(10); sl@0: } sl@0: sl@0: // Test thread, just looks for flags being set sl@0: void TiedEventThread(TAny*) sl@0: { sl@0: TInt cpu, i, j; sl@0: TUint32 set=0; sl@0: sl@0: for_each_cpu(cpu) sl@0: { sl@0: NKern::ThreadSetCpuAffinity(NKern::CurrentThread(), cpu); sl@0: sl@0: for (i=0; i 0, "Flag wasn't set, test broken?"); sl@0: } sl@0: #endif sl@0: sl@0: void TestTiedEvents() sl@0: { sl@0: #ifdef __SMP__ sl@0: TiedEventTest(EFalse, 1, ETimer); sl@0: TiedEventTest(ETrue, 1, ETimer); sl@0: TiedEventTest(EFalse, 2, ETimer); sl@0: TiedEventTest(ETrue, 2, ETimer); sl@0: sl@0: #ifndef __X86__ sl@0: TiedEventTest(EFalse, 1, EInterrupt); sl@0: TiedEventTest(ETrue, 1, EInterrupt); sl@0: TiedEventTest(EFalse, 2, EInterrupt); sl@0: TiedEventTest(ETrue, 2, EInterrupt); sl@0: #endif sl@0: sl@0: TiedEventTest(EFalse, 1, EIDFC); sl@0: TiedEventTest(ETrue, 1, EIDFC); sl@0: TiedEventTest(EFalse, 2, EIDFC); sl@0: TiedEventTest(ETrue, 2, EIDFC); sl@0: #endif sl@0: }