diff -r 000000000000 -r a41df078684a kerneltest/f32test/bench/t_notify_perf.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/bench/t_notify_perf.h Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,418 @@ +// Copyright (c) 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: +// f32test\bench\t_notify_perf.h +// +// + +#include +#include +#include +#include +#include +#include +#include + +// File operation made in test path to trigger notifications +enum TNotifyPerfTestOperations + { + // File Operations + EOpEnd, // indicates that a series of operations ended + EOpCreate, + EOpReplace, + EOpChgAttr, + EOpRename, + EOpWrite, + EOpResize, + EOpDelete, + EOpManyChanges, // Large number changes to a single file + EOpManyFiles, // Small changes to large number of files + + // Directory Operations + EOpCreateDir, + EOpRenameDir, + EOpDeleteDir, + + // Mixed Operations + EOpMixed // A series of mixed operations involving both Files and Dirs + }; + +enum TTestOptions + { + ////////////////////////////////////////////////////// + // Lowest 4 bit reserved for notification treads ID // + ////////////////////////////////////////////////////// + + // Test with a lot of filters for enhanced notification - 1st bit + // set - on; unset - off + EBigFilter = 0x0010, + + // Whether perform full directory scan and save the file changes to a list - 2nd bit + // set - perform; unset - not perform + EReportChg = 0x0020, + + // Whether use big buffer for enhanced notification- 3rd bit + // Set - big buffer(no overflow); unset - small(could have overflow) + EBigBuffer = 0x0040, + + // For multi clients test. Enhanced Notification Only! + // Mode 1: set a variety of different notifications, same on each clients - 4th bit + EMultiNoti1 = 0x0080, + + // For multi clients test. Enhanced Notification Only! + // Mode 2: set a variety of different notifications, in which some are different on each clients, + // and some are same on each clients, only support upto 4 clients - 5th bit + EMultiNoti2 = 0x0100, + + ENotPerfTestReserved6 = 0x0200, + ENotPerfTestReserved7 = 0x0400, + ENotPerfTestReserved8 = 0x0800, + + // Notification type - 13th - 16th bits + ENoNotify = 0x1000, // Test without notification + EEnhanced = 0x2000, // Using enhanced notification APIs + EOriginal = 0x4000, // Using original notification APIs + EPlugin = 0x8000, // Using Nokia plug-in for notification + }; + +// Note for Plugin Test +// the plugin test can only be run manually because the plugin is not available in KHS code base +// to run the test: +// 1. enable the MACRO above in the mmp +// 2. get a S60 environment +// 3. copy the MdsFileServerPlugin.ptx from the release(\Winscw or \Armv5 depend on what kind of test you want to run) +// directory of S60 to the equivalent folder of release directory of your epoc32 +// 4. when build a rom, include the MdsFileServerPlugin.ptx file in the rom +// 5. then you can run +enum TMdsFSPOperation + { + EMdsFSPOpEnable, + EMdsFSPOpDisable, + EMdsFSPOpRegisterNotification, + EMdsFSPOpAddNotificationPath, + EMdsFSPOpRemoveNotificationPath, + EMdsFSPOpAddIgnorePath, + EMdsFSPOpRemoveIgnorePath, + EMdsFSPOpNotificationCancel, + }; + +class TMdsFSPStatus + { +public: + TInt iFileEventType; + TInt iDriveNumber; + TFileName iFileName; + TFileName iNewFileName; + TUid iProcessId; + }; + +enum TMdsFileEventType + { + EMdsFileCreated, + EMdsFileRenamed, + EMdsFileModified, + EMdsFileReplaced, + EMdsFileDeleted, + EMdsDriveFormatted, + EMdsFileUnknown, + EMdsDirRenamed + }; + +typedef TPckgBuf TMdsFSPStatusPckg; + +const TInt KMdsFSPluginPosition = 0x200071CD; +_LIT(KPluginName, "MdsFileServerPlugin"); + +// the list of operations to be conducted during a test case +const TUint KDefaultOpList[] = {EOpCreate, EOpReplace, EOpChgAttr, EOpRename, EOpWrite, EOpResize, EOpDelete, EOpEnd}; +const TUint KDefaultOpListDir[] = {EOpCreateDir, EOpRenameDir, EOpDeleteDir, EOpEnd}; + +const TUint KManyChangesOpList[] = {EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpEnd}; +const TUint KManyFilesOpList[] = {EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpEnd}; +const TUint KMixedOpTestList[] = {EOpMixed, EOpMixed, EOpMixed, EOpMixed, EOpMixed, EOpEnd}; + +const TUint16 KNotifyOptionMask = 0xF000; +const TUint16 KNotifyTreadIdMask = 0x000F; + +// default time scale for timer +const TUint KDefaultTimeScale = 1000; // 1ms +const TInt KMaxHeapSize = 0x1000000; + +// used by SafeCheck +const TInt KNoThreadId = -1; + +// a Controllor of whether measure time and write loggs; +extern TBool gPerfMeasure; + +extern TFileName gTestPath; +extern TFileName gLogFilePath; + +// Threads handles +extern RArray gNotiThreads; +extern RThread gFileThread; + +extern TBuf<50> gLogPostFix; + +//------------------------------------------------------------- + +class CTimerLogger; + +// a wrapper for test settings +class TTestSetting + { + +public: + TTestSetting(); + TTestSetting(TInt aNumFiles, TInt aNumCli, TUint16 aOpt, const TUint* aOpList); + inline void Reset(); + +public: + TInt iNumFiles; + TInt iNumCli; + TUint16 iOption; + const TUint* iOperationList; + + }; + +// a wrapper of parameters for the main thread to pass into notification thread or file operation thread +struct TThreadParam + { + TTestSetting iSetting; + RSemaphore* iSmphFT; // Semophore used by File Thread for waiting for signals from Notification Threads + RSemaphore* iSmphNT; // Semophore used by Notification Threads for waiting for signals from File Thread + CTimerLogger* iLogger; // Logger used by Notification Threads; + RPointerArray* iLoggerArray; // a pointer to an array of pointers to CTimmerLoggger + }; + +// This is the controller of the plugin, it's a simplified copy of the plugin engine used in S60 internally +class CMdsPluginControl : public RPlugin + { +public: + inline void RegisterNotification( TMdsFSPStatusPckg& aMdsFSPStatus, TRequestStatus& aStat); + inline void AddNotificationPath( const TDesC& aPath ); + inline void RemoveNotificationPath( const TDesC& aPath ); + inline TInt Enable(); + inline TInt Disable(); + inline void NotificationCancel(); + }; + +// timer class, also responsible for writing logs +class CTimerLogger : public CBase + { + +public: + static CTimerLogger* NewL(const TFileName& aLogFile); + ~CTimerLogger(); + inline TInt MeasureStart(); + inline TInt MeasureEnd(); + inline TBool Timing(); + TInt Log(const TDesC& aDes, TBool aIsLine = ETrue); + TInt LogAndPrint(const TDesC& aDes, TBool aIsLine = ETrue); + TInt LogSettingDescription(const TInt aNumFile, const TInt aNumCli, const TUint16 aOption, TBool aNumOpVaries = EFalse); + TInt LogTestStepTime(TUint aOp, TInt aNum); + +private: + CTimerLogger(); + void ConstructL(const TFileName& aLogFile); + +private: + TBool iTiming; + TUint32 iTickNumber; + TUint iTimeScale; + TInt iTickPeriod; + TFileName iLogFile; + RFs iFs; + }; + +// the conductor of test cases +class CTestExecutor : public CBase + { + +public: + CTestExecutor(TTestSetting& aSetting); + ~CTestExecutor(); + + inline void SetTestSetting(TTestSetting& aSetting); + inline void LogDescription(); + + void RunTestCaseL(); + static void KillAllTestThreads(); + +private: + TTestSetting iTestSetting; + + }; + +// This class performs file operations +class CFileOperator : public CBase + { + +public: + CFileOperator(const TTestSetting& aSetting, RPointerArray& aLoggerArray, RSemaphore* aSmphFT, RSemaphore* aSmphNT); + ~CFileOperator(); + void DoChangesL(); + +private: + void DoCreateL(); + void DoReplaceL(); + void DoChangeAttL(); + void DoRenameL(); + void DoWriteL(); + void DoResizeL(); + void DoDeleteL(); + void DoCreateDirL(); + void DoRenameDirL(); + void DoDeleteDirL(); + void DoMixedOperationsL(); + + void DoManyChangesOnSingleFileL(); + void DoSmallChangesOnManyFilesL(); + + void MesureStartsAll(); + void WaitForSignalsAll(); + + void TestStepPrepare(TUint aOp); + void TestStepFinish(TUint aOp); + +private: + // test case will use the number iFirstFile and iNumFiles to generate test file names. + // For example: + // if iFirstFile = 0 and iNumFiles = 100, the test files will be 0000.tst, 0001.tst ... 0099.tst + // if iFirstFile = 21 and iNumFiles = 200, the test files will be 0021.tst, 0022.tst ... 0220.tst + // + // When doing rename or replace test, the new names for test will be the biggest existing file + // number + 1 to the number + iNumFiles. + // As a result, in the case of if iFirstFile = 0 and iNumFiles = 100: + // The exsting files should be 0000.tst ... 0099.tst + // Rename or Replace test will use the new names 0100.tst ... 0199.tst to replace or rename the + // existing files. + TInt iFirstFile; + + // Number of files for operating. + // Note: in "Large number changes to a single file" case, this indicates the number of changes made on the single file. + TInt iNumFiles; + TInt iNumCli; + TUint16 iOption; + const TUint* iCurrentOp; + + RPointerArray iLoggers; + RSemaphore* iSmphS; // Use for signaling Notification threads + RSemaphore* iSmphW; // Use for waiting signal from Notification threads + + RFs iFs; + }; + +// an operator to monitor notification watcher and test stopper +class CNotifyOperator : public CBase + { + +public: + CNotifyOperator(const TTestSetting& aSetting, RSemaphore* aSmphFT, RSemaphore* aSmphNT, CTimerLogger* aLogger); + ~CNotifyOperator(); + + void StartOperationL(); + +private: + void LogNotificationNumbers(TInt aNumNoti, TInt aNumIter, TInt aNumOverflow); + void LogTestResult(TInt aCounter, TInt aMeanCounter, TInt aOFCounter); + void TestChangeReport(TInt aNumChanges); + +private: + TInt iNumFiles; + TUint16 iOption; + const TUint* iCurrentOp; + + CTimerLogger* iLogger; + RSemaphore* iSmphS; // Use for signaling file operation thread + RSemaphore* iSmphW; // Use for waiting signal from file operation thread + }; + +// this class is responsible for handling notifications +class CNotifyWatcher : public CActive + { +friend class CNotifyOperator; + +public: + static CNotifyWatcher* NewL(TInt aNumFiles, TUint16 aOption, TUint aCurrentOp, CTimerLogger* aLogger); + ~CNotifyWatcher(); + + void DoCancel(); + void RunL(); + + void RequestNotification(); + + void Reset(TUint aOp); + +private: + CNotifyWatcher(TInt aNumFiles, TUint16 aOption, TUint aCurrentOp, CTimerLogger* aLogger); + void ConstructL(); + + void FullDirectoryScanL(RArray& aArray); + void MakeChangeRecordL(RArray& aArray); + TBool CompareEntry(const TEntry& aEntry1, const TEntry& aEntry2); + + void AddLotsOfFilters(); + + void RequestNotificationEnhanced(); + void RequestNotificationOriginal(); + + void HandleNotification(TBool aLastTime); + + void HandleNotificationEnhanced(TBool aLastTime); + void HandleNotificationOriginal(TBool aLastTime); + + void ResetMdsFSPStatus(); + void RequestNotificationPlugin(); + void HandleNotificationPlugin(TBool aLastTime); + +private: + TInt iCounter; + TInt iMeanCounter; + TInt iOverflowCounter; + + TUint iCurrentOp; + TInt iNumFiles; + TUint16 iOption; + + RArray iEntries; + RArray iRecords; // this is the output we produce + + CTimerLogger* iLogger; + + CFsNotify* iNotify; + + TMdsFSPStatusPckg iPluginStatusPkg; + CMdsPluginControl iPlugin; + + RFs iFs; + }; + +// An AO aims for stopping the Active Scheduler when test finish +class CTestStopper : public CActive + { + +public: + CTestStopper(); + ~CTestStopper(); + + void DoCancel(); + void RunL(); + + void StartWaitingForFile(); + +private: + TFileName iTestEndFile; + RFs iFs; + }; + +#include "t_notify_perf.inl"