os/kernelhwsrv/kerneltest/f32test/bench/t_notify_perf.h
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // f32test\bench\t_notify_perf.h
    15 // 
    16 //
    17 
    18 #include <f32file.h>
    19 #include <f32file_private.h>
    20 #include <e32test.h>
    21 #include <e32svr.h>
    22 #include <hal.h>
    23 #include <e32math.h>
    24 #include <e32std.h>
    25 
    26 // File operation made in test path to trigger notifications
    27 enum TNotifyPerfTestOperations
    28 	{
    29 	// File Operations
    30 	EOpEnd,			// indicates that a series of operations ended
    31 	EOpCreate,
    32 	EOpReplace,
    33 	EOpChgAttr,
    34 	EOpRename,
    35 	EOpWrite,
    36 	EOpResize,
    37 	EOpDelete,
    38 	EOpManyChanges,	// Large number changes to a single file 
    39 	EOpManyFiles,	// Small changes to large number of files
    40 	
    41 	// Directory Operations
    42 	EOpCreateDir,
    43 	EOpRenameDir,
    44 	EOpDeleteDir,
    45 	
    46 	// Mixed Operations
    47 	EOpMixed		// A series of mixed operations involving both Files and Dirs
    48 	};
    49 	
    50 enum TTestOptions
    51 	{
    52 	//////////////////////////////////////////////////////
    53 	// Lowest 4 bit reserved for notification treads ID //
    54 	//////////////////////////////////////////////////////
    55 	
    56 	// Test with a lot of filters for enhanced notification - 1st bit
    57 	// set - on; unset - off
    58 	EBigFilter	= 0x0010,
    59 	
    60 	// Whether perform full directory scan and save the file changes to a list - 2nd bit
    61 	// set - perform; unset - not perform
    62 	EReportChg	= 0x0020, 
    63 	
    64 	// Whether use big buffer for enhanced notification- 3rd bit
    65 	// Set - big buffer(no overflow); unset - small(could have overflow)
    66 	EBigBuffer	= 0x0040,
    67 	
    68 	// For multi clients test. Enhanced Notification Only!
    69 	// Mode 1: set a variety of different notifications, same on each clients - 4th bit
    70 	EMultiNoti1	= 0x0080,
    71 	
    72 	// For multi clients test. Enhanced Notification Only!
    73 	// Mode 2: set a variety of different notifications, in which some are different on each clients, 
    74 	// and some are same on each clients, only support upto 4 clients - 5th bit
    75 	EMultiNoti2	= 0x0100,
    76 	
    77 	ENotPerfTestReserved6	= 0x0200, 
    78 	ENotPerfTestReserved7	= 0x0400, 
    79 	ENotPerfTestReserved8	= 0x0800, 
    80 	
    81 	// Notification type - 13th - 16th bits
    82 	ENoNotify	= 0x1000,	// Test without notification
    83 	EEnhanced	= 0x2000,	// Using enhanced notification APIs
    84 	EOriginal	= 0x4000,	// Using original notification APIs
    85 	EPlugin		= 0x8000,	// Using Nokia plug-in for notification
    86 	};
    87 
    88 // Note for Plugin Test
    89 // the plugin test can only be run manually because the plugin is not available in KHS code base
    90 // to run the test:
    91 // 1. enable the MACRO above in the mmp
    92 // 2. get a S60 environment
    93 // 3. copy the MdsFileServerPlugin.ptx from the release(\Winscw or \Armv5 depend on what kind of test you want to run) 
    94 //    directory of S60 to the equivalent folder of release directory of your epoc32
    95 // 4. when build a rom, include the MdsFileServerPlugin.ptx file in the rom
    96 // 5. then you can run
    97 enum TMdsFSPOperation
    98     {
    99     EMdsFSPOpEnable,
   100     EMdsFSPOpDisable,
   101     EMdsFSPOpRegisterNotification,
   102     EMdsFSPOpAddNotificationPath,
   103     EMdsFSPOpRemoveNotificationPath,
   104     EMdsFSPOpAddIgnorePath,
   105     EMdsFSPOpRemoveIgnorePath,
   106     EMdsFSPOpNotificationCancel,
   107     };
   108 
   109 class TMdsFSPStatus
   110     {
   111 public:
   112     TInt iFileEventType;
   113     TInt iDriveNumber;
   114     TFileName iFileName;
   115     TFileName iNewFileName;
   116     TUid iProcessId;
   117     };
   118 
   119 enum TMdsFileEventType
   120     {
   121     EMdsFileCreated,
   122     EMdsFileRenamed,
   123     EMdsFileModified,
   124     EMdsFileReplaced,
   125     EMdsFileDeleted,
   126     EMdsDriveFormatted,
   127     EMdsFileUnknown,
   128     EMdsDirRenamed
   129     };
   130 
   131 typedef TPckgBuf<TMdsFSPStatus> TMdsFSPStatusPckg;
   132 
   133 const TInt KMdsFSPluginPosition = 0x200071CD;
   134 _LIT(KPluginName, "MdsFileServerPlugin");
   135 
   136 // the list of operations to be conducted during a test case
   137 const TUint KDefaultOpList[] = {EOpCreate, EOpReplace, EOpChgAttr, EOpRename, EOpWrite, EOpResize, EOpDelete, EOpEnd};
   138 const TUint KDefaultOpListDir[] = {EOpCreateDir, EOpRenameDir, EOpDeleteDir, EOpEnd};
   139 
   140 const TUint KManyChangesOpList[] = {EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpManyChanges, EOpEnd};
   141 const TUint KManyFilesOpList[] = {EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpManyFiles, EOpEnd};
   142 const TUint KMixedOpTestList[] = {EOpMixed, EOpMixed, EOpMixed, EOpMixed, EOpMixed, EOpEnd};
   143 
   144 const TUint16 KNotifyOptionMask = 0xF000;
   145 const TUint16 KNotifyTreadIdMask = 0x000F;
   146 
   147 // default time scale for timer
   148 const TUint KDefaultTimeScale = 1000; // 1ms
   149 const TInt KMaxHeapSize = 0x1000000;
   150 
   151 // used by SafeCheck
   152 const TInt KNoThreadId = -1;
   153 
   154 // a Controllor of whether measure time and write loggs;
   155 extern TBool gPerfMeasure;
   156 
   157 extern TFileName gTestPath;
   158 extern TFileName gLogFilePath;
   159 
   160 // Threads handles
   161 extern RArray<RThread> gNotiThreads;
   162 extern RThread gFileThread;
   163 
   164 extern TBuf<50> gLogPostFix;
   165 
   166 //-------------------------------------------------------------
   167 
   168 class CTimerLogger;
   169 
   170 // a wrapper for test settings
   171 class TTestSetting
   172 	{
   173 
   174 public:
   175 	TTestSetting();
   176 	TTestSetting(TInt aNumFiles, TInt aNumCli, TUint16 aOpt, const TUint* aOpList);
   177 	inline void Reset();
   178 	
   179 public:
   180 	TInt iNumFiles;
   181 	TInt iNumCli;
   182 	TUint16 iOption;
   183 	const TUint* iOperationList;
   184 	
   185 	};
   186 
   187 // a wrapper of parameters for the main thread to pass into notification thread or file operation thread
   188 struct TThreadParam
   189 	{
   190 	TTestSetting iSetting;
   191 	RSemaphore* iSmphFT;	// Semophore used by File Thread for waiting for signals from Notification Threads
   192 	RSemaphore* iSmphNT;	// Semophore used by Notification Threads for waiting for signals from File Thread
   193 	CTimerLogger* iLogger;	// Logger used by Notification Threads;
   194 	RPointerArray<CTimerLogger>* iLoggerArray;	// a pointer to an array of pointers to CTimmerLoggger
   195 	};
   196 
   197 // This is the controller of the plugin, it's a simplified copy of the plugin engine used in S60 internally
   198 class CMdsPluginControl : public RPlugin
   199     {   
   200 public:
   201     inline void RegisterNotification( TMdsFSPStatusPckg& aMdsFSPStatus, TRequestStatus& aStat);
   202     inline void AddNotificationPath( const TDesC& aPath );
   203     inline void RemoveNotificationPath( const TDesC& aPath );
   204     inline TInt Enable();
   205     inline TInt Disable();
   206     inline void NotificationCancel();
   207     };
   208 
   209 // timer class, also responsible for writing logs
   210 class CTimerLogger : public CBase
   211 	{
   212 	
   213 public:	
   214 	static CTimerLogger* NewL(const TFileName& aLogFile);
   215 	~CTimerLogger();
   216 	inline TInt MeasureStart();
   217 	inline TInt MeasureEnd();
   218 	inline TBool Timing();
   219 	TInt Log(const TDesC& aDes, TBool aIsLine = ETrue);
   220 	TInt LogAndPrint(const TDesC& aDes, TBool aIsLine = ETrue);
   221 	TInt LogSettingDescription(const TInt aNumFile, const TInt aNumCli, const TUint16 aOption, TBool aNumOpVaries = EFalse);
   222 	TInt LogTestStepTime(TUint aOp, TInt aNum);
   223 
   224 private:
   225 	CTimerLogger();
   226 	void ConstructL(const TFileName& aLogFile);
   227 	
   228 private:
   229 	TBool iTiming;
   230 	TUint32 iTickNumber;
   231 	TUint iTimeScale;
   232 	TInt iTickPeriod;
   233 	TFileName iLogFile;
   234 	RFs iFs;
   235 	};
   236 
   237 // the conductor of test cases
   238 class CTestExecutor : public CBase
   239 	{
   240 
   241 public:
   242 	CTestExecutor(TTestSetting& aSetting);
   243 	~CTestExecutor();
   244 	
   245 	inline void SetTestSetting(TTestSetting& aSetting);
   246 	inline void LogDescription();
   247 	
   248 	void RunTestCaseL();
   249 	static void KillAllTestThreads();
   250 	
   251 private:
   252 	TTestSetting iTestSetting;
   253 	
   254 	};
   255 
   256 // This class performs file operations
   257 class CFileOperator : public CBase
   258 	{
   259 	
   260 public:	
   261 	CFileOperator(const TTestSetting& aSetting, RPointerArray<CTimerLogger>& aLoggerArray, RSemaphore* aSmphFT, RSemaphore* aSmphNT);
   262 	~CFileOperator();
   263 	void DoChangesL();
   264 	
   265 private:
   266 	void DoCreateL();
   267 	void DoReplaceL();
   268 	void DoChangeAttL();
   269 	void DoRenameL();
   270 	void DoWriteL();
   271 	void DoResizeL();
   272 	void DoDeleteL();
   273 	void DoCreateDirL();
   274 	void DoRenameDirL();
   275 	void DoDeleteDirL();
   276 	void DoMixedOperationsL();
   277 	
   278 	void DoManyChangesOnSingleFileL();
   279 	void DoSmallChangesOnManyFilesL();
   280 	
   281 	void MesureStartsAll();
   282 	void WaitForSignalsAll();
   283 
   284 	void TestStepPrepare(TUint aOp);
   285 	void TestStepFinish(TUint aOp);
   286 	
   287 private:
   288 	// test case will use the number iFirstFile and iNumFiles to generate test file names.
   289 	// For example: 
   290 	// if iFirstFile = 0 and iNumFiles = 100, the test files will be 0000.tst, 0001.tst ... 0099.tst
   291 	// if iFirstFile = 21 and iNumFiles = 200, the test files will be 0021.tst, 0022.tst ... 0220.tst
   292 	//
   293 	// When doing rename or replace test, the new names for test will be the biggest existing file 
   294 	// number + 1 to the number + iNumFiles.
   295 	// As a result, in the case of if iFirstFile = 0 and iNumFiles = 100:
   296 	// The exsting files should be 0000.tst ... 0099.tst
   297 	// Rename or Replace test will use the new names 0100.tst ... 0199.tst to replace or rename the
   298 	// existing files.
   299 	TInt iFirstFile;
   300 	
   301 	// Number of files for operating.
   302 	// Note: in "Large number changes to a single file" case, this indicates the number of changes made on the single file.
   303 	TInt iNumFiles;
   304 	TInt iNumCli;
   305 	TUint16 iOption;
   306 	const TUint* iCurrentOp;
   307 	
   308 	RPointerArray<CTimerLogger> iLoggers;
   309 	RSemaphore* iSmphS;		// Use for signaling Notification threads
   310 	RSemaphore* iSmphW;		// Use for waiting signal from Notification threads
   311 	
   312 	RFs iFs;
   313 	};
   314 
   315 // an operator to monitor notification watcher and test stopper
   316 class CNotifyOperator : public CBase
   317 	{
   318 	
   319 public:
   320 	CNotifyOperator(const TTestSetting& aSetting, RSemaphore* aSmphFT, RSemaphore* aSmphNT, CTimerLogger* aLogger);
   321 	~CNotifyOperator();
   322 	
   323 	void StartOperationL();
   324 	
   325 private:
   326 	void LogNotificationNumbers(TInt aNumNoti, TInt aNumIter, TInt aNumOverflow);
   327 	void LogTestResult(TInt aCounter, TInt aMeanCounter, TInt aOFCounter);
   328 	void TestChangeReport(TInt aNumChanges);
   329 	
   330 private:
   331 	TInt iNumFiles;
   332 	TUint16 iOption;
   333 	const TUint* iCurrentOp;
   334 	
   335 	CTimerLogger* iLogger;
   336 	RSemaphore* iSmphS;	// Use for signaling file operation thread
   337 	RSemaphore* iSmphW;	// Use for waiting signal from file operation thread
   338 	};
   339 
   340 // this class is responsible for handling notifications
   341 class CNotifyWatcher : public CActive
   342 	{
   343 friend class CNotifyOperator;
   344 
   345 public:
   346 	static CNotifyWatcher* NewL(TInt aNumFiles, TUint16 aOption, TUint aCurrentOp, CTimerLogger* aLogger);
   347 	~CNotifyWatcher();
   348 	
   349 	void DoCancel();
   350 	void RunL();
   351 
   352 	void RequestNotification();
   353 	
   354 	void Reset(TUint aOp);
   355 	
   356 private:
   357 	CNotifyWatcher(TInt aNumFiles, TUint16 aOption, TUint aCurrentOp, CTimerLogger* aLogger);
   358 	void ConstructL();
   359 
   360 	void FullDirectoryScanL(RArray<TEntry>& aArray);
   361 	void MakeChangeRecordL(RArray<TEntry>& aArray);
   362 	TBool CompareEntry(const TEntry& aEntry1, const TEntry& aEntry2);
   363 	
   364 	void AddLotsOfFilters();
   365 	
   366 	void RequestNotificationEnhanced();
   367 	void RequestNotificationOriginal();
   368 	
   369 	void HandleNotification(TBool aLastTime);
   370 	
   371 	void HandleNotificationEnhanced(TBool aLastTime);
   372 	void HandleNotificationOriginal(TBool aLastTime);
   373 	
   374 	void ResetMdsFSPStatus();
   375 	void RequestNotificationPlugin();
   376 	void HandleNotificationPlugin(TBool aLastTime);
   377 	
   378 private:
   379 	TInt iCounter;
   380 	TInt iMeanCounter;
   381 	TInt iOverflowCounter;
   382 	
   383 	TUint iCurrentOp;
   384 	TInt iNumFiles;
   385 	TUint16 iOption;
   386 
   387 	RArray<TEntry> iEntries;
   388 	RArray<TFileName> iRecords;	// this is the output we produce
   389 	
   390 	CTimerLogger* iLogger;
   391 	
   392 	CFsNotify* iNotify;
   393 	  
   394 	TMdsFSPStatusPckg iPluginStatusPkg;
   395     CMdsPluginControl iPlugin;	
   396 	
   397 	RFs iFs;
   398 	};
   399 
   400 // An AO aims for stopping the Active Scheduler when test finish
   401 class CTestStopper : public CActive
   402 	{
   403 	
   404 public:
   405 	CTestStopper();
   406 	~CTestStopper();
   407 	
   408 	void DoCancel();
   409 	void RunL();
   410 	
   411 	void StartWaitingForFile();
   412 	
   413 private:
   414 	TFileName iTestEndFile;
   415 	RFs iFs;
   416 	};
   417 
   418 #include "t_notify_perf.inl"