os/kernelhwsrv/kerneltest/f32test/fsstress/t_soak1.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 1999-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\fsstress\t_soak1.cpp
sl@0
    15
// Suggestions for future improvements: The createVerifyFileX method uses local 
sl@0
    16
// RBufs for writing and reading. By making these buffers global (at least the 
sl@0
    17
// write buffers), the overhead of allocating and filling memory can be avoided.
sl@0
    18
// 
sl@0
    19
//
sl@0
    20
sl@0
    21
#include <f32file.h>
sl@0
    22
#include <e32test.h>
sl@0
    23
#include "t_chlffs.h"
sl@0
    24
#include "t_server.h"
sl@0
    25
#define __TESTING_LFFS__
sl@0
    26
sl@0
    27
LOCAL_D TInt gDriveNumber;
sl@0
    28
sl@0
    29
const TInt KMaxNumberThreads     = 4;
sl@0
    30
const TInt KHeapSize             = 0x600000;
sl@0
    31
const TInt KDiskUnitThreshold    = 0x1000000; // if disk metrics are above threshold, display in MB rather than KB
sl@0
    32
const TInt KNotificationInterval = 10 * 1000000;
sl@0
    33
sl@0
    34
const TInt KMaxSizeArray         = 3;
sl@0
    35
const TInt KMaxFilesPerDirectory = 100;
sl@0
    36
sl@0
    37
struct TTestMetrics
sl@0
    38
	{
sl@0
    39
	TInt SizeArray[KMaxSizeArray][5];
sl@0
    40
	TInt KSpaceRequiredForMakeAndDelete;
sl@0
    41
	TInt KFillDiskFileSize;
sl@0
    42
	};
sl@0
    43
sl@0
    44
sl@0
    45
sl@0
    46
sl@0
    47
///#define SINGLE__THREAD
sl@0
    48
sl@0
    49
// 256 sectors, 17 sectors+1, 3 bytes, 254 sectors+4, 100 sectors
sl@0
    50
//  50 sectors, 113 sectors+25, 10 sectors, 103 bytes, 199 sectors+44
sl@0
    51
// 24 sectors+166, 189 bytes, 225 sectors, 4 sectors+221, 117 sectors+40
sl@0
    52
LOCAL_D const TTestMetrics DefMetrics =
sl@0
    53
				{
sl@0
    54
				{{65536,4353,3,65028,25600},	// Sizearray[0]
sl@0
    55
				{12800,28953,2560,103,50988},	// Sizearray[1]
sl@0
    56
				{6310,189,57600,1245,29992}},	// Sizearray[2]
sl@0
    57
				655360,							// KSpaceRequiredForMakeAndDelete
sl@0
    58
				65536							// KFillDiskFileSize
sl@0
    59
				};
sl@0
    60
sl@0
    61
// 16 sectors, 1 sectors+1, 3 bytes, 15 sectors+4, 6 sectors
sl@0
    62
//  3 sectors, 7 sectors+25, 1 sector, 103 bytes, 12 sectors+44
sl@0
    63
// 2 sectors+166, 189 bytes, 15 sectors, 4 sectors+221, 7 sectors+40
sl@0
    64
LOCAL_D const TTestMetrics LffsMetrics = 
sl@0
    65
				{
sl@0
    66
				{{4096,257,3,3844,1536},		// Sizearray[0]
sl@0
    67
				{768,1817,256,103,3116},		// Sizearray[1]
sl@0
    68
				{678,189,3840,1245,1832}},		// Sizearray[2]
sl@0
    69
				36864,							// KSpaceRequiredForMakeAndDelete
sl@0
    70
				4096							// KFillDiskFileSize
sl@0
    71
				};
sl@0
    72
sl@0
    73
// 1600 sectors, 100 sectors+100, 1 sector+44, 1501 sectors+144, 600 sectors
sl@0
    74
// 300 sectors, 709 sectors+196, 100 sectors, 40 sectors+60, 1217 sectors+48
sl@0
    75
// 264 sectors+216, 73 sectors+212, 486 sectors+84, 715 sectors+160
sl@0
    76
LOCAL_D const TTestMetrics FAT32Metrics =
sl@0
    77
				{
sl@0
    78
				{{409600,25700,300,384400,153600},		// Sizearray[0]
sl@0
    79
				{76800,181700,25600,10300,311600},		// Sizearray[1]
sl@0
    80
				{67800,18900,384000,124500,183200}},	// Sizearray[2]
sl@0
    81
				3686400,								// KSpaceRequiredForMakeAndDelete
sl@0
    82
				409600									// KFillDiskFileSize
sl@0
    83
				};
sl@0
    84
sl@0
    85
// 8 sectors, 1 sectors+1, 3 bytes, 7 sectors+4, 3 sectors
sl@0
    86
//  1 sectors, 3 sectors+25, 1 sector, 103 bytes, 6 sectors+44
sl@0
    87
// 1 sector+166 bytes, 189 bytes, 7 sectors, 2 sectors+221, 3 sectors+40
sl@0
    88
sl@0
    89
LOCAL_D const TTestMetrics NandMetrics = 
sl@0
    90
				{
sl@0
    91
				{{2048,257,3,1796,768},			// Sizearray[0]
sl@0
    92
				{256,793,256,103,1580},			// Sizearray[1]
sl@0
    93
				{422,189,1792,833,808}},		// Sizearray[2]
sl@0
    94
				20480,							// KSpaceRequiredForMakeAndDelete
sl@0
    95
				2048							// KFillDiskFileSize
sl@0
    96
				};
sl@0
    97
sl@0
    98
sl@0
    99
sl@0
   100
LOCAL_D const TTestMetrics* TheMetrics = 0;
sl@0
   101
sl@0
   102
sl@0
   103
#if defined(__WINS__)
sl@0
   104
#define WIN32_LEAN_AND_MEAN
sl@0
   105
#pragma warning (disable:4201) // warning C4201: nonstandard extension used : nameless struct/union
sl@0
   106
#pragma warning (default:4201) // warning C4201: nonstandard extension used : nameless struct/union
sl@0
   107
#endif
sl@0
   108
sl@0
   109
#if defined(_UNICODE)
sl@0
   110
	#if !defined(UNICODE)
sl@0
   111
		#define UNICODE
sl@0
   112
	#endif
sl@0
   113
#endif
sl@0
   114
sl@0
   115
#ifndef SINGLE__THREAD
sl@0
   116
	#define REUSE_THREAD
sl@0
   117
#endif
sl@0
   118
sl@0
   119
#ifdef REUSE_THREAD
sl@0
   120
	LOCAL_D TBool gRequestEnd;
sl@0
   121
#endif
sl@0
   122
sl@0
   123
class TThreadTestInfo
sl@0
   124
	{
sl@0
   125
public:
sl@0
   126
	TInt iCycles;
sl@0
   127
	TInt iErrors;
sl@0
   128
	TInt iSizeArrayPos;
sl@0
   129
	TInt iErrorInfo;
sl@0
   130
	};
sl@0
   131
sl@0
   132
GLDEF_D RTest test(_L("T_SOAK1"));
sl@0
   133
LOCAL_D TThreadTestInfo ThreadTestInfo[KMaxNumberThreads];
sl@0
   134
LOCAL_D TBool CurrentlyFillingDisk;
sl@0
   135
LOCAL_D TInt FillDiskCount;
sl@0
   136
LOCAL_D TInt FillDiskCycle;
sl@0
   137
sl@0
   138
LOCAL_C TInt MakeAndDeleteFilesThread(TAny* anId);
sl@0
   139
LOCAL_C TInt FillAndEmptyDiskThread(TAny* anId);
sl@0
   140
LOCAL_C TInt CreateVerifyFileX(const TDesC& aBaseName,TInt aSize,RFs &aFs,TInt aPattern);
sl@0
   141
LOCAL_C TInt MakeFileName(TInt aThreadId, TInt aFileNumber, RFs & aFs, TFileName& aName, TBool aMakeDir = ETrue);
sl@0
   142
LOCAL_C TInt AppendPath(TFileName& aPath, TInt aNumber, TInt aLevel);
sl@0
   143
sl@0
   144
_LIT( KConnect, "Connect" );
sl@0
   145
_LIT( KDelete, "Delete" );
sl@0
   146
_LIT( KDriveToChar, "DriveToChar" );
sl@0
   147
_LIT( KAppendPath, "AppendPath" );
sl@0
   148
_LIT( KSetSessPath, "SetSessPath" );
sl@0
   149
_LIT( KMdAll, "MkdirAll" );
sl@0
   150
_LIT( KVolInfo, "VolInfo" );
sl@0
   151
_LIT( KReplace, "Replace" );
sl@0
   152
_LIT( KRead, "Read" );
sl@0
   153
_LIT( KWrite, "Write" );
sl@0
   154
_LIT( KFlush, "Flush" );
sl@0
   155
_LIT( KDataCompare, "DataCompare" );
sl@0
   156
_LIT( KMemory, "Memory" );
sl@0
   157
_LIT( KFilePrefix, "FILE_" );
sl@0
   158
sl@0
   159
_LIT(KPath, "?:\\SOAK_TEST\\SESSION%d\\");
sl@0
   160
sl@0
   161
LOCAL_C void LogError( TInt aError, const TDesC& aAction, const TDesC& aFileName, TUint a1, TUint a2, TInt line = -1 )
sl@0
   162
	{
sl@0
   163
	if(line >= 0)
sl@0
   164
		{
sl@0
   165
		_LIT(KFmt, "TSOAK1 ERROR (line %d): %d, file [%S], %S, (0x%x, 0x%x)");
sl@0
   166
		RDebug::Print(KFmt, line, aError, &aFileName, &aAction, a1, a2);
sl@0
   167
		}
sl@0
   168
	else 
sl@0
   169
		{
sl@0
   170
		_LIT(KFmt, "TSOAK1 ERROR: %d, file [%S], %S, (0x%x, 0x%x)");
sl@0
   171
		RDebug::Print(KFmt, aError, &aFileName, &aAction, a1, a2);
sl@0
   172
		}
sl@0
   173
	}
sl@0
   174
sl@0
   175
LOCAL_C TInt MakeFileName(TInt aThreadId, TInt aFileNumber, RFs & aFs, TFileName& aName, TBool aMakeDir)
sl@0
   176
//
sl@0
   177
// creates a file name and makes all the directory components, if required
sl@0
   178
//
sl@0
   179
	{
sl@0
   180
	
sl@0
   181
	TFileName path;
sl@0
   182
	path.Format(KPath, aThreadId);
sl@0
   183
	
sl@0
   184
	TChar driveLetter;
sl@0
   185
	TInt  r;
sl@0
   186
	r = aFs.DriveToChar(gDriveNumber, driveLetter);
sl@0
   187
	if (r != KErrNone)
sl@0
   188
		{
sl@0
   189
		LogError(r, KDriveToChar, KNullDesC, driveLetter, 0);
sl@0
   190
		aFs.Close();
sl@0
   191
		return(r);
sl@0
   192
		}
sl@0
   193
		
sl@0
   194
	path[0] = (TText) driveLetter;
sl@0
   195
	r = aFs.SetSessionPath(path);
sl@0
   196
	if (r != KErrNone)
sl@0
   197
		{
sl@0
   198
		LogError(r, KSetSessPath, path, 0, 0);
sl@0
   199
		aFs.Close();
sl@0
   200
		return(r);
sl@0
   201
		}
sl@0
   202
		
sl@0
   203
	// add additional directories
sl@0
   204
	TInt fileNumber;
sl@0
   205
	fileNumber = aFileNumber;
sl@0
   206
	r = AppendPath(path, fileNumber, 0);
sl@0
   207
	if(r != KErrNone)
sl@0
   208
		{
sl@0
   209
		LogError(r, KAppendPath, path, fileNumber, 0);
sl@0
   210
		aFs.Close();
sl@0
   211
		return(r);
sl@0
   212
		}
sl@0
   213
		
sl@0
   214
	if(aMakeDir)
sl@0
   215
		{
sl@0
   216
		r = aFs.MkDirAll(path);
sl@0
   217
		if (r != KErrNone && r != KErrAlreadyExists)
sl@0
   218
			{
sl@0
   219
			LogError(r, KMdAll, path, 0, 0);
sl@0
   220
			aFs.Close();
sl@0
   221
			return(r);
sl@0
   222
			}
sl@0
   223
		}
sl@0
   224
		
sl@0
   225
	// and finally add file name
sl@0
   226
	path.Append(KFilePrefix);
sl@0
   227
	path.AppendNum(aFileNumber);
sl@0
   228
sl@0
   229
	aName = path;
sl@0
   230
	return(KErrNone);
sl@0
   231
	}
sl@0
   232
	
sl@0
   233
sl@0
   234
LOCAL_C TInt AppendPath(TFileName& aPath, TInt aNumber, TInt aLevel)
sl@0
   235
//
sl@0
   236
// helper function for MakeFileName()
sl@0
   237
//
sl@0
   238
	{
sl@0
   239
	
sl@0
   240
	if(aNumber > KMaxFilesPerDirectory)
sl@0
   241
		{
sl@0
   242
		aNumber /= KMaxFilesPerDirectory;
sl@0
   243
		AppendPath(aPath, aNumber, aLevel + 1);
sl@0
   244
		}
sl@0
   245
		
sl@0
   246
	if(aLevel)
sl@0
   247
		{	
sl@0
   248
		aPath.AppendNum(aNumber % KMaxFilesPerDirectory);	
sl@0
   249
		aPath.Append('\\');	
sl@0
   250
		}
sl@0
   251
	
sl@0
   252
	return(KErrNone);
sl@0
   253
	}
sl@0
   254
sl@0
   255
LOCAL_C TInt MakeAndDeleteFilesThread(TAny* anId)
sl@0
   256
//
sl@0
   257
// The entry point for the 'MakeAndDeleteFiles' thread.
sl@0
   258
//
sl@0
   259
	{
sl@0
   260
sl@0
   261
	TInt thrdId=(TInt)anId;
sl@0
   262
	TInt pattern=(ThreadTestInfo[thrdId].iCycles)%2;
sl@0
   263
    TInt r;
sl@0
   264
	RFs f;
sl@0
   265
	r=f.Connect();
sl@0
   266
	if (r!=KErrNone)
sl@0
   267
		{
sl@0
   268
		LogError( r, KConnect, KNullDesC, 0, 0 );
sl@0
   269
		ThreadTestInfo[thrdId].iErrorInfo=1;
sl@0
   270
		return(r);
sl@0
   271
		}
sl@0
   272
sl@0
   273
	TFileName fileName;
sl@0
   274
	TInt sizeArrayPos = ThreadTestInfo[thrdId].iSizeArrayPos;
sl@0
   275
#ifdef REUSE_THREAD
sl@0
   276
	while(!gRequestEnd)
sl@0
   277
		{
sl@0
   278
#endif	
sl@0
   279
		for(TInt i = 0; i < 5; i++)
sl@0
   280
			{
sl@0
   281
			// create files
sl@0
   282
			r = MakeFileName(thrdId, i, f, fileName);
sl@0
   283
			if(r != KErrNone)
sl@0
   284
				{
sl@0
   285
				ThreadTestInfo[thrdId].iErrorInfo=2;
sl@0
   286
				f.Close();
sl@0
   287
				return(r);
sl@0
   288
				}
sl@0
   289
			
sl@0
   290
			r = CreateVerifyFileX(fileName, TheMetrics->SizeArray[sizeArrayPos][0], f, pattern);
sl@0
   291
			if (r!=KErrNone)
sl@0
   292
				{
sl@0
   293
				ThreadTestInfo[thrdId].iErrorInfo=3;
sl@0
   294
				f.Close();
sl@0
   295
				return(r);
sl@0
   296
				}
sl@0
   297
			
sl@0
   298
			// delete selected files at certain points in the cycle
sl@0
   299
			TInt deleteFile = EFalse;
sl@0
   300
			switch(i)
sl@0
   301
				{
sl@0
   302
				default:
sl@0
   303
					// nothing to be done
sl@0
   304
				break;
sl@0
   305
				case 2:
sl@0
   306
					// delete file 0
sl@0
   307
					deleteFile = ETrue;
sl@0
   308
					r = MakeFileName(thrdId, 0, f, fileName, EFalse);
sl@0
   309
				break;
sl@0
   310
				case 3:
sl@0
   311
					// delete file 1
sl@0
   312
					deleteFile = ETrue;
sl@0
   313
					r = MakeFileName(thrdId, 1, f, fileName, EFalse);
sl@0
   314
				break;
sl@0
   315
				}
sl@0
   316
				
sl@0
   317
				if(deleteFile)
sl@0
   318
					{
sl@0
   319
					// check MakeFileName() error code
sl@0
   320
					if(r != KErrNone)
sl@0
   321
						{
sl@0
   322
						ThreadTestInfo[thrdId].iErrorInfo = 4;
sl@0
   323
						f.Close();
sl@0
   324
						return(r);
sl@0
   325
						}
sl@0
   326
						
sl@0
   327
					// and delete file
sl@0
   328
					r = f.Delete(fileName);
sl@0
   329
					if(r != KErrNone)
sl@0
   330
						{
sl@0
   331
						ThreadTestInfo[thrdId].iErrorInfo = 5;
sl@0
   332
						f.Close();
sl@0
   333
						return(r);
sl@0
   334
						}
sl@0
   335
					}
sl@0
   336
			}
sl@0
   337
			
sl@0
   338
		sizeArrayPos++;
sl@0
   339
		if(sizeArrayPos >= KMaxSizeArray)
sl@0
   340
			{
sl@0
   341
			sizeArrayPos = 0;
sl@0
   342
			}
sl@0
   343
			
sl@0
   344
		ThreadTestInfo[thrdId].iSizeArrayPos=sizeArrayPos;
sl@0
   345
#ifdef REUSE_THREAD
sl@0
   346
	ThreadTestInfo[thrdId].iCycles++;
sl@0
   347
	pattern = (ThreadTestInfo[thrdId].iCycles) % 2;
sl@0
   348
	}
sl@0
   349
#endif
sl@0
   350
sl@0
   351
	f.Close();
sl@0
   352
	return(KErrNone);
sl@0
   353
	}
sl@0
   354
sl@0
   355
LOCAL_C TInt FillAndEmptyDiskThread(TAny* anId)
sl@0
   356
//
sl@0
   357
// The entry point for the 'FillAndEmptyDisk' thread.
sl@0
   358
//
sl@0
   359
	{
sl@0
   360
sl@0
   361
	TInt thrdId=(TInt)anId;
sl@0
   362
	TInt pattern=(ThreadTestInfo[thrdId].iCycles)%2;
sl@0
   363
    TInt r;
sl@0
   364
	RFs f;
sl@0
   365
	r=f.Connect();
sl@0
   366
	if (r!=KErrNone)
sl@0
   367
		{
sl@0
   368
		LogError( r, KConnect, KNullDesC, 0, 0 );
sl@0
   369
		ThreadTestInfo[thrdId].iErrorInfo=6;
sl@0
   370
		return(r);
sl@0
   371
		}
sl@0
   372
sl@0
   373
	TInt i;
sl@0
   374
#ifdef REUSE_THREAD
sl@0
   375
	while(!gRequestEnd)
sl@0
   376
		{
sl@0
   377
#endif	
sl@0
   378
		for (i=0;i<5;i++) // Create/Delete 5 files each time
sl@0
   379
			{
sl@0
   380
			if (CurrentlyFillingDisk)
sl@0
   381
				{
sl@0
   382
				TVolumeInfo v;
sl@0
   383
				r=f.Volume(v,gDriveNumber);
sl@0
   384
				if (r!=KErrNone)
sl@0
   385
					{
sl@0
   386
					ThreadTestInfo[thrdId].iErrorInfo=7;
sl@0
   387
					LogError( r, KVolInfo, KNullDesC, gDriveNumber, 0);
sl@0
   388
					f.Close();
sl@0
   389
					return(r);
sl@0
   390
					}
sl@0
   391
				if (v.iFree<=(TheMetrics->KSpaceRequiredForMakeAndDelete+TheMetrics->KFillDiskFileSize))
sl@0
   392
					CurrentlyFillingDisk=EFalse;
sl@0
   393
				else
sl@0
   394
					{
sl@0
   395
					TFileName fileName;
sl@0
   396
					r = MakeFileName(thrdId, FillDiskCount, f, fileName);
sl@0
   397
					if(r != KErrNone)
sl@0
   398
						{
sl@0
   399
						ThreadTestInfo[thrdId].iErrorInfo = 8;
sl@0
   400
						f.Close();
sl@0
   401
						return(r);
sl@0
   402
						}			
sl@0
   403
					
sl@0
   404
					r = CreateVerifyFileX(fileName, TheMetrics->KFillDiskFileSize, f, pattern);
sl@0
   405
					if (r!=KErrNone)
sl@0
   406
						{
sl@0
   407
						ThreadTestInfo[thrdId].iErrorInfo=9;
sl@0
   408
						f.Close();
sl@0
   409
						return(r);
sl@0
   410
						}
sl@0
   411
					FillDiskCount++;
sl@0
   412
					}
sl@0
   413
				}
sl@0
   414
			else
sl@0
   415
				{
sl@0
   416
				if (FillDiskCount<=0)
sl@0
   417
					{
sl@0
   418
					CurrentlyFillingDisk=ETrue;
sl@0
   419
					FillDiskCount=0;
sl@0
   420
					FillDiskCycle++;
sl@0
   421
					}
sl@0
   422
				else
sl@0
   423
					{
sl@0
   424
					FillDiskCount--;
sl@0
   425
					TFileName fileName;
sl@0
   426
					r = MakeFileName(thrdId, FillDiskCount, f, fileName, EFalse);
sl@0
   427
					if(r != KErrNone)
sl@0
   428
						{
sl@0
   429
						ThreadTestInfo[thrdId].iErrorInfo = 10;
sl@0
   430
						f.Close();
sl@0
   431
						return(r);
sl@0
   432
						}
sl@0
   433
					
sl@0
   434
					r = f.Delete(fileName);				
sl@0
   435
					if (r!=KErrNone)
sl@0
   436
						{
sl@0
   437
						ThreadTestInfo[thrdId].iErrorInfo=11;
sl@0
   438
						LogError(r, KDelete, fileName,FillDiskCount, 0);
sl@0
   439
						f.Close();
sl@0
   440
						return(r);
sl@0
   441
						}
sl@0
   442
					}
sl@0
   443
				}
sl@0
   444
			}
sl@0
   445
#ifdef REUSE_THREAD
sl@0
   446
		ThreadTestInfo[thrdId].iCycles++;
sl@0
   447
		pattern = (ThreadTestInfo[thrdId].iCycles) % 2;
sl@0
   448
		}			
sl@0
   449
#endif
sl@0
   450
sl@0
   451
	f.Close();
sl@0
   452
	return(KErrNone);
sl@0
   453
	}
sl@0
   454
sl@0
   455
const TInt KCreateFileBufSize = 0x80000; 
sl@0
   456
LOCAL_C TInt CreateVerifyFileX(const TDesC& aFileName, TInt aSize, RFs& aFs, TInt aPattern)
sl@0
   457
//
sl@0
   458
// Create and verify a file.
sl@0
   459
//
sl@0
   460
	{
sl@0
   461
	// Note, the directory structure is provided by MakeFileName(). Hence it 
sl@0
   462
	// is assumed at this point that the path to the file exists already.
sl@0
   463
	RFile file;
sl@0
   464
	TInt r;
sl@0
   465
	r = file.Replace(aFs, aFileName, EFileWrite);
sl@0
   466
	if (r!=KErrNone)
sl@0
   467
		{
sl@0
   468
		LogError( r, KReplace, aFileName, EFileWrite, 0 );
sl@0
   469
		return(r);
sl@0
   470
		}
sl@0
   471
sl@0
   472
	// Grow it to the specified size by writing a pattern buffer to it
sl@0
   473
	// Alternate the pattern buffer each time
sl@0
   474
	RBuf8 wBuf;
sl@0
   475
	r = wBuf.CreateMax(KCreateFileBufSize);
sl@0
   476
	if(r != KErrNone)
sl@0
   477
		{
sl@0
   478
		LogError(r, KMemory, aFileName, 0, 0, __LINE__);
sl@0
   479
		wBuf.Close();
sl@0
   480
		file.Close();
sl@0
   481
		return(r);
sl@0
   482
		}
sl@0
   483
		
sl@0
   484
	TInt i;
sl@0
   485
	
sl@0
   486
	if (aPattern)
sl@0
   487
		{
sl@0
   488
		// ascending pattern
sl@0
   489
		for (i = 0; i < KCreateFileBufSize; i++)
sl@0
   490
			{			
sl@0
   491
			wBuf[i] = (TUint8) i;			
sl@0
   492
			}
sl@0
   493
		}
sl@0
   494
	else
sl@0
   495
		{
sl@0
   496
		// descending pattern
sl@0
   497
		for (i = 0; i < KCreateFileBufSize; i++)
sl@0
   498
			{
sl@0
   499
			wBuf[i] = (TUint8) ((KCreateFileBufSize - 1) - i);
sl@0
   500
			}
sl@0
   501
		}
sl@0
   502
sl@0
   503
sl@0
   504
	TInt pos;
sl@0
   505
	TInt chunkSize;
sl@0
   506
	TInt sectorCount = 0;
sl@0
   507
	
sl@0
   508
	for (pos = 0; pos < aSize; pos += chunkSize)
sl@0
   509
		{
sl@0
   510
		wBuf[0]=(TUint8)i;	// Insert sector count
sl@0
   511
		chunkSize = Min((aSize-pos), KCreateFileBufSize);
sl@0
   512
		r = file.Write(pos, wBuf, chunkSize);
sl@0
   513
		if (r != KErrNone)
sl@0
   514
			{
sl@0
   515
			LogError(r, KWrite, aFileName, pos, chunkSize, __LINE__);
sl@0
   516
			file.Close();
sl@0
   517
			wBuf.Close();
sl@0
   518
			return(r);
sl@0
   519
			}
sl@0
   520
			
sl@0
   521
		sectorCount++;
sl@0
   522
		}
sl@0
   523
sl@0
   524
	// Flush it
sl@0
   525
	r=file.Flush();
sl@0
   526
	if (r!=KErrNone)
sl@0
   527
		{
sl@0
   528
		LogError( r, KFlush, aFileName, 0, 0, __LINE__);
sl@0
   529
		file.Close();
sl@0
   530
		wBuf.Close();
sl@0
   531
		return(r);
sl@0
   532
		}
sl@0
   533
sl@0
   534
//	Test still works if this is commented out just doesn't verify
sl@0
   535
	// Read back and verify it
sl@0
   536
	RBuf8 rBuf;
sl@0
   537
	r = rBuf.CreateMax(KCreateFileBufSize);
sl@0
   538
	if(r != KErrNone)
sl@0
   539
		{
sl@0
   540
		LogError( r, KMemory, aFileName, 0, 0, __LINE__);
sl@0
   541
		file.Close();
sl@0
   542
		wBuf.Close();
sl@0
   543
		rBuf.Close();
sl@0
   544
		return(KErrGeneral);
sl@0
   545
		}
sl@0
   546
	
sl@0
   547
	
sl@0
   548
	for (pos = 0;pos < aSize; pos += chunkSize)
sl@0
   549
		{
sl@0
   550
		chunkSize = Min((aSize-pos), KCreateFileBufSize);
sl@0
   551
		r = file.Read(pos, rBuf, chunkSize);
sl@0
   552
		if (r != KErrNone)
sl@0
   553
			{
sl@0
   554
			LogError(r, KRead, aFileName, pos, 0, __LINE__);
sl@0
   555
			file.Close();
sl@0
   556
			wBuf.Close();
sl@0
   557
			rBuf.Close();
sl@0
   558
			return(r);
sl@0
   559
			}
sl@0
   560
			
sl@0
   561
		wBuf[0] = (TUint8) i; // Insert sector count
sl@0
   562
		wBuf.SetLength(chunkSize);
sl@0
   563
		r = rBuf.Compare(wBuf);
sl@0
   564
		if (r != 0)
sl@0
   565
			{
sl@0
   566
			LogError(r, KDataCompare, aFileName, 0, 0, __LINE__);
sl@0
   567
			file.Close();
sl@0
   568
			wBuf.Close();
sl@0
   569
			rBuf.Close();
sl@0
   570
			return(KErrGeneral);
sl@0
   571
			}
sl@0
   572
		}
sl@0
   573
//
sl@0
   574
sl@0
   575
	file.Close();
sl@0
   576
	wBuf.Close();
sl@0
   577
	rBuf.Close();
sl@0
   578
	return(KErrNone);
sl@0
   579
	}
sl@0
   580
	
sl@0
   581
sl@0
   582
#ifdef SINGLE__THREAD
sl@0
   583
LOCAL_C void DoTests()
sl@0
   584
//
sl@0
   585
//  single thread
sl@0
   586
//
sl@0
   587
    {
sl@0
   588
sl@0
   589
	TInt r=KErrNone;
sl@0
   590
	test.Next(_L("Start continuous file Write/Read/Verify operation"));
sl@0
   591
	RThread t[KMaxNumberThreads];
sl@0
   592
	TRequestStatus tStat[KMaxNumberThreads];
sl@0
   593
sl@0
   594
	TInt i=0;
sl@0
   595
sl@0
   596
	TName threadName;
sl@0
   597
	TRequestStatus kStat=KRequestPending;
sl@0
   598
	test.Console()->Read(kStat);
sl@0
   599
	ThreadTestInfo[i].iCycles=0;
sl@0
   600
	ThreadTestInfo[i].iErrors=0;
sl@0
   601
	ThreadTestInfo[i].iSizeArrayPos=(i%KMaxSizeArray);
sl@0
   602
	ThreadTestInfo[i].iErrorInfo=0;
sl@0
   603
	if (i<(KMaxNumberThreads-1))
sl@0
   604
		{
sl@0
   605
		threadName.Format(_L("MakeAndDeleteFiles%d"),i);
sl@0
   606
    	r=t[i].Create(threadName,MakeAndDeleteFilesThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   607
		}
sl@0
   608
	else
sl@0
   609
		{
sl@0
   610
		// Last thread fills/empties disk
sl@0
   611
		threadName.Format(_L("FillAndEmptyDisk%d"),i);
sl@0
   612
    	r=t[i].Create(threadName,FillAndEmptyDiskThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   613
		}
sl@0
   614
	if (r!=KErrNone)
sl@0
   615
		test.Printf(_L("Error(%d) creating thread(%d)\r\n"),r,i);
sl@0
   616
	test(r==KErrNone);
sl@0
   617
	t[i].Logon(tStat[i]);
sl@0
   618
	t[i].Resume();
sl@0
   619
	CurrentlyFillingDisk=ETrue;
sl@0
   620
	FillDiskCount=0;
sl@0
   621
sl@0
   622
    TInt totalTime=0;
sl@0
   623
    TTime startTime;
sl@0
   624
    TTime time;
sl@0
   625
    startTime.UniversalTime();
sl@0
   626
sl@0
   627
	TInt ypos=test.Console()->WhereY();
sl@0
   628
	FOREVER
sl@0
   629
		{
sl@0
   630
		User::WaitForAnyRequest();
sl@0
   631
		if (kStat!=KRequestPending)
sl@0
   632
			{
sl@0
   633
    		t[i].LogonCancel(tStat[i]);
sl@0
   634
			User::WaitForRequest(tStat[i]);
sl@0
   635
			break;
sl@0
   636
			}
sl@0
   637
		else
sl@0
   638
			{
sl@0
   639
			TBool threadFinished=EFalse;
sl@0
   640
			if (tStat[i]!=KRequestPending && !threadFinished)
sl@0
   641
				{
sl@0
   642
				t[i].Close();
sl@0
   643
				(ThreadTestInfo[i].iCycles)++;
sl@0
   644
				if (tStat[i]!=KErrNone)
sl@0
   645
					(ThreadTestInfo[i].iErrors)++;
sl@0
   646
				threadFinished=ETrue;
sl@0
   647
sl@0
   648
				// Launch another thread
sl@0
   649
				TInt threadNameId=((ThreadTestInfo[i].iCycles)%2)?(i+KMaxNumberThreads):i; // Alternate thread name
sl@0
   650
				threadName.Format(_L("FillAndEmptyDisk%d"),threadNameId);
sl@0
   651
   				r=t[i].Create(threadName,FillAndEmptyDiskThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   652
				if (r!=KErrNone)
sl@0
   653
					test.Printf(_L("Error(%d) creating thread(%d)\r\n"),r,i);
sl@0
   654
    			test(r==KErrNone);
sl@0
   655
    			t[i].Logon(tStat[i]);
sl@0
   656
				t[i].Resume();
sl@0
   657
				}
sl@0
   658
				
sl@0
   659
			test.Console()->SetPos(0,(ypos+i));
sl@0
   660
			test.Printf(_L("Thread(%d): % 4d errors in % 4d cycles (%d)\r\n"),i,ThreadTestInfo[i].iErrors,ThreadTestInfo[i].iCycles,ThreadTestInfo[i].iErrorInfo);
sl@0
   661
			if (!threadFinished)
sl@0
   662
				{
sl@0
   663
				test.Printf(_L("Semaphore death"));
sl@0
   664
				break;
sl@0
   665
				}
sl@0
   666
			TVolumeInfo v;
sl@0
   667
			r=TheFs.Volume(v,gDriveNumber);
sl@0
   668
			test(r==KErrNone);
sl@0
   669
			test.Console()->SetPos(0,(ypos+KMaxNumberThreads));
sl@0
   670
			test.Printf(_L("Free space on disk: %u K(of %u K)\r\n"),(v.iFree/1024).Low(),(v.iSize/1024).Low());
sl@0
   671
sl@0
   672
            TTimeIntervalSeconds timeTaken;
sl@0
   673
            time.UniversalTime();
sl@0
   674
            r=time.SecondsFrom(startTime,timeTaken);
sl@0
   675
            test(r==KErrNone);
sl@0
   676
            totalTime=timeTaken.Int();
sl@0
   677
sl@0
   678
            TInt seconds = totalTime % 60;
sl@0
   679
            TInt minutes = (totalTime / 60) % 60;
sl@0
   680
            TInt hours   = (totalTime / 3600) % 24;
sl@0
   681
            TInt days    = totalTime / (60 * 60 * 24);
sl@0
   682
            test.Printf(_L("Elapsed Time: %d d %02d:%02d:%02d\r\n"), days, hours, minutes, seconds);
sl@0
   683
			}
sl@0
   684
		}
sl@0
   685
    }
sl@0
   686
sl@0
   687
#else 
sl@0
   688
sl@0
   689
LOCAL_C void DoTests()
sl@0
   690
//
sl@0
   691
//  multiple threads
sl@0
   692
//
sl@0
   693
    {
sl@0
   694
sl@0
   695
	TInt r=KErrNone;
sl@0
   696
	test.Next(_L("Start continuous file Write/Read/Verify operation"));
sl@0
   697
	RThread t[KMaxNumberThreads];
sl@0
   698
	TRequestStatus tStat[KMaxNumberThreads];
sl@0
   699
sl@0
   700
	TInt i=0;
sl@0
   701
sl@0
   702
	TName threadName;
sl@0
   703
	TRequestStatus kStat=KRequestPending;
sl@0
   704
	test.Console()->Read(kStat);
sl@0
   705
	for (i=0;i<KMaxNumberThreads;i++)
sl@0
   706
		{
sl@0
   707
		ThreadTestInfo[i].iCycles=0;
sl@0
   708
		ThreadTestInfo[i].iErrors=0;
sl@0
   709
		ThreadTestInfo[i].iSizeArrayPos=(i%KMaxSizeArray);
sl@0
   710
		ThreadTestInfo[i].iErrorInfo=0;
sl@0
   711
		if (i<(KMaxNumberThreads-1))
sl@0
   712
			{
sl@0
   713
			threadName.Format(_L("MakeAndDeleteFiles%d"),i);
sl@0
   714
	    	r=t[i].Create(threadName,MakeAndDeleteFilesThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   715
			}
sl@0
   716
		else
sl@0
   717
			{
sl@0
   718
			// Last thread fills/empties disk
sl@0
   719
			threadName.Format(_L("FillAndEmptyDisk%d"),i);
sl@0
   720
	    	r=t[i].Create(threadName,FillAndEmptyDiskThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   721
			}
sl@0
   722
		if (r!=KErrNone)
sl@0
   723
   			test.Printf(_L("Error(%d) creating thread(%d)\r\n"),r,i);
sl@0
   724
	    test(r==KErrNone);
sl@0
   725
	    t[i].Logon(tStat[i]);
sl@0
   726
		t[i].Resume();
sl@0
   727
		}
sl@0
   728
	CurrentlyFillingDisk=ETrue;
sl@0
   729
	FillDiskCount=0;
sl@0
   730
sl@0
   731
    TInt totalTime = 0;
sl@0
   732
    TTime cycleTime;
sl@0
   733
    TTime startTime;
sl@0
   734
    TTime time;
sl@0
   735
    startTime.UniversalTime();
sl@0
   736
    cycleTime.UniversalTime();
sl@0
   737
    
sl@0
   738
	TVolumeInfo v;
sl@0
   739
	r=TheFs.Volume(v,gDriveNumber);
sl@0
   740
	test(r==KErrNone);
sl@0
   741
//	TInt initialFreeSpace = I64LOW(v.iFree / 1024);
sl@0
   742
sl@0
   743
#ifdef __LIMIT_EXECUTION_TIME__
sl@0
   744
	RTimer timer;
sl@0
   745
	timer.CreateLocal();
sl@0
   746
	TRequestStatus reqStat;
sl@0
   747
	timer.After(reqStat,60000000); // After 60 secs
sl@0
   748
#endif
sl@0
   749
sl@0
   750
#ifdef REUSE_THREAD
sl@0
   751
	RTimer displayTimer;
sl@0
   752
	displayTimer.CreateLocal();
sl@0
   753
	TRequestStatus displayStat;
sl@0
   754
	displayTimer.After(displayStat, KNotificationInterval); // after 10 secs
sl@0
   755
#endif
sl@0
   756
sl@0
   757
	TInt ypos=test.Console()->WhereY();
sl@0
   758
	FOREVER
sl@0
   759
		{
sl@0
   760
		User::WaitForAnyRequest();
sl@0
   761
		if (kStat!=KRequestPending)
sl@0
   762
			{
sl@0
   763
			// user requested to end - let threads die
sl@0
   764
#ifdef REUSE_THREAD				
sl@0
   765
			gRequestEnd = ETrue;
sl@0
   766
#endif			
sl@0
   767
			for (i=0;i<KMaxNumberThreads;i++)
sl@0
   768
				{
sl@0
   769
				User::WaitForRequest(tStat[i]);
sl@0
   770
				}
sl@0
   771
			break;
sl@0
   772
			}
sl@0
   773
#ifdef __LIMIT_EXECUTION_TIME__
sl@0
   774
		else if (reqStat != KRequestPending)
sl@0
   775
			{
sl@0
   776
			// max execution exceeded - wait for threads to die
sl@0
   777
			TInt totalCycles = 0;
sl@0
   778
			for (i=0;i<KMaxNumberThreads;i++)
sl@0
   779
				{
sl@0
   780
				totalCycles+= ThreadTestInfo[i].iCycles;
sl@0
   781
				}
sl@0
   782
			test.Printf(_L("Total cycles = %d\r\n"), totalCycles);
sl@0
   783
			test.Printf(_L("Waiting for thread death...\r\n"));
sl@0
   784
			for (i=0;i<KMaxNumberThreads;i++)
sl@0
   785
				{
sl@0
   786
				User::WaitForRequest(tStat[i]);
sl@0
   787
				}
sl@0
   788
			break;
sl@0
   789
			}
sl@0
   790
#endif
sl@0
   791
		else
sl@0
   792
			{
sl@0
   793
			// other notification
sl@0
   794
			TBool threadFinished=EFalse;
sl@0
   795
			for (i=0;i<KMaxNumberThreads;i++)
sl@0
   796
				{
sl@0
   797
				if (tStat[i]!=KRequestPending && !threadFinished)
sl@0
   798
					{
sl@0
   799
					t[i].Close();
sl@0
   800
					(ThreadTestInfo[i].iCycles)++;
sl@0
   801
					if (tStat[i]!=KErrNone)
sl@0
   802
						(ThreadTestInfo[i].iErrors)++;
sl@0
   803
					threadFinished=ETrue;
sl@0
   804
sl@0
   805
					// Launch another thread
sl@0
   806
					TInt threadNameId=((ThreadTestInfo[i].iCycles)%2)?(i+KMaxNumberThreads):i; // Alternate thread name
sl@0
   807
					if (i<(KMaxNumberThreads-1))
sl@0
   808
						{
sl@0
   809
						threadName.Format(_L("MakeAndDeleteFiles%d"),threadNameId);
sl@0
   810
	    				r=t[i].Create(threadName,MakeAndDeleteFilesThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   811
						}
sl@0
   812
					else
sl@0
   813
						{
sl@0
   814
						// Last thread fills/empties disk
sl@0
   815
						threadName.Format(_L("FillAndEmptyDisk%d"),threadNameId);
sl@0
   816
	    				r=t[i].Create(threadName,FillAndEmptyDiskThread,KDefaultStackSize,KHeapSize,KHeapSize,(TAny*)i);
sl@0
   817
						}
sl@0
   818
					if (r!=KErrNone)
sl@0
   819
   						test.Printf(_L("Error(%d) creating thread(%d)\r\n"),r,i);
sl@0
   820
	    			test(r==KErrNone);
sl@0
   821
	    			t[i].Logon(tStat[i]);
sl@0
   822
					t[i].Resume();
sl@0
   823
					}
sl@0
   824
				test.Console()->SetPos(0,(ypos+i));
sl@0
   825
   				test.Printf(_L("Thread(%d): % 4d errors in % 4d cycles (%d)\r\n"),i,ThreadTestInfo[i].iErrors,ThreadTestInfo[i].iCycles,ThreadTestInfo[i].iErrorInfo);
sl@0
   826
				}
sl@0
   827
				
sl@0
   828
#ifdef REUSE_THREAD
sl@0
   829
			if(displayStat != KRequestPending)
sl@0
   830
				{
sl@0
   831
				// re-request notification
sl@0
   832
				displayTimer.After(displayStat, KNotificationInterval);
sl@0
   833
				}
sl@0
   834
			else if (!threadFinished)
sl@0
   835
				{
sl@0
   836
				test.Printf(_L("Semaphore death"));
sl@0
   837
				break;
sl@0
   838
				}
sl@0
   839
#else 
sl@0
   840
			if (!threadFinished)
sl@0
   841
				{
sl@0
   842
				test.Printf(_L("Semaphore death"));
sl@0
   843
				break;
sl@0
   844
				}
sl@0
   845
#endif					
sl@0
   846
				
sl@0
   847
			r=TheFs.Volume(v,gDriveNumber);
sl@0
   848
			test(r==KErrNone);
sl@0
   849
			test.Console()->SetPos(0,(ypos+KMaxNumberThreads));
sl@0
   850
			
sl@0
   851
			TInt  freeSpace;
sl@0
   852
			TInt8 freeSpaceUnit;
sl@0
   853
			TInt  totalSpace;
sl@0
   854
			TInt8 totalSpaceUnit;
sl@0
   855
			
sl@0
   856
			// switch t
sl@0
   857
			if(v.iFree > KDiskUnitThreshold)
sl@0
   858
				{
sl@0
   859
				// display in MB
sl@0
   860
				freeSpace = I64LOW(v.iFree / (1024 * 1024));
sl@0
   861
				freeSpaceUnit = 'M';
sl@0
   862
				}
sl@0
   863
			else
sl@0
   864
				{
sl@0
   865
				// display in KB
sl@0
   866
				freeSpace = I64LOW(v.iFree/1024);
sl@0
   867
				freeSpaceUnit = 'K';
sl@0
   868
				}
sl@0
   869
			
sl@0
   870
			if(v.iSize > KDiskUnitThreshold)
sl@0
   871
				{
sl@0
   872
				// display in MB
sl@0
   873
				totalSpace = I64LOW(v.iSize / (1024 * 1024));
sl@0
   874
				totalSpaceUnit = 'M';
sl@0
   875
				}
sl@0
   876
			else
sl@0
   877
				{
sl@0
   878
				// display in KB
sl@0
   879
				totalSpace = I64LOW(v.iSize/1024);
sl@0
   880
				totalSpaceUnit = 'K';
sl@0
   881
				}
sl@0
   882
			
sl@0
   883
			test.Printf(_L("Free space on disk: %u %cB (of %u %cB)\r\n"), 
sl@0
   884
						freeSpace, freeSpaceUnit, totalSpace, totalSpaceUnit);
sl@0
   885
sl@0
   886
            TTimeIntervalSeconds timeTaken;
sl@0
   887
            time.UniversalTime();            
sl@0
   888
            r=time.SecondsFrom(startTime,timeTaken);
sl@0
   889
            test(r==KErrNone);
sl@0
   890
            totalTime=timeTaken.Int();
sl@0
   891
sl@0
   892
            TInt seconds = totalTime % 60;
sl@0
   893
            TInt minutes = (totalTime / 60) % 60;
sl@0
   894
            TInt hours   = (totalTime / 3600) % 24;
sl@0
   895
            TInt days    = totalTime / (60 * 60 * 24);
sl@0
   896
            test.Printf(_L("Elapsed Time (%d): %d d %02d:%02d:%02d\r\n"), FillDiskCycle, days, hours, minutes, seconds);
sl@0
   897
            
sl@0
   898
            if(CurrentlyFillingDisk)
sl@0
   899
            	{
sl@0
   900
            	// work out ETA to full disk
sl@0
   901
	            r = time.SecondsFrom(cycleTime, timeTaken);
sl@0
   902
    	        if((r == KErrNone) && (v.iSize > v.iFree))
sl@0
   903
    	        	{
sl@0
   904
		            	totalTime = (TInt) ((v.iFree/1024 * (TInt64) timeTaken.Int()) / (v.iSize/1024 - v.iFree/1024));
sl@0
   905
		    	        seconds = totalTime % 60;
sl@0
   906
    		    	    minutes = (totalTime / 60) % 60;
sl@0
   907
        		    	hours   = (totalTime / 3600) % 24;
sl@0
   908
	            		days    = totalTime / (60 * 60 * 24);
sl@0
   909
            	
sl@0
   910
    	        		test.Printf(_L("ETA to full disk: %d d %02d:%02d:%02d\r\n"), days, hours, minutes, seconds);
sl@0
   911
        	    	}
sl@0
   912
            	}
sl@0
   913
            else 
sl@0
   914
            	{
sl@0
   915
            	// currently emptying disk, update time metrics
sl@0
   916
            	cycleTime.UniversalTime();
sl@0
   917
            	}            	
sl@0
   918
           	
sl@0
   919
			}
sl@0
   920
						
sl@0
   921
			test.Printf(_L("\n"));
sl@0
   922
		}
sl@0
   923
    }
sl@0
   924
#endif
sl@0
   925
sl@0
   926
sl@0
   927
GLDEF_C void CallTestsL()
sl@0
   928
//
sl@0
   929
// Call all tests
sl@0
   930
//
sl@0
   931
    {
sl@0
   932
	TInt r = TheFs.CharToDrive( gSessionPath[0], gDriveNumber );
sl@0
   933
	test( KErrNone == r );
sl@0
   934
	
sl@0
   935
	// select appropriate metrics table
sl@0
   936
	if(IsFileSystemFAT32(TheFs, gDriveNumber)) 
sl@0
   937
		{
sl@0
   938
		TheMetrics = &FAT32Metrics;
sl@0
   939
		RDebug::Printf("Using FAT32 metrics\r\n");
sl@0
   940
		}
sl@0
   941
	else if(IsTestingLFFS())
sl@0
   942
		{
sl@0
   943
		TheMetrics = &LffsMetrics;
sl@0
   944
		RDebug::Printf("Using LFFS metrics\r\n");
sl@0
   945
		}
sl@0
   946
	else
sl@0
   947
		{
sl@0
   948
		TDriveInfo driveInfo;
sl@0
   949
		r=TheFs.Drive(driveInfo, gDriveNumber);
sl@0
   950
		test(r==KErrNone);
sl@0
   951
		
sl@0
   952
		if((driveInfo.iType==EMediaNANDFlash) && !(driveInfo.iMediaAtt & KMediaAttWriteProtected))
sl@0
   953
			{
sl@0
   954
			TheMetrics = &NandMetrics;
sl@0
   955
			RDebug::Printf("Using NAND metrics\r\n");
sl@0
   956
			}
sl@0
   957
		else 
sl@0
   958
			{
sl@0
   959
			TheMetrics = &DefMetrics;
sl@0
   960
			RDebug::Printf("Using default metrics\r\n");
sl@0
   961
			}
sl@0
   962
		}
sl@0
   963
		
sl@0
   964
	FillDiskCycle = 1;
sl@0
   965
#ifdef REUSE_THREAD
sl@0
   966
	gRequestEnd = EFalse;
sl@0
   967
#endif
sl@0
   968
	DoTests();
sl@0
   969
sl@0
   970
    }
sl@0
   971