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