sl@0: // Copyright (c) 2002-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: // sl@0: sl@0: #include sl@0: #include "t_property.h" sl@0: sl@0: _LIT(KTestName,"t_stress_property"); sl@0: sl@0: RTest test(KTestName); sl@0: sl@0: const TInt32 KUidPropTestCategoryValue = 0x101f75b8; sl@0: const TUid KPropTestCategory = { KUidPropTestCategoryValue }; sl@0: sl@0: #define TEST_TIME 36000 //10 hours sl@0: sl@0: #define TEST_ERROR(rl,rr) { if((TInt)rl!=(TInt)rr) { ExitThread(rl, rr, __LINE__); return KErrGeneral; } } sl@0: sl@0: TBool volatile StopAndExit = EFalse; sl@0: TTime startTime; sl@0: sl@0: LOCAL_D void ExitThread(TInt rl, TInt rr, TInt aLine) sl@0: { sl@0: test.Printf(_L("Test '%S' failed at line %d; Expected value=%d Actual value=%d; \n"), &KTestName, aLine, rr, rl); sl@0: StopAndExit = ETrue; sl@0: //delete if it's not deleted, to wake up subscribing threads waiting for events on this property sl@0: RProperty::Delete(KPropTestCategory,0); sl@0: } sl@0: sl@0: LOCAL_D TInt LowPriorityThread1(TAny* /*aParameter*/) sl@0: { sl@0: RProperty prop; sl@0: TBuf8<512> buffer; sl@0: TInt length = 2; sl@0: sl@0: TInt r=prop.Attach(KPropTestCategory,0); sl@0: TEST_ERROR(r,KErrNone); sl@0: sl@0: while(!StopAndExit) sl@0: { sl@0: buffer.SetLength(length); sl@0: buffer[0]=(TUint8)(length%256); sl@0: buffer[length-1]=(TUint8)((length-1)%256); sl@0: ++length; sl@0: if(length>512) sl@0: length=2; sl@0: r=prop.Set(buffer); sl@0: if(r!=KErrArgument && r!=KErrNotFound) sl@0: { sl@0: //if it's not of type EInt and defined sl@0: TEST_ERROR(r,KErrNone); sl@0: } sl@0: User::AfterHighRes(0); sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: LOCAL_D TInt LowPriorityThread2(TAny* /*aParameter*/) sl@0: { sl@0: RProperty prop; sl@0: TBuf8<512> buffer; sl@0: sl@0: TInt r=prop.Attach(KPropTestCategory,0); sl@0: TEST_ERROR(r,KErrNone); sl@0: sl@0: while(!StopAndExit) sl@0: { sl@0: r=prop.Get(buffer); sl@0: if(r!=KErrArgument && r!=KErrNotFound) sl@0: { sl@0: //if it's not of type EInt and defined sl@0: TEST_ERROR(r,KErrNone); sl@0: TInt length=buffer.Length(); sl@0: if(length>0) sl@0: { sl@0: TEST_ERROR(buffer[0],length%256); sl@0: TEST_ERROR(buffer[length-1],(length-1)%256); sl@0: } sl@0: } sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: LOCAL_D TInt MediumPriorityThread(TAny* /*aParameter*/) sl@0: { sl@0: RProperty prop; sl@0: TBuf8<512> buffer; sl@0: sl@0: TInt r=prop.Attach(KPropTestCategory,0); sl@0: TEST_ERROR(r,KErrNone); sl@0: sl@0: TRequestStatus status; sl@0: sl@0: while(!StopAndExit) sl@0: { sl@0: prop.Subscribe(status); sl@0: sl@0: User::WaitForRequest(status); sl@0: if(StopAndExit) sl@0: break; sl@0: if(status.Int() != KErrNotFound) sl@0: { sl@0: //property is defined sl@0: TEST_ERROR(status.Int(),KErrNone); sl@0: sl@0: r=prop.Get(buffer); sl@0: if(r!=KErrArgument) sl@0: { sl@0: TEST_ERROR(r,KErrNone); sl@0: TInt length=buffer.Length(); sl@0: if(length>0) sl@0: { sl@0: TEST_ERROR(buffer[0],length%256); sl@0: TEST_ERROR(buffer[length-1],(length-1)%256); sl@0: } sl@0: } sl@0: } sl@0: } sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: LOCAL_D TInt HighPriorityThread(TAny* /*aParameter*/) sl@0: { sl@0: sl@0: TInt type=RProperty::EInt; sl@0: TInt iteration=0; sl@0: TInt r; sl@0: sl@0: while(!StopAndExit) sl@0: { sl@0: User::AfterHighRes(1000); //wait for 1ms sl@0: sl@0: // test.Printf(_L("Deleting property\r\n")); sl@0: r=RProperty::Delete(KPropTestCategory,0); sl@0: TEST_ERROR(r,KErrNone); sl@0: sl@0: // test.Printf(_L("Defining property\r\n")); sl@0: r=RProperty::Define(KPropTestCategory,0,type, KPassPolicy, KPassPolicy); sl@0: TEST_ERROR(r,KErrNone); sl@0: sl@0: type=(type+1)%RProperty::ETypeLimit; sl@0: sl@0: if(1000 == ++iteration) sl@0: { sl@0: //check if we should exit sl@0: TTimeIntervalSeconds timeTaken; sl@0: TTime time; sl@0: time.HomeTime(); sl@0: TInt r = time.SecondsFrom(startTime, timeTaken); sl@0: TEST_ERROR(r,KErrNone); sl@0: sl@0: if(timeTaken.Int() >= TEST_TIME) sl@0: { sl@0: //we should exit sl@0: sl@0: StopAndExit=ETrue; sl@0: //delete if it's not deleted, to wake up subscribing threads waiting for events on this property sl@0: RProperty::Delete(KPropTestCategory,0); sl@0: break; sl@0: } sl@0: iteration=0; sl@0: } sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: { sl@0: sl@0: test.Start(_L("Stress test using multiple threads accessing the same property")); sl@0: sl@0: startTime.HomeTime(); sl@0: TInt r=RProperty::Define(KPropTestCategory,0,RProperty::EInt, KPassPolicy, KPassPolicy); sl@0: test(r==KErrNone); sl@0: sl@0: TRequestStatus status1; sl@0: TRequestStatus status2; sl@0: TRequestStatus status3; sl@0: TRequestStatus status4; sl@0: RThread t1; sl@0: RThread t2; sl@0: RThread t3; sl@0: RThread t4; sl@0: sl@0: r = t1.Create(KNullDesC, LowPriorityThread1, 0x2000, NULL, 0); sl@0: test(r == KErrNone); sl@0: t1.SetPriority(EPriorityLess); sl@0: t1.Logon(status1); sl@0: sl@0: r = t2.Create(KNullDesC, LowPriorityThread2, 0x2000, NULL, 0); sl@0: test(r == KErrNone); sl@0: t2.SetPriority(EPriorityLess); sl@0: t2.Logon(status2); sl@0: sl@0: r = t3.Create(KNullDesC, MediumPriorityThread, 0x2000, NULL, 0); sl@0: test(r == KErrNone); sl@0: t3.SetPriority(EPriorityNormal); sl@0: t3.Logon(status3); sl@0: sl@0: r = t4.Create(KNullDesC, HighPriorityThread, 0x2000, NULL, 0); sl@0: test(r == KErrNone); sl@0: t4.SetPriority(EPriorityMore); sl@0: t4.Logon(status4); sl@0: sl@0: TBool jit = User::JustInTime(); sl@0: User::SetJustInTime(EFalse); sl@0: sl@0: t1.Resume(); sl@0: t2.Resume(); sl@0: t3.Resume(); sl@0: t4.Resume(); sl@0: sl@0: User::WaitForRequest(status1); sl@0: User::WaitForRequest(status2); sl@0: User::WaitForRequest(status3); sl@0: User::WaitForRequest(status4); sl@0: sl@0: User::SetJustInTime(jit); sl@0: sl@0: test(status1 == KErrNone); sl@0: test(status2 == KErrNone); sl@0: test(status3 == KErrNone); sl@0: test(status4 == KErrNone); sl@0: sl@0: TTimeIntervalSeconds timeTaken; sl@0: TTime time; sl@0: time.HomeTime(); sl@0: r = time.SecondsFrom(startTime, timeTaken); sl@0: test(r==KErrNone); sl@0: TInt totalTime = timeTaken.Int(); sl@0: sl@0: TInt seconds = totalTime % 60; sl@0: TInt minutes = (totalTime / 60) % 60; sl@0: TInt hours = totalTime / 3600; sl@0: sl@0: test.Printf(_L("Time taken since test started: %d:%d:%d\r\n"), sl@0: hours, minutes, seconds); sl@0: sl@0: CLOSE_AND_WAIT(t1); sl@0: CLOSE_AND_WAIT(t2); sl@0: CLOSE_AND_WAIT(t3); sl@0: CLOSE_AND_WAIT(t4); sl@0: sl@0: test.End(); sl@0: sl@0: return KErrNone; sl@0: }