--- /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 <f32file.h>
+#include <f32file_private.h>
+#include <e32test.h>
+#include <e32svr.h>
+#include <hal.h>
+#include <e32math.h>
+#include <e32std.h>
+
+// 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<TMdsFSPStatus> 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<RThread> 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<CTimerLogger>* 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<CTimerLogger>& 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<CTimerLogger> 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<TEntry>& aArray);
+ void MakeChangeRecordL(RArray<TEntry>& 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<TEntry> iEntries;
+ RArray<TFileName> 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"