os/kernelhwsrv/kerneltest/f32test/server/t_fsched.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) 2006-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\server\t_fsched.cpp
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
/**
sl@0
    19
 @file
sl@0
    20
 @internalTechnology 
sl@0
    21
*/
sl@0
    22
sl@0
    23
#define __E32TEST_EXTENSION__
sl@0
    24
sl@0
    25
#include <f32file.h>
sl@0
    26
#include <e32test.h>
sl@0
    27
#include <e32svr.h>
sl@0
    28
#include <f32dbg.h>
sl@0
    29
#include "t_server.h"
sl@0
    30
#include <e32twin.h>
sl@0
    31
#include <e32cmn.h>
sl@0
    32
sl@0
    33
//----------------------------------------------------------------------------------------------
sl@0
    34
//! @SYMTestCaseID      PBASE-T_FSCHED-0191
sl@0
    35
//! @SYMTestType        CIT
sl@0
    36
//! @SYMPREQ            PREQ914
sl@0
    37
//! @SYMTestCaseDesc    This test case is exercising the Fair Scheduling functionality added to 
sl@0
    38
//!						the File Server. There are negative and positive tests. 
sl@0
    39
//! @SYMTestActions     0   setup the environment to execute the tests and benchmarks the time 
sl@0
    40
//!							taken to write the two files that are going to be used during the test
sl@0
    41
//!						1	TestReadingWhileWriting uses two threads (sync case) to write a big file/
sl@0
    42
//!							read a small file simultaneously and verifies that the timing is correct. 
sl@0
    43
//!							Same test in the async case. 
sl@0
    44
//!						2	TestWritingWhileWriting same test as before, but the two operations are 
sl@0
    45
//!							writes. 
sl@0
    46
//!						3 	TestTwoBigOnes does the same test as 1, but with two big files, ensuring
sl@0
    47
//!							that the first starting is the first finishing. 
sl@0
    48
//!						4 	TestReadingWhileWritingSameFile reads a file while it is being written. 
sl@0
    49
//!						5	TestClientDies starts a file write and kills it, then checks the integrity 
sl@0
    50
//!							of the volume. 
sl@0
    51
//!						6 	Finally it performs the benchmark of writing the two files again, to see 
sl@0
    52
//!							if it has been degraded during the execution
sl@0
    53
//!
sl@0
    54
//! @SYMTestExpectedResults finishes if the fair scheduling behaves as expected, panics otherwise
sl@0
    55
//! @SYMTestPriority        High
sl@0
    56
//! @SYMTestStatus          Implemented
sl@0
    57
//----------------------------------------------------------------------------------------------
sl@0
    58
sl@0
    59
sl@0
    60
class RTestThreadSemaphore : public RSemaphore
sl@0
    61
	{
sl@0
    62
public:
sl@0
    63
	inline void Signal(TInt aError = KErrNone) {iError = aError; RSemaphore::Signal();};
sl@0
    64
public:
sl@0
    65
	TInt iError;
sl@0
    66
	};
sl@0
    67
sl@0
    68
// macro to be used in place of test(). Signals main thread if assertion fails
sl@0
    69
#define TEST(x)								\
sl@0
    70
if (!(x))									\
sl@0
    71
	{										\
sl@0
    72
	RThread t;								\
sl@0
    73
	if (t.Id() != gMainThreadId)			\
sl@0
    74
		client.Signal(KErrGeneral); 		\
sl@0
    75
	test(x);								\
sl@0
    76
	}				
sl@0
    77
#define TESTERROR(x)						\
sl@0
    78
	if (x != KErrNone)						\
sl@0
    79
	{										\
sl@0
    80
	RThread t;								\
sl@0
    81
	if (t.Id() != gMainThreadId)			\
sl@0
    82
		RDebug::Print(_L("error %d\n"), x);	\
sl@0
    83
	else									\
sl@0
    84
		test.Printf(_L("error %d\n"), x);	\
sl@0
    85
	TEST(x==KErrNone);								\
sl@0
    86
	}
sl@0
    87
sl@0
    88
#define CLIENTWAIT() {client.Wait(); test(client.iError == KErrNone);}
sl@0
    89
sl@0
    90
////////////////////////////////////////////////////////////
sl@0
    91
// Template functions encapsulating ControlIo magic
sl@0
    92
//
sl@0
    93
GLDEF_D template <class C>
sl@0
    94
GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
sl@0
    95
{
sl@0
    96
    TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
sl@0
    97
sl@0
    98
    TInt r = fs.ControlIo(drv, fkn, ptrC);
sl@0
    99
sl@0
   100
    return r;
sl@0
   101
}
sl@0
   102
sl@0
   103
sl@0
   104
GLDEF_D RTest test(_L("T_FSCHED"));
sl@0
   105
sl@0
   106
GLDEF_D	RFs TheFs;
sl@0
   107
GLDEF_D TInt gDrive;
sl@0
   108
GLDEF_D TFileName gSessionPath;
sl@0
   109
GLDEF_D TChar gDriveToTest;	
sl@0
   110
TThreadId gMainThreadId;
sl@0
   111
sl@0
   112
HBufC8* gBuf = NULL;
sl@0
   113
TPtr8 gBufReadPtr(NULL, 0);	
sl@0
   114
HBufC8* gBufSec = NULL;
sl@0
   115
TPtr8 gBufWritePtr(NULL, 0);	
sl@0
   116
sl@0
   117
const TInt KuStomS = 1000;
sl@0
   118
const TInt KOneK = 1024;
sl@0
   119
const TInt KOneMeg = KOneK * 1024;
sl@0
   120
const TInt KBigBlockSize = KOneMeg ; 
sl@0
   121
const TInt KBlockSize = KOneK * 129 ; 
sl@0
   122
const TInt KWaitRequestsTableSize = 70;
sl@0
   123
sl@0
   124
TInt gBigFileSize = 0; 
sl@0
   125
TInt gSmallFileSize = 0;
sl@0
   126
TInt64 gMediaSize = 0;
sl@0
   127
TInt gTotalTimeSync[2];
sl@0
   128
TInt gTotalTimeAsync[2];
sl@0
   129
sl@0
   130
TTimeIntervalMicroSeconds32 gTimeTakenBigFile(0);
sl@0
   131
TTimeIntervalMicroSeconds32 gTimeTakenBigBlock(0);
sl@0
   132
TBuf16<45> gSmallFile, gBigFile;
sl@0
   133
TInt gNextFile=0;
sl@0
   134
TTime gTime1;
sl@0
   135
TTime gTime2;
sl@0
   136
sl@0
   137
RSemaphore gSync;
sl@0
   138
sl@0
   139
// Concurrent Threads
sl@0
   140
RThread gBig;
sl@0
   141
RThread gSmall;
sl@0
   142
RTestThreadSemaphore client;	
sl@0
   143
const TInt KHeapSize = 0x4000;
sl@0
   144
const TInt KMaxHeapSize = 0x200000;
sl@0
   145
TRequestStatus gStatus[KWaitRequestsTableSize];
sl@0
   146
sl@0
   147
enum TTestState 
sl@0
   148
	{
sl@0
   149
	EThreadWait,
sl@0
   150
	EThreadSignal,
sl@0
   151
	ENoThreads	
sl@0
   152
	};
sl@0
   153
sl@0
   154
/** Generates a file name of the form FFFFF*<aPos>.TXT (aLong.3)
sl@0
   155
sl@0
   156
	@param aBuffer The filename will be returned here
sl@0
   157
	@param aLong   Defines the longitude of the file name 
sl@0
   158
	@param aPos	   Defines the number that will be attached to the filename
sl@0
   159
*/
sl@0
   160
void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos) 
sl@0
   161
{
sl@0
   162
	TInt padding;
sl@0
   163
	TInt i=0;
sl@0
   164
	TBuf16<10> tempbuf;
sl@0
   165
	
sl@0
   166
	_LIT(KNumber,"%d");
sl@0
   167
	tempbuf.Format(KNumber,aPos);
sl@0
   168
	padding=aLong-tempbuf.Size()/2;
sl@0
   169
	aBuffer=_L("");
sl@0
   170
	while(i<padding)
sl@0
   171
	{
sl@0
   172
		aBuffer.Append('F');
sl@0
   173
		i++;
sl@0
   174
	}
sl@0
   175
	aBuffer.Append(tempbuf);
sl@0
   176
	
sl@0
   177
	_LIT(KExtension1, ".TXT");
sl@0
   178
	aBuffer.Append(KExtension1);
sl@0
   179
}
sl@0
   180
sl@0
   181
sl@0
   182
/**  Reads the parameters from the comand line 
sl@0
   183
	 and updates the appropriate variables
sl@0
   184
*/
sl@0
   185
void parseCommandLine() 
sl@0
   186
{
sl@0
   187
	TBuf<0x100> cmd;
sl@0
   188
	User::CommandLine(cmd);
sl@0
   189
	TLex lex(cmd);
sl@0
   190
	TPtrC token=lex.NextToken();
sl@0
   191
	TInt r=0;
sl@0
   192
sl@0
   193
	if(token.Length()!=0)		
sl@0
   194
		{
sl@0
   195
		gDriveToTest = token[0];
sl@0
   196
		gDriveToTest.UpperCase();
sl@0
   197
		}
sl@0
   198
	else						
sl@0
   199
		{
sl@0
   200
		gDriveToTest='C';
sl@0
   201
		}	
sl@0
   202
		
sl@0
   203
	r = TheFs.CharToDrive(gDriveToTest,gDrive);
sl@0
   204
	TESTERROR(r);
sl@0
   205
	gSessionPath = _L("?:\\F32-TST\\");
sl@0
   206
	gSessionPath[0] = (TText)(gDrive+'A');
sl@0
   207
	test.Printf(_L("\nCLP=%C\n"), (TInt)gDriveToTest);
sl@0
   208
}
sl@0
   209
sl@0
   210
/** Verifies the content of a buffer (all the letters are like the first one)
sl@0
   211
sl@0
   212
	@param aBuffer  Buffer to be verified
sl@0
   213
	
sl@0
   214
	@return KErrNone if all the letters are the same, KErrCorrupt otherwise
sl@0
   215
*/
sl@0
   216
TInt VerifyBuffer(TDes8& aBuffer, TChar aExpectedChar)
sl@0
   217
	{
sl@0
   218
	TChar c = aExpectedChar;
sl@0
   219
	
sl@0
   220
	for(TInt i = 1; i<aBuffer.Length(); i++)
sl@0
   221
		{
sl@0
   222
		if(c != (TChar)(aBuffer[i])) 
sl@0
   223
			{
sl@0
   224
			RDebug::Print(_L("VerifyBuffer() failed at +%d, %02X != %02X"), i, (TInt) c, aBuffer[i] );
sl@0
   225
			return KErrCorrupt;
sl@0
   226
			}
sl@0
   227
		}
sl@0
   228
		
sl@0
   229
	return KErrNone;
sl@0
   230
	}
sl@0
   231
sl@0
   232
/**  Fills a buffer with character aC
sl@0
   233
sl@0
   234
	@param aBuffer  Buffer to be filled, output
sl@0
   235
	@param aLength  Length to be filled
sl@0
   236
	@param aC		Character to be used to fill the buffer
sl@0
   237
*/
sl@0
   238
void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC)
sl@0
   239
	{
sl@0
   240
	test (aBuffer.MaxLength() >= aLength);
sl@0
   241
	for(TInt i=0; i<aLength; i++)
sl@0
   242
		{
sl@0
   243
		aBuffer.Append(aC);
sl@0
   244
		}
sl@0
   245
	}
sl@0
   246
sl@0
   247
/**  Waits for all the TRequestStatus in status[] to complete
sl@0
   248
sl@0
   249
	@param status 	Array of TRequestStatus 
sl@0
   250
	@param aLength  Length to be filled
sl@0
   251
	@param aC		Character to be used to fill the buffer
sl@0
   252
*/
sl@0
   253
void WaitForAll(TRequestStatus* status, TInt aFileSize, TInt aBlockSize) 
sl@0
   254
{
sl@0
   255
	TInt i = 0;
sl@0
   256
	TInt size = 0;
sl@0
   257
sl@0
   258
	if((aFileSize % aBlockSize) == 0 ) 
sl@0
   259
		size = aFileSize/aBlockSize;	
sl@0
   260
	else 
sl@0
   261
		size = (aFileSize/aBlockSize) + 1;	
sl@0
   262
sl@0
   263
	while(i < size)
sl@0
   264
	{
sl@0
   265
		User::WaitForRequest(status[i++]);	
sl@0
   266
	}
sl@0
   267
}
sl@0
   268
sl@0
   269
/**  Writes a file synchronously in blocks of aBlockSize size
sl@0
   270
sl@0
   271
	@param fs			RFs object
sl@0
   272
	@param aFile		File name
sl@0
   273
	@param aSize		Size of the file in bytes
sl@0
   274
	@param aBlockSize	Size of the blocks to be used in bytes
sl@0
   275
	@param aState		Determines if the operation is being done in the main process
sl@0
   276
						or in a thread
sl@0
   277
						
sl@0
   278
	@return Returns KErrNone if everything ok, otherwise it panics 
sl@0
   279
*/
sl@0
   280
TInt WriteFile(RFs& fs, TDes16& aFile, TInt aSize, TInt aBlockSize, TTestState aState) 
sl@0
   281
	{
sl@0
   282
	TInt r = 0;
sl@0
   283
	RFile fileWrite;
sl@0
   284
sl@0
   285
	TEST(aBlockSize>0);	
sl@0
   286
	
sl@0
   287
	r = fileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite|EFileWriteDirectIO);
sl@0
   288
	TESTERROR(r);
sl@0
   289
sl@0
   290
	if(aState==EThreadWait)
sl@0
   291
	{
sl@0
   292
		gSync.Wait();
sl@0
   293
		User::After(gTimeTakenBigBlock);
sl@0
   294
	}
sl@0
   295
sl@0
   296
	TInt j = 0;
sl@0
   297
	while(j < aSize)
sl@0
   298
		{
sl@0
   299
			if((j == 0) && (aState == EThreadSignal))
sl@0
   300
			{
sl@0
   301
				gSync.Signal();
sl@0
   302
			}			
sl@0
   303
sl@0
   304
			if((aSize - j) >= aBlockSize) 	// All the blocks but the last one
sl@0
   305
				r = fileWrite.Write(gBufWritePtr, aBlockSize); 
sl@0
   306
			else							// The last block
sl@0
   307
				r = fileWrite.Write(gBufWritePtr, (aSize - j)); 
sl@0
   308
				
sl@0
   309
			TESTERROR(r);
sl@0
   310
			j += aBlockSize;
sl@0
   311
		}					
sl@0
   312
sl@0
   313
	fileWrite.Close();
sl@0
   314
	
sl@0
   315
	return KErrNone;	
sl@0
   316
	}
sl@0
   317
sl@0
   318
/**  Read File in blocks of size aBlockSize
sl@0
   319
sl@0
   320
	@param fs			RFs object
sl@0
   321
	@param aFile		File name
sl@0
   322
	@param aBlockSize	Size of the blocks to be used in bytes
sl@0
   323
	@param aState		Determines if the operation is being done in the main process
sl@0
   324
						or in a thread
sl@0
   325
						
sl@0
   326
	@return Returns KErrNone if everything ok, otherwise it panics 
sl@0
   327
*/
sl@0
   328
TInt ReadFile(RFs& fs, TDes16& aFile, TInt aBlockSize, TTestState aState) 
sl@0
   329
	{
sl@0
   330
	RTest test(_L("T_FSCHED"));
sl@0
   331
	TInt r = 0, size = 0;
sl@0
   332
	RFile fileRead;
sl@0
   333
	
sl@0
   334
	TEST(aBlockSize > 0);		
sl@0
   335
sl@0
   336
	r = fileRead.Open(fs, aFile, EFileShareAny|EFileRead|EFileReadDirectIO);
sl@0
   337
	TESTERROR(r);
sl@0
   338
	
sl@0
   339
	r = fileRead.Size(size);
sl@0
   340
	TESTERROR(r);
sl@0
   341
	
sl@0
   342
	if(aState == EThreadWait)
sl@0
   343
	{
sl@0
   344
		gSync.Wait();
sl@0
   345
		User::After(gTimeTakenBigBlock);
sl@0
   346
	}
sl@0
   347
sl@0
   348
	TInt j = 0;
sl@0
   349
	while(j < size) 
sl@0
   350
		{
sl@0
   351
			if((j == 0)&&(aState == EThreadSignal))
sl@0
   352
			{
sl@0
   353
				gSync.Signal();
sl@0
   354
			}			
sl@0
   355
			r = fileRead.Read(gBufReadPtr, aBlockSize);
sl@0
   356
			TESTERROR(r);
sl@0
   357
			r = VerifyBuffer(gBufReadPtr, 'B');	
sl@0
   358
			TESTERROR(r);
sl@0
   359
			
sl@0
   360
			j += aBlockSize;
sl@0
   361
			r = fileRead.Size(size);
sl@0
   362
			TESTERROR(r);
sl@0
   363
		}					
sl@0
   364
sl@0
   365
	fileRead.Close();
sl@0
   366
sl@0
   367
	return KErrNone;	
sl@0
   368
	}
sl@0
   369
sl@0
   370
sl@0
   371
/**  Write a file asynchronously in blocks of aBlockSize size
sl@0
   372
sl@0
   373
	@param fs			RFs object
sl@0
   374
	@param aFileWrite	RFile object, needs to exist beyond the scope of this function
sl@0
   375
	@param aFile		File name
sl@0
   376
	@param aSize		Size of the file in bytes
sl@0
   377
	@param aBlockSize	Size of the blocks to be used in bytes
sl@0
   378
	@param aStatus		TRequestStatus array for all the requests
sl@0
   379
*/
sl@0
   380
void WriteFileAsync(RFs& fs, RFile& aFileWrite, TDes16& aFile, TInt aSize, TInt aBlockSize, TRequestStatus aStatus[]) 
sl@0
   381
	{
sl@0
   382
		
sl@0
   383
	TInt r = 0;
sl@0
   384
	
sl@0
   385
	TEST(aBlockSize > 0);				// Block size must be greater than 0
sl@0
   386
sl@0
   387
	r = aFileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite|EFileWriteDirectIO);
sl@0
   388
	TESTERROR(r);
sl@0
   389
sl@0
   390
	TInt j = 0;
sl@0
   391
	TInt i = 0;
sl@0
   392
	while(j < aSize)
sl@0
   393
		{
sl@0
   394
		if((aSize - j) >= aBlockSize) 	// All the blocks but the last one
sl@0
   395
			aFileWrite.Write(gBufWritePtr, aBlockSize, aStatus[i]); 
sl@0
   396
		else							// The last block
sl@0
   397
			aFileWrite.Write(gBufWritePtr, (aSize - j), aStatus[i]); 
sl@0
   398
sl@0
   399
		TInt status = aStatus[i].Int();
sl@0
   400
		if (status != KErrNone && status != KRequestPending)
sl@0
   401
			{
sl@0
   402
			test.Printf(_L("RFile::Write() returned %d\n"), aStatus[i].Int());
sl@0
   403
			}
sl@0
   404
sl@0
   405
		test (status == KErrNone || status == KRequestPending);
sl@0
   406
		i++;
sl@0
   407
		j += aBlockSize;	
sl@0
   408
		}					
sl@0
   409
	}
sl@0
   410
sl@0
   411
/**  Read a file asynchronously in blocks of aBlockSize size
sl@0
   412
sl@0
   413
	@param fs			RFs object
sl@0
   414
	@param aFileRead	RFile object, needs to exist beyond the scope of this function
sl@0
   415
	@param aFile		File name
sl@0
   416
	@param aSize		Size of the file in bytes
sl@0
   417
	@param aBlockSize	Size of the blocks to be used in bytes
sl@0
   418
	@param aStatus		TRequestStatus array for all the requests
sl@0
   419
	
sl@0
   420
	@return KErrNone
sl@0
   421
*/
sl@0
   422
TInt ReadFileAsync(RFs& fs, RFile& aFileRead, TDes16& aFile, TInt aBlockSize, TRequestStatus aStatus[]) 
sl@0
   423
	{
sl@0
   424
	TInt r = 0, size = 0;
sl@0
   425
	
sl@0
   426
	TEST(aBlockSize > 0);				// Block size must be greater than 0
sl@0
   427
	
sl@0
   428
sl@0
   429
	r = aFileRead.Open(fs, aFile, EFileShareAny|EFileRead|EFileReadDirectIO);
sl@0
   430
	TESTERROR(r);
sl@0
   431
	
sl@0
   432
	r = aFileRead.Size(size);
sl@0
   433
	TESTERROR(r);
sl@0
   434
	
sl@0
   435
	TInt j = 0, i = 0;
sl@0
   436
	while(j < size) 
sl@0
   437
		{
sl@0
   438
		aFileRead.Read(gBufReadPtr, aBlockSize, aStatus[i]);
sl@0
   439
		test (aStatus[i].Int() == KErrNone || aStatus[i].Int() == KRequestPending);
sl@0
   440
		i++;
sl@0
   441
		TESTERROR(r);
sl@0
   442
		j += aBlockSize;
sl@0
   443
		}					
sl@0
   444
sl@0
   445
	return KErrNone;	
sl@0
   446
	}
sl@0
   447
sl@0
   448
sl@0
   449
/**  
sl@0
   450
Write a pattern to 2 files simultaneously in blocks of aBlockSize size and verify that fair scheduling
sl@0
   451
does not interfere with the write order by reading both files back and verifying the contents.
sl@0
   452
sl@0
   453
aBlockSize should be slightly bigger that the fair scheduling size
sl@0
   454
sl@0
   455
@param aFs			RFs object
sl@0
   456
@param aSize		Size of the file in bytes
sl@0
   457
@param aBlockSize	Size of the blocks to be used in bytes, should be slightly bigger that the fair scheduling size
sl@0
   458
*/
sl@0
   459
void WriteOrderTest(RFs& aFs, TInt aSize, TInt aBlockSize) 
sl@0
   460
	{
sl@0
   461
	TFileName fileName1, fileName2;
sl@0
   462
	FileNameGen(fileName1, 8, 99);
sl@0
   463
	FileNameGen(fileName2, 8, 100);
sl@0
   464
sl@0
   465
	RFile file1, file2;
sl@0
   466
sl@0
   467
	TRequestStatus status1[KWaitRequestsTableSize];
sl@0
   468
	TRequestStatus status2[KWaitRequestsTableSize];
sl@0
   469
sl@0
   470
	TInt r = 0;
sl@0
   471
	
sl@0
   472
	TEST(aBlockSize > 0);				// Block size must be greater than 0
sl@0
   473
sl@0
   474
	r = file1.Replace(aFs, fileName1,EFileShareAny|EFileWrite|EFileWriteDirectIO);
sl@0
   475
	TESTERROR(r);
sl@0
   476
sl@0
   477
	r = file2.Replace(aFs, fileName2,EFileShareAny|EFileWrite|EFileWriteDirectIO);
sl@0
   478
	TESTERROR(r);
sl@0
   479
sl@0
   480
sl@0
   481
	HBufC8* buf1 = NULL;
sl@0
   482
	TRAP(r,buf1 = HBufC8::NewL(KBigBlockSize));
sl@0
   483
	TEST(r == KErrNone && buf1 != NULL);
sl@0
   484
sl@0
   485
	TInt maxBlockNum = KBigBlockSize / aBlockSize;
sl@0
   486
	TInt blockNum = 0;
sl@0
   487
	TInt blocksFree = maxBlockNum;
sl@0
   488
sl@0
   489
	TInt blockHead = 0;		// ha ha
sl@0
   490
	TInt blockTail = 0;
sl@0
   491
sl@0
   492
sl@0
   493
	TPtrC8* writeBuffer = new TPtrC8[maxBlockNum];
sl@0
   494
	for (TInt n=0; n<maxBlockNum; n++)
sl@0
   495
		{
sl@0
   496
		TUint8* addr = (TUint8*) buf1->Des().Ptr() + (n * aBlockSize);
sl@0
   497
		writeBuffer[n].Set(addr, aBlockSize);
sl@0
   498
		}
sl@0
   499
sl@0
   500
	TInt j = 0;
sl@0
   501
	TInt i = 0;
sl@0
   502
	while(j < aSize)
sl@0
   503
		{
sl@0
   504
sl@0
   505
		// fill the buffer with a char based on the block number
sl@0
   506
		TPtr8 bufWritePtr((TUint8*) writeBuffer[blockHead].Ptr(), 0, writeBuffer[blockHead].Length());
sl@0
   507
		TUint8* addr = (TUint8*) buf1->Des().Ptr() + (blockHead * aBlockSize);
sl@0
   508
		bufWritePtr.Set(addr, 0, aBlockSize);
sl@0
   509
		FillBuffer(bufWritePtr, aBlockSize, 'A'+blockNum);
sl@0
   510
sl@0
   511
//test.Printf(_L("j %d, addr %08X, aSize %d, blockNum %d, blockTail %d, blockHead %d, maxBlockNum %d, blocksFree %d\n"), 
sl@0
   512
//	j, writeBuffer[blockHead].Ptr(), aSize, blockNum, blockTail, blockHead, maxBlockNum, blocksFree);
sl@0
   513
sl@0
   514
		if((aSize - j) >= aBlockSize) 	// All the blocks but the last one
sl@0
   515
			file1.Write(writeBuffer[blockHead], aBlockSize, status1[blockHead]); 
sl@0
   516
		else							// The last block
sl@0
   517
			file1.Write(writeBuffer[blockHead], (aSize - j), status1[blockHead]); 
sl@0
   518
sl@0
   519
		if((aSize - j) >= aBlockSize) 	// All the blocks but the last one
sl@0
   520
			file2.Write(writeBuffer[blockHead], aBlockSize, status2[blockHead]); 
sl@0
   521
		else							// The last block
sl@0
   522
			file2.Write(writeBuffer[blockHead], (aSize - j), status2[blockHead]); 
sl@0
   523
sl@0
   524
		TInt status = status1[blockHead].Int();
sl@0
   525
		if (status != KErrNone && status != KRequestPending)
sl@0
   526
			test.Printf(_L("RFile::Write() returned %d\n"), status1[blockHead].Int());
sl@0
   527
		test (status == KErrNone || status == KRequestPending);
sl@0
   528
sl@0
   529
		status = status2[blockHead].Int();
sl@0
   530
		if (status != KErrNone && status != KRequestPending)
sl@0
   531
			test.Printf(_L("RFile::Write() returned %d\n"), status1[blockHead].Int());
sl@0
   532
		test (status == KErrNone || status == KRequestPending);
sl@0
   533
sl@0
   534
		i++;
sl@0
   535
		j += aBlockSize;	
sl@0
   536
		blockNum++;
sl@0
   537
		blockHead = (blockHead + 1) % maxBlockNum;
sl@0
   538
		blocksFree--;
sl@0
   539
sl@0
   540
		if (blocksFree == 0)
sl@0
   541
			{
sl@0
   542
//test.Printf(_L("Waiting for block %d\n"), blockTail);
sl@0
   543
			User::WaitForRequest(status1[blockTail]);
sl@0
   544
			User::WaitForRequest(status2[blockTail]);
sl@0
   545
			blockTail = (blockTail + 1) % maxBlockNum;
sl@0
   546
			blocksFree++;
sl@0
   547
			}
sl@0
   548
sl@0
   549
		}					
sl@0
   550
	
sl@0
   551
		while (blockTail != blockHead)
sl@0
   552
			{
sl@0
   553
//test.Printf(_L("Waiting for block %d\n"), blockTail);
sl@0
   554
			User::WaitForRequest(status1[blockTail]);
sl@0
   555
			User::WaitForRequest(status2[blockTail]);
sl@0
   556
			blockTail = (blockTail + 1) % maxBlockNum;
sl@0
   557
			blocksFree++;
sl@0
   558
			}
sl@0
   559
sl@0
   560
	file1.Close();	
sl@0
   561
	file2.Close();	
sl@0
   562
sl@0
   563
	// Verify file1
sl@0
   564
	r = file1.Open(aFs, fileName1, EFileShareAny|EFileRead|EFileReadDirectIO);
sl@0
   565
	TESTERROR(r);
sl@0
   566
	TInt size;
sl@0
   567
	r = file1.Size(size);
sl@0
   568
	TESTERROR(r);
sl@0
   569
	blockNum = 0;
sl@0
   570
	j = 0;
sl@0
   571
	while(j < size) 
sl@0
   572
		{
sl@0
   573
		TPtr8 readPtr((TUint8*) writeBuffer[0].Ptr(), aBlockSize, aBlockSize);
sl@0
   574
		r = file1.Read(readPtr);
sl@0
   575
		TESTERROR(r);
sl@0
   576
		r = VerifyBuffer(readPtr, 'A' + blockNum);	
sl@0
   577
		TESTERROR(r);
sl@0
   578
		j += aBlockSize;
sl@0
   579
		blockNum++;
sl@0
   580
		}	
sl@0
   581
	
sl@0
   582
	// Verify file2
sl@0
   583
	r = file2.Open(aFs, fileName2, EFileShareAny|EFileRead|EFileReadDirectIO);
sl@0
   584
	TESTERROR(r);
sl@0
   585
	r = file2.Size(size);
sl@0
   586
	TESTERROR(r);
sl@0
   587
	blockNum = 0;
sl@0
   588
	j = 0;
sl@0
   589
	while(j < size) 
sl@0
   590
		{
sl@0
   591
		TPtr8 readPtr((TUint8*) writeBuffer[0].Ptr(), aBlockSize, aBlockSize);
sl@0
   592
		r = file2.Read(readPtr);
sl@0
   593
		TESTERROR(r);
sl@0
   594
		r = VerifyBuffer(readPtr, 'A' + blockNum);	
sl@0
   595
		TESTERROR(r);
sl@0
   596
		j += aBlockSize;
sl@0
   597
		blockNum++;
sl@0
   598
		}	
sl@0
   599
	
sl@0
   600
	file2.Close();			
sl@0
   601
	file1.Close();			
sl@0
   602
	
sl@0
   603
	delete [] writeBuffer;
sl@0
   604
	delete buf1;
sl@0
   605
sl@0
   606
	r = aFs.Delete(fileName1);
sl@0
   607
	TEST(r == KErrNone);
sl@0
   608
	r = aFs.Delete(fileName2);
sl@0
   609
	TEST(r == KErrNone);
sl@0
   610
	}
sl@0
   611
sl@0
   612
sl@0
   613
sl@0
   614
/** Measure the time taken for a big block to be written synchronously
sl@0
   615
*/
sl@0
   616
void TimeTakenToWriteBigBlock() 
sl@0
   617
{
sl@0
   618
	TTime startTime;
sl@0
   619
	TTime endTime;
sl@0
   620
	RFile fileWrite;
sl@0
   621
	
sl@0
   622
	TInt r = fileWrite.Replace(TheFs,gBigFile,EFileShareAny|EFileWrite|EFileWriteDirectIO);
sl@0
   623
	TESTERROR(r);
sl@0
   624
sl@0
   625
	// Calculate how long it takes to write a big block to be able to issue at the right time the concurrent writes
sl@0
   626
	startTime.HomeTime();
sl@0
   627
	
sl@0
   628
	r = fileWrite.Write(gBufWritePtr, KBigBlockSize); 
sl@0
   629
	
sl@0
   630
	endTime.HomeTime();
sl@0
   631
	
sl@0
   632
	fileWrite.Close();
sl@0
   633
sl@0
   634
	TESTERROR(r);
sl@0
   635
	
sl@0
   636
	gTimeTakenBigBlock = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()/3);
sl@0
   637
sl@0
   638
	test.Printf(_L("\nTime spent to write the big block in isolation: %d ms\n"), gTimeTakenBigBlock.Int() / KuStomS);
sl@0
   639
}
sl@0
   640
	
sl@0
   641
sl@0
   642
/** Measure the time taken for this file to be written synchronously
sl@0
   643
*/
sl@0
   644
void TimeTakenToWriteBigFile(TInt aPos) 
sl@0
   645
{
sl@0
   646
	TTime startTime;
sl@0
   647
	TTime endTime;
sl@0
   648
	
sl@0
   649
	test((aPos >= 0) && (aPos <= 1));
sl@0
   650
	startTime.HomeTime();
sl@0
   651
	
sl@0
   652
	WriteFile(TheFs,gBigFile, gBigFileSize, KBigBlockSize, ENoThreads);
sl@0
   653
	
sl@0
   654
	endTime.HomeTime();
sl@0
   655
sl@0
   656
	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
sl@0
   657
	
sl@0
   658
	
sl@0
   659
	test.Printf(_L("\nTime spent to write the big file in isolation: %d ms\n"), gTimeTakenBigFile.Int() / KuStomS);
sl@0
   660
	
sl@0
   661
	gTotalTimeSync[aPos] = Max((gTimeTakenBigFile.Int()/KuStomS), gTotalTimeSync[aPos]) ;
sl@0
   662
}
sl@0
   663
sl@0
   664
/** Measure the time taken for this file to be written asynchronously
sl@0
   665
*/
sl@0
   666
void TimeTakenToWriteBigFileAsync(TInt aPos) 
sl@0
   667
{
sl@0
   668
	TTime startTime;
sl@0
   669
	TTime endTime;
sl@0
   670
	TTime endTime2;
sl@0
   671
	TRequestStatus status[KWaitRequestsTableSize];
sl@0
   672
	RFile bigFile;
sl@0
   673
	
sl@0
   674
	test((aPos >= 0) && (aPos <= 1));
sl@0
   675
	
sl@0
   676
	startTime.HomeTime();
sl@0
   677
	WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize,KBigBlockSize,status); 
sl@0
   678
	endTime.HomeTime();
sl@0
   679
sl@0
   680
	
sl@0
   681
	WaitForAll(status, gBigFileSize, KBigBlockSize);	
sl@0
   682
	
sl@0
   683
	endTime2.HomeTime();
sl@0
   684
	
sl@0
   685
	gTimeTakenBigFile=I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
sl@0
   686
	bigFile.Close();
sl@0
   687
	test.Printf(_L("\nTime to queue the blocks in isolation asynchronously: %d ms, "), gTimeTakenBigFile.Int() / KuStomS);
sl@0
   688
	gTimeTakenBigFile=I64LOW(endTime2.MicroSecondsFrom(startTime).Int64());
sl@0
   689
	test.Printf(_L("to actually write it: %d ms\n"),gTimeTakenBigFile.Int() / KuStomS);
sl@0
   690
	gTotalTimeAsync[aPos] = Max((gTimeTakenBigFile.Int() / KuStomS), gTotalTimeAsync[aPos]) ; 
sl@0
   691
}
sl@0
   692
sl@0
   693
/**  Delete content of directory
sl@0
   694
sl@0
   695
	@param aDir	Target directory
sl@0
   696
	
sl@0
   697
	@return Error returned if any, otherwise KErrNone
sl@0
   698
*/
sl@0
   699
TInt DeleteAll(TDes16& aDir) 
sl@0
   700
	{
sl@0
   701
		TBuf16<100> dir;
sl@0
   702
		CFileMan* fMan=CFileMan::NewL(TheFs);
sl@0
   703
		TInt r=0;
sl@0
   704
		
sl@0
   705
		dir = aDir;
sl@0
   706
		dir.Append(_L("F*.*"));
sl@0
   707
		r = fMan->Delete(dir);	
sl@0
   708
sl@0
   709
		delete fMan;
sl@0
   710
		return r;
sl@0
   711
	}
sl@0
   712
sl@0
   713
/**  Read a small file sync, in a different thread
sl@0
   714
sl@0
   715
	@return ETrue
sl@0
   716
*/
sl@0
   717
TInt ReadSmallFile(TAny* )
sl@0
   718
	{
sl@0
   719
	RTest test(_L("T_FSCHED"));
sl@0
   720
	RFs fs;
sl@0
   721
	TInt r=fs.Connect();
sl@0
   722
	TESTERROR(r);
sl@0
   723
sl@0
   724
	r = fs.SetSessionPath(gSessionPath);
sl@0
   725
	TESTERROR(r);
sl@0
   726
	
sl@0
   727
	ReadFile(fs,gSmallFile,KBlockSize, EThreadWait);
sl@0
   728
	gTime2.HomeTime();
sl@0
   729
	
sl@0
   730
	client.Signal();
sl@0
   731
	
sl@0
   732
	fs.Close();
sl@0
   733
	test.Close();
sl@0
   734
	
sl@0
   735
	return ETrue;
sl@0
   736
	}
sl@0
   737
sl@0
   738
/**  Read the big file sync, in a different thread
sl@0
   739
sl@0
   740
	@return ETrue
sl@0
   741
*/
sl@0
   742
TInt ReadBigFile(TAny* )
sl@0
   743
	{
sl@0
   744
	RTest test(_L("T_FSCHED"));
sl@0
   745
	RFs fs;
sl@0
   746
	TInt r=fs.Connect();
sl@0
   747
	TESTERROR(r);
sl@0
   748
sl@0
   749
	r=fs.SetSessionPath(gSessionPath);
sl@0
   750
	TESTERROR(r);
sl@0
   751
	
sl@0
   752
	ReadFile(fs,gBigFile,KBlockSize, EThreadWait);
sl@0
   753
	gTime2.HomeTime();
sl@0
   754
	
sl@0
   755
	client.Signal();
sl@0
   756
		
sl@0
   757
	fs.Close();
sl@0
   758
	test.Close();
sl@0
   759
	
sl@0
   760
	return ETrue;
sl@0
   761
	}
sl@0
   762
sl@0
   763
/**  Write a small file sync, in a different thread
sl@0
   764
sl@0
   765
	@return ETrue
sl@0
   766
*/
sl@0
   767
TInt WriteSmallFile(TAny* )
sl@0
   768
	{
sl@0
   769
	RTest test(_L("T_FSCHED"));
sl@0
   770
	RFs fs;
sl@0
   771
	TInt r=fs.Connect();
sl@0
   772
	TESTERROR(r);
sl@0
   773
sl@0
   774
	r=fs.SetSessionPath(gSessionPath);
sl@0
   775
	TESTERROR(r);
sl@0
   776
	
sl@0
   777
	WriteFile(fs,gSmallFile,gSmallFileSize, KBlockSize, EThreadWait);
sl@0
   778
	gTime2.HomeTime();
sl@0
   779
	
sl@0
   780
	client.Signal();
sl@0
   781
	
sl@0
   782
	fs.Close();
sl@0
   783
	test.Close();
sl@0
   784
	
sl@0
   785
	return ETrue;
sl@0
   786
	}
sl@0
   787
sl@0
   788
/**  Write a big file sync, in a different thread
sl@0
   789
sl@0
   790
	@return ETrue
sl@0
   791
*/
sl@0
   792
TInt WriteBigFile(TAny* )
sl@0
   793
	{
sl@0
   794
	RTest test(_L("T_FSCHED"));
sl@0
   795
	RFs fs;
sl@0
   796
	TInt r=fs.Connect();
sl@0
   797
	TESTERROR(r);
sl@0
   798
sl@0
   799
	r=fs.SetSessionPath(gSessionPath);
sl@0
   800
	TESTERROR(r);
sl@0
   801
	
sl@0
   802
	WriteFile(fs, gBigFile, gBigFileSize, KBigBlockSize, EThreadSignal); 
sl@0
   803
	gTime1.HomeTime();
sl@0
   804
	
sl@0
   805
	client.Signal();
sl@0
   806
	
sl@0
   807
	fs.Close();
sl@0
   808
	test.Close();
sl@0
   809
	
sl@0
   810
	return ETrue;
sl@0
   811
	}
sl@0
   812
sl@0
   813
/**   Write big file after a signalling thread has been scheduled, in a different thread
sl@0
   814
sl@0
   815
	@return ETrue
sl@0
   816
*/
sl@0
   817
TInt WriteBigFile2(TAny* )
sl@0
   818
	{
sl@0
   819
	RTest test(_L("T_FSCHED"));
sl@0
   820
	RFs fs;
sl@0
   821
	TInt r=fs.Connect();
sl@0
   822
	TESTERROR(r);
sl@0
   823
sl@0
   824
	r = fs.SetSessionPath(gSessionPath);
sl@0
   825
	TESTERROR(r);
sl@0
   826
	
sl@0
   827
	WriteFile(fs, gSmallFile, gBigFileSize, KBigBlockSize, EThreadWait); 
sl@0
   828
	gTime2.HomeTime();
sl@0
   829
	
sl@0
   830
	client.Signal();
sl@0
   831
	
sl@0
   832
	fs.Close();
sl@0
   833
	test.Close();
sl@0
   834
	
sl@0
   835
	return ETrue;
sl@0
   836
	}
sl@0
   837
sl@0
   838
/**  Write a big file async, in a different thread
sl@0
   839
sl@0
   840
	@return ETrue
sl@0
   841
*/
sl@0
   842
TInt WriteBigFileAsync(TAny* )
sl@0
   843
	{
sl@0
   844
	RTest test(_L("T_FSCHED"));
sl@0
   845
	RFs fs;
sl@0
   846
	TInt r = fs.Connect();
sl@0
   847
	TESTERROR(r);
sl@0
   848
sl@0
   849
	r=fs.SetSessionPath(gSessionPath);
sl@0
   850
	TESTERROR(r);
sl@0
   851
	
sl@0
   852
sl@0
   853
	RFile bigFile;
sl@0
   854
	
sl@0
   855
	WriteFileAsync(fs, bigFile, gSmallFile, gBigFileSize, KBlockSize,gStatus); 
sl@0
   856
	gSync.Signal();
sl@0
   857
	WaitForAll(gStatus, gBigFileSize, KBlockSize);
sl@0
   858
	
sl@0
   859
	fs.Close();
sl@0
   860
	test.Close();
sl@0
   861
	
sl@0
   862
	return ETrue;
sl@0
   863
	}
sl@0
   864
	
sl@0
   865
/**  Delete a big file, in a different thread
sl@0
   866
sl@0
   867
	@return ETrue
sl@0
   868
*/
sl@0
   869
TInt DeleteBigFile(TAny* )
sl@0
   870
	{
sl@0
   871
	RTest test(_L("T_FSCHED"));
sl@0
   872
	RFs fs;
sl@0
   873
	TInt r = fs.Connect();
sl@0
   874
	TESTERROR(r);
sl@0
   875
sl@0
   876
	r = fs.SetSessionPath(gSessionPath);
sl@0
   877
	TESTERROR(r);
sl@0
   878
	
sl@0
   879
	gSync.Wait(); 
sl@0
   880
	
sl@0
   881
	r = fs.Delete(gBigFile);
sl@0
   882
#if defined(__WINS__)
sl@0
   883
	TEST(r == KErrInUse || r == KErrNone);
sl@0
   884
#else
sl@0
   885
	test_Equal(KErrInUse, r);
sl@0
   886
#endif
sl@0
   887
		
sl@0
   888
	client.Signal();
sl@0
   889
	
sl@0
   890
	fs.Close();
sl@0
   891
	test.Close();
sl@0
   892
	
sl@0
   893
	return ETrue;
sl@0
   894
	}
sl@0
   895
sl@0
   896
/**  Reads a small file while writing a big one
sl@0
   897
sl@0
   898
*/
sl@0
   899
void TestReadingWhileWriting() 
sl@0
   900
{
sl@0
   901
	TInt r = 0;
sl@0
   902
	TTime time1;
sl@0
   903
	TTime time2;
sl@0
   904
sl@0
   905
	time1.HomeTime();
sl@0
   906
	
sl@0
   907
	// Write the small file and take the appropriate measures
sl@0
   908
	WriteFile(TheFs,gSmallFile,KBlockSize, KBlockSize, ENoThreads);
sl@0
   909
sl@0
   910
	// Sync test
sl@0
   911
	TBuf<20> buf=_L("Big Write");
sl@0
   912
	r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
   913
	TEST(r == KErrNone);
sl@0
   914
sl@0
   915
	buf = _L("Small Read");
sl@0
   916
	r = gSmall.Create(buf, ReadSmallFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
   917
	TEST(r == KErrNone);
sl@0
   918
	
sl@0
   919
	gBig.Resume();
sl@0
   920
	gSmall.Resume();
sl@0
   921
sl@0
   922
	CLIENTWAIT();
sl@0
   923
	CLIENTWAIT();
sl@0
   924
	
sl@0
   925
	gBig.Close();
sl@0
   926
	gSmall.Close();
sl@0
   927
	
sl@0
   928
	
sl@0
   929
	TTimeIntervalMicroSeconds timeTaken = gTime1.MicroSecondsFrom(gTime2);
sl@0
   930
	test.Printf(_L("\nSync read done %d ms before the write ended\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
   931
	TReal time=I64LOW(timeTaken.Int64() / KuStomS); 
sl@0
   932
	#if !defined(__WINS__)
sl@0
   933
	// If this condition fails, means that writing the sync file while fairscheduling a small sync read takes too long
sl@0
   934
		test.Printf(_L("time: %f\n"), time);
sl@0
   935
//		test((time > 0) && (((gTotalTimeSync[0]-time)>0) || ((gTotalTimeSync[1]-time)>0)) );  
sl@0
   936
		test(time > 0);
sl@0
   937
	#endif 
sl@0
   938
	
sl@0
   939
	// Async test 
sl@0
   940
	TRequestStatus status[KWaitRequestsTableSize];
sl@0
   941
	TRequestStatus status2[2];
sl@0
   942
	RFile bigFile, smallFile;	
sl@0
   943
sl@0
   944
	WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize,  KBigBlockSize ,status); 
sl@0
   945
	ReadFileAsync(TheFs, smallFile, gSmallFile, KBlockSize, status2 );
sl@0
   946
sl@0
   947
	WaitForAll(status2,KBlockSize , KBlockSize );
sl@0
   948
	time1.HomeTime(); 
sl@0
   949
sl@0
   950
	WaitForAll(status,gBigFileSize, KBigBlockSize);
sl@0
   951
sl@0
   952
	time2.HomeTime();
sl@0
   953
	bigFile.Close();
sl@0
   954
	smallFile.Close();
sl@0
   955
	
sl@0
   956
	timeTaken = time2.MicroSecondsFrom(time1);
sl@0
   957
	
sl@0
   958
	test.Printf(_L("\nAsync read done %d ms before the write ended\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
   959
	time = I64LOW(timeTaken.Int64() / KuStomS); 
sl@0
   960
sl@0
   961
	#if !defined(__WINS__)
sl@0
   962
	// If this condition fails, means that writing the async file while fairscheduling a small async read takes too long
sl@0
   963
		test.Printf(_L("time: %f\n"), time);
sl@0
   964
		test.Printf(_L("gTotalTimeAsync[0] = %d , gTotalTimeAsync[1] = %d\n"),gTotalTimeAsync[0],gTotalTimeAsync[1] );
sl@0
   965
//		test((time > 0) && (((gTotalTimeAsync[0]-time)>0) || ((gTotalTimeAsync[1]-time)>0)) );
sl@0
   966
		test(time > 0);
sl@0
   967
	#endif
sl@0
   968
}
sl@0
   969
sl@0
   970
/** Writes a small file while writing a big one
sl@0
   971
sl@0
   972
*/
sl@0
   973
void TestWritingWhileWriting() 
sl@0
   974
{
sl@0
   975
	TInt r = 0;
sl@0
   976
	TTime time1;
sl@0
   977
	TTime time2;
sl@0
   978
sl@0
   979
	// Sync test
sl@0
   980
	TBuf<20> buf = _L("Big Write II");
sl@0
   981
	r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
   982
	TEST(r == KErrNone);
sl@0
   983
sl@0
   984
	buf = _L("Small Write II");
sl@0
   985
	r = gSmall.Create(buf, WriteSmallFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
   986
	TEST(r==KErrNone);
sl@0
   987
	
sl@0
   988
	gBig.Resume();
sl@0
   989
	gSmall.Resume();
sl@0
   990
sl@0
   991
	CLIENTWAIT();
sl@0
   992
	CLIENTWAIT();
sl@0
   993
	
sl@0
   994
	gBig.Close();
sl@0
   995
	gSmall.Close();
sl@0
   996
	
sl@0
   997
	TTimeIntervalMicroSeconds timeTaken = gTime1.MicroSecondsFrom(gTime2);
sl@0
   998
	test.Printf(_L("\nSync write done %d ms before the big write ended\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
   999
	TReal time=I64LOW(timeTaken.Int64() / KuStomS); 
sl@0
  1000
	#if !defined(__WINS__)
sl@0
  1001
	// If this condition fails, means that writing the sync file while fairscheduling a small sync write takes too long
sl@0
  1002
		test.Printf(_L("time: %f\n"), time);
sl@0
  1003
// 		test((time > 0) && (((gTotalTimeSync[0]-time)>0) || ((gTotalTimeSync[1]-time)>0)) ); 
sl@0
  1004
		test(time > 0);
sl@0
  1005
	#endif 
sl@0
  1006
sl@0
  1007
	// Async test 
sl@0
  1008
	TRequestStatus status[KWaitRequestsTableSize];
sl@0
  1009
	TRequestStatus status2[1];
sl@0
  1010
	RFile bigFile, smallFile;
sl@0
  1011
sl@0
  1012
	WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize, KBigBlockSize, status); 
sl@0
  1013
	WriteFileAsync(TheFs,smallFile, gSmallFile,gSmallFileSize,KBlockSize,status2);
sl@0
  1014
	WaitForAll(status2,gSmallFileSize, KBlockSize);
sl@0
  1015
	time1.HomeTime();
sl@0
  1016
	WaitForAll(status, gBigFileSize, KBigBlockSize);
sl@0
  1017
	time2.HomeTime();
sl@0
  1018
	
sl@0
  1019
	timeTaken = time2.MicroSecondsFrom(time1);
sl@0
  1020
	test.Printf(_L("\nAsync write done %d ms before the big write ended\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
  1021
	time=I64LOW(timeTaken.Int64() / KuStomS); 
sl@0
  1022
	#if !defined(__WINS__)
sl@0
  1023
	// If this condition fails, means that writing the async file while fairscheduling a small async write takes too long
sl@0
  1024
		test.Printf(_L("time: %f\n"), time);
sl@0
  1025
		test.Printf(_L("gTotalTimeAsync[0] = %d , gTotalTimeAsync[1] = %d\n"),gTotalTimeAsync[0],gTotalTimeAsync[1] );
sl@0
  1026
//		test((time > 0) && (((gTotalTimeAsync[0]-time)>0) || ((gTotalTimeAsync[1]-time)>0)) ); 
sl@0
  1027
		test(time > 0);
sl@0
  1028
	#endif
sl@0
  1029
	bigFile.Close();
sl@0
  1030
	smallFile.Close();	
sl@0
  1031
}
sl@0
  1032
sl@0
  1033
/** Writes two big files, ensuring the one that started to be written later ends the last one
sl@0
  1034
sl@0
  1035
*/
sl@0
  1036
void TestTwoBigOnes()
sl@0
  1037
{
sl@0
  1038
	TInt r = 0;
sl@0
  1039
	TTime time1;
sl@0
  1040
	TTime time2;
sl@0
  1041
sl@0
  1042
	// Sync test
sl@0
  1043
	TBuf<20> buf = _L("Big Write IIII");
sl@0
  1044
	r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1045
	TEST(r == KErrNone);
sl@0
  1046
sl@0
  1047
	buf = _L("Big Write The Second");
sl@0
  1048
	r = gSmall.Create(buf, WriteBigFile2, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1049
	TEST(r == KErrNone);
sl@0
  1050
sl@0
  1051
	gBig.Resume();
sl@0
  1052
	gSmall.Resume();
sl@0
  1053
sl@0
  1054
	CLIENTWAIT();
sl@0
  1055
	CLIENTWAIT();
sl@0
  1056
	
sl@0
  1057
	gBig.Close();
sl@0
  1058
	gSmall.Close();
sl@0
  1059
	
sl@0
  1060
	TTimeIntervalMicroSeconds timeTaken = gTime2.MicroSecondsFrom(gTime1);
sl@0
  1061
	test.Printf(_L("\nSync first write ended %d ms before the second write ended (same file size)\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
  1062
sl@0
  1063
	// Async test 
sl@0
  1064
	TRequestStatus status[KWaitRequestsTableSize];
sl@0
  1065
	TRequestStatus status2[KWaitRequestsTableSize];
sl@0
  1066
	RFile bigFile, bigFile2;
sl@0
  1067
sl@0
  1068
	WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize, KBigBlockSize, status); 
sl@0
  1069
	WriteFileAsync(TheFs, bigFile2, gSmallFile, gBigFileSize, KBigBlockSize, status2);
sl@0
  1070
	WaitForAll(status, gBigFileSize, KBigBlockSize);
sl@0
  1071
	time1.HomeTime();
sl@0
  1072
	WaitForAll(status2, gBigFileSize, KBigBlockSize);
sl@0
  1073
	time2.HomeTime();
sl@0
  1074
	
sl@0
  1075
	timeTaken = time2.MicroSecondsFrom(time1);
sl@0
  1076
	test.Printf(_L("\nAsync first write ended %d ms before the second write ended (same file size)\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
  1077
	bigFile.Close();
sl@0
  1078
	bigFile2.Close();	
sl@0
  1079
}
sl@0
  1080
sl@0
  1081
/**  Reads the file that is being written
sl@0
  1082
sl@0
  1083
*/
sl@0
  1084
void TestReadingWhileWritingSameFile() 
sl@0
  1085
{
sl@0
  1086
	TInt r = 0;
sl@0
  1087
	TTime time1;
sl@0
  1088
	
sl@0
  1089
	time1.HomeTime();
sl@0
  1090
	
sl@0
  1091
	// Sync test
sl@0
  1092
	TBuf<20> buf = _L("Big Write IV");
sl@0
  1093
	r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1094
	TEST(r == KErrNone);
sl@0
  1095
sl@0
  1096
	buf = _L("Read IV");
sl@0
  1097
	r = gSmall.Create(buf, ReadBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1098
	TEST(r == KErrNone);
sl@0
  1099
	
sl@0
  1100
	gBig.Resume();
sl@0
  1101
	gSmall.Resume();
sl@0
  1102
	
sl@0
  1103
	CLIENTWAIT();
sl@0
  1104
	CLIENTWAIT();
sl@0
  1105
	
sl@0
  1106
	CLOSE_AND_WAIT(gBig);
sl@0
  1107
	CLOSE_AND_WAIT(gSmall);
sl@0
  1108
	
sl@0
  1109
	TTimeIntervalMicroSeconds timeTaken = gTime2.MicroSecondsFrom(gTime1);
sl@0
  1110
	test.Printf(_L("\nSync write finished %d ms before the read ended\n"),I64LOW(timeTaken.Int64() / KuStomS));
sl@0
  1111
	
sl@0
  1112
}
sl@0
  1113
sl@0
  1114
/** Client dying uncleanly before the operation is finished
sl@0
  1115
sl@0
  1116
*/
sl@0
  1117
void TestClientDies()
sl@0
  1118
{
sl@0
  1119
	TInt r = 0;
sl@0
  1120
sl@0
  1121
sl@0
  1122
	TBuf<20> drive = _L("?:\\");
sl@0
  1123
	TVolumeInfo volInfo;
sl@0
  1124
	drive[0]=(TText)(gDrive+'A');
sl@0
  1125
	
sl@0
  1126
	r = TheFs.CheckDisk(drive);
sl@0
  1127
	TEST(r == KErrNone || r == KErrNotSupported);
sl@0
  1128
sl@0
  1129
	// Sync test
sl@0
  1130
	TBuf<20> buf = _L("Big Write V");
sl@0
  1131
	r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1132
	TEST(r == KErrNone);
sl@0
  1133
	
sl@0
  1134
	TRequestStatus status;
sl@0
  1135
	gBig.Logon(status);
sl@0
  1136
	gBig.Resume();
sl@0
  1137
	gSync.Wait();
sl@0
  1138
sl@0
  1139
	// Kill the writing thread and wait for it to die.
sl@0
  1140
	
sl@0
  1141
    if(status.Int() == KRequestPending)
sl@0
  1142
		{// the people who wrote this test did not consider the case when the file write finishes before they try to kill the thread.
sl@0
  1143
		gBig.Kill(KErrGeneral);
sl@0
  1144
		User::WaitForRequest(status);
sl@0
  1145
		TEST(gBig.ExitReason() == KErrGeneral);
sl@0
  1146
		TEST(gBig.ExitType() == EExitKill);
sl@0
  1147
		}
sl@0
  1148
sl@0
  1149
    
sl@0
  1150
    // Make sure the thread is destroyed and the handles it owned and IPCs
sl@0
  1151
    // it executed are closed/cancelled.
sl@0
  1152
    CLOSE_AND_WAIT(gBig);
sl@0
  1153
sl@0
  1154
sl@0
  1155
	r = TheFs.Volume(volInfo, gDrive);
sl@0
  1156
	TESTERROR(r);
sl@0
  1157
sl@0
  1158
	r = TheFs.CheckDisk(drive);
sl@0
  1159
	TEST(r == KErrNone || r == KErrNotSupported);
sl@0
  1160
sl@0
  1161
	r = TheFs.ScanDrive(drive);
sl@0
  1162
	TEST(r == KErrNone || r == KErrNotSupported);
sl@0
  1163
sl@0
  1164
	test.Printf(_L("Sync operation stopped\n"));
sl@0
  1165
	
sl@0
  1166
	// Async test 
sl@0
  1167
	buf = _L("Big Write VI");
sl@0
  1168
	r = gSmall.Create(buf, WriteBigFileAsync, KDefaultStackSize * 2, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1169
	TEST(r == KErrNone);
sl@0
  1170
	
sl@0
  1171
	gSmall.Logon(status);
sl@0
  1172
	gSmall.Resume();
sl@0
  1173
	gSync.Wait();
sl@0
  1174
	
sl@0
  1175
    
sl@0
  1176
    if(status.Int() == KRequestPending)
sl@0
  1177
		{
sl@0
  1178
		// Kill the writing thread and wait for it to die.
sl@0
  1179
		gSmall.Kill(KErrGeneral);
sl@0
  1180
		User::WaitForRequest(status);
sl@0
  1181
		TEST(gSmall.ExitReason() == KErrGeneral);
sl@0
  1182
		TEST(gSmall.ExitType() == EExitKill);
sl@0
  1183
		}
sl@0
  1184
sl@0
  1185
sl@0
  1186
    // Make sure the thread is destroyed and the handles it owned and IPCs
sl@0
  1187
    // it executed are closed/cancelled.
sl@0
  1188
    CLOSE_AND_WAIT(gSmall);
sl@0
  1189
sl@0
  1190
	r = TheFs.CheckDisk(drive);
sl@0
  1191
	TEST(r == KErrNone || r == KErrNotSupported);
sl@0
  1192
	
sl@0
  1193
	r=TheFs.ScanDrive(drive);
sl@0
  1194
	TEST(r == KErrNone || r == KErrNotSupported);
sl@0
  1195
	
sl@0
  1196
	test.Printf(_L("Async operation stopped\n"));
sl@0
  1197
}
sl@0
  1198
sl@0
  1199
/** Reads a small file while writing a big one
sl@0
  1200
sl@0
  1201
*/
sl@0
  1202
void TestDeletionWhileWriting()
sl@0
  1203
{
sl@0
  1204
	TInt r = 0;
sl@0
  1205
	
sl@0
  1206
	// Sync test
sl@0
  1207
	TBuf<20> buf = _L("Big Write V");
sl@0
  1208
	r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1209
	TEST(r == KErrNone);
sl@0
  1210
sl@0
  1211
	buf = _L("Deletion");
sl@0
  1212
	r = gSmall.Create(buf, DeleteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL);
sl@0
  1213
	TEST(r == KErrNone);
sl@0
  1214
sl@0
  1215
	gSmall.Resume();
sl@0
  1216
	gBig.Resume();
sl@0
  1217
sl@0
  1218
	CLIENTWAIT();
sl@0
  1219
	CLIENTWAIT();
sl@0
  1220
	
sl@0
  1221
	gBig.Close();
sl@0
  1222
	gSmall.Close();
sl@0
  1223
	
sl@0
  1224
	test.Printf(_L("The file was properly blocked when writing sync, not deleted\n"));
sl@0
  1225
	
sl@0
  1226
	// Async test 
sl@0
  1227
	TRequestStatus status[KWaitRequestsTableSize];
sl@0
  1228
	RFile bigFile;
sl@0
  1229
	RFs fs; 
sl@0
  1230
sl@0
  1231
	r = fs.Connect();
sl@0
  1232
	TESTERROR(r);
sl@0
  1233
	r = fs.SetSessionPath(gSessionPath);
sl@0
  1234
	TESTERROR(r);
sl@0
  1235
sl@0
  1236
	WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize, KBigBlockSize, status); 	
sl@0
  1237
sl@0
  1238
	r = fs.Delete(gBigFile);
sl@0
  1239
	TEST(r == KErrInUse);
sl@0
  1240
	
sl@0
  1241
	WaitForAll(status, gBigFileSize, KBigBlockSize);
sl@0
  1242
	
sl@0
  1243
	bigFile.Close();
sl@0
  1244
	fs.Close();
sl@0
  1245
	
sl@0
  1246
	test.Printf(_L("The file was properly blocked when writing async, not deleted\n"));
sl@0
  1247
sl@0
  1248
}
sl@0
  1249
sl@0
  1250
sl@0
  1251
void TestWriteOrder()
sl@0
  1252
	{
sl@0
  1253
	RFs fs; 
sl@0
  1254
sl@0
  1255
	TInt r = fs.Connect();
sl@0
  1256
	TESTERROR(r);
sl@0
  1257
	r = fs.SetSessionPath(gSessionPath);
sl@0
  1258
	TESTERROR(r);
sl@0
  1259
sl@0
  1260
	WriteOrderTest(TheFs, gBigFileSize, KBlockSize);
sl@0
  1261
sl@0
  1262
	fs.Close();
sl@0
  1263
	}
sl@0
  1264
sl@0
  1265
sl@0
  1266
/** Main tests function
sl@0
  1267
*/ 
sl@0
  1268
void CallTestsL()
sl@0
  1269
	{
sl@0
  1270
	TBuf16<45> dir;
sl@0
  1271
	TInt r = 0;
sl@0
  1272
	
sl@0
  1273
	
sl@0
  1274
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1275
	test.Printf(_L("Disabling Lock Fail simulation ...\n"));
sl@0
  1276
	// turn OFF lock failure mode (if cache is enabled)
sl@0
  1277
	
sl@0
  1278
	TBool simulatelockFailureMode = EFalse;
sl@0
  1279
	r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
sl@0
  1280
	test (r == KErrNone  ||  r == KErrNotSupported);
sl@0
  1281
#endif
sl@0
  1282
sl@0
  1283
	// FileNames/File generation
sl@0
  1284
	test.Start(_L("Preparing the environment\n"));
sl@0
  1285
	
sl@0
  1286
	FileNameGen(gSmallFile, 8, gNextFile++);
sl@0
  1287
	FileNameGen(gBigFile, 8, gNextFile++);
sl@0
  1288
	
sl@0
  1289
	dir = gSessionPath;
sl@0
  1290
	dir.Append(gSmallFile);
sl@0
  1291
	
sl@0
  1292
	gSmallFile = dir;
sl@0
  1293
	dir = gSessionPath;
sl@0
  1294
	dir.Append(gBigFile);
sl@0
  1295
	gBigFile = dir;
sl@0
  1296
sl@0
  1297
	TRAPD(res,gBuf = HBufC8::NewL(KBigBlockSize));
sl@0
  1298
	TEST(res == KErrNone && gBuf != NULL);
sl@0
  1299
		
sl@0
  1300
	gBufWritePtr.Set(gBuf->Des());
sl@0
  1301
	FillBuffer(gBufWritePtr, KBigBlockSize, 'B');
sl@0
  1302
	
sl@0
  1303
	TRAPD(res2, gBufSec = HBufC8::NewL(KBlockSize));
sl@0
  1304
	TEST(res2 == KErrNone && gBufSec != NULL);
sl@0
  1305
	gBufReadPtr.Set(gBufSec->Des());
sl@0
  1306
	
sl@0
  1307
	test.Next(_L("Benchmarking\n"));
sl@0
  1308
	TimeTakenToWriteBigFile(0);  
sl@0
  1309
	TimeTakenToWriteBigFileAsync(0);
sl@0
  1310
	
sl@0
  1311
	test.Printf(_L("second try, second timings account for the last comparison\n")); 
sl@0
  1312
	TimeTakenToWriteBigFile(0);  
sl@0
  1313
	TimeTakenToWriteBigFileAsync(0);
sl@0
  1314
	
sl@0
  1315
	TimeTakenToWriteBigBlock();
sl@0
  1316
	
sl@0
  1317
	test.Next(_L("Big file sync written, small file read from the media at the same time\n"));
sl@0
  1318
	TestReadingWhileWriting();
sl@0
  1319
	
sl@0
  1320
	test.Next(_L("Big file written, small file written at the same time\n"));
sl@0
  1321
	TestWritingWhileWriting();
sl@0
  1322
	
sl@0
  1323
  	test.Next(_L("Big file written async, deletion in the meantime\n"));
sl@0
  1324
	TestDeletionWhileWriting();
sl@0
  1325
	
sl@0
  1326
	test.Next(_L("Two big files written at the same time\n"));
sl@0
  1327
	TestTwoBigOnes();	
sl@0
  1328
	
sl@0
  1329
	test.Next(_L("Big file being written, start reading\n"));
sl@0
  1330
	TestReadingWhileWritingSameFile();
sl@0
  1331
sl@0
  1332
	test.Next(_L("Client dying unexpectedly\n"));
sl@0
  1333
	TestClientDies();
sl@0
  1334
sl@0
  1335
  	test.Next(_L("Ensure write order is preserved\n"));
sl@0
  1336
	TestWriteOrder();
sl@0
  1337
	
sl@0
  1338
	// Format the drive to make sure no blocks are left to be erased in LFFS
sl@0
  1339
	#if !defined(__WINS__)
sl@0
  1340
		Format(gDrive);	
sl@0
  1341
	#endif
sl@0
  1342
	r = TheFs.MkDirAll(gSessionPath);
sl@0
  1343
	
sl@0
  1344
	TimeTakenToWriteBigFile(1);  
sl@0
  1345
	TimeTakenToWriteBigFileAsync(1);
sl@0
  1346
sl@0
  1347
	// Make sure that the difference between the first time and the last time the files are written doesn't
sl@0
  1348
	// differ more than 3%
sl@0
  1349
	test.Printf(_L("Abs(gTotalTimeSync[0]-gTotalTimeSync[1]) :%d\n"), Abs(gTotalTimeSync[0]-gTotalTimeSync[1]));
sl@0
  1350
	test.Printf(_L("Abs(gTotalTimeAsync[0]-gTotalTimeAsync[1]) :%d\n"), Abs(gTotalTimeAsync[0]-gTotalTimeAsync[1]));
sl@0
  1351
	test.Printf(_L("gTotalTimeSync[0] :%d\n"), gTotalTimeSync[0]);
sl@0
  1352
	test.Printf(_L("gTotalTimeAsync[0] :%d\n"), gTotalTimeAsync[0]);
sl@0
  1353
	
sl@0
  1354
	#if !defined(__WINS__)
sl@0
  1355
		test((Abs(gTotalTimeSync[0]-gTotalTimeSync[1])/gTotalTimeSync[0]) < 0.03);
sl@0
  1356
		test((Abs(gTotalTimeAsync[0]-gTotalTimeAsync[1])/gTotalTimeAsync[0]) < 0.03);	
sl@0
  1357
	#endif
sl@0
  1358
	
sl@0
  1359
	r = DeleteAll(gSessionPath);
sl@0
  1360
	TESTERROR(r);
sl@0
  1361
	
sl@0
  1362
	delete gBuf;
sl@0
  1363
	delete gBufSec;
sl@0
  1364
	
sl@0
  1365
#if defined(_DEBUG) || defined(_DEBUG_RELEASE)
sl@0
  1366
	// turn lock failure mode back ON (if cache is enabled)
sl@0
  1367
	simulatelockFailureMode = ETrue;
sl@0
  1368
	r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
sl@0
  1369
    test (r == KErrNone  ||  r == KErrNotSupported);
sl@0
  1370
#endif
sl@0
  1371
sl@0
  1372
	test.End();
sl@0
  1373
	}
sl@0
  1374
sl@0
  1375
/** Initialises semaphores and call the tests
sl@0
  1376
*/ 
sl@0
  1377
void DoTests()
sl@0
  1378
	{
sl@0
  1379
 	TInt r = 0;
sl@0
  1380
 	
sl@0
  1381
 	r = client.CreateLocal(0);
sl@0
  1382
 	TESTERROR(r);
sl@0
  1383
 
sl@0
  1384
  	r = gSync.CreateLocal(0);
sl@0
  1385
 	TESTERROR(r);
sl@0
  1386
 
sl@0
  1387
	r = TheFs.SetSessionPath(gSessionPath);
sl@0
  1388
	TESTERROR(r);
sl@0
  1389
	
sl@0
  1390
	r = TheFs.MkDirAll(gSessionPath);
sl@0
  1391
	if (r != KErrNone && r != KErrAlreadyExists)
sl@0
  1392
		{
sl@0
  1393
		TESTERROR(r);
sl@0
  1394
		}
sl@0
  1395
	TheFs.ResourceCountMarkStart();
sl@0
  1396
	TRAP(r,CallTestsL());
sl@0
  1397
	if (r == KErrNone)
sl@0
  1398
		TheFs.ResourceCountMarkEnd();
sl@0
  1399
	else
sl@0
  1400
		{
sl@0
  1401
		TESTERROR(r);
sl@0
  1402
		}
sl@0
  1403
	}
sl@0
  1404
sl@0
  1405
/** Determines the space that can be used for the files
sl@0
  1406
sl@0
  1407
*/
sl@0
  1408
TBool CheckForDiskSize()
sl@0
  1409
{
sl@0
  1410
	TVolumeInfo volInfo;
sl@0
  1411
	TInt r = TheFs.Volume(volInfo, gDrive);
sl@0
  1412
	TESTERROR(r);
sl@0
  1413
	
sl@0
  1414
	gMediaSize = volInfo.iSize;
sl@0
  1415
	gSmallFileSize = KBlockSize;
sl@0
  1416
	gBigFileSize = KBlockSize*20;
sl@0
  1417
	
sl@0
  1418
	while(((2*gBigFileSize)+KOneMeg) > gMediaSize ) 
sl@0
  1419
		{
sl@0
  1420
		gBigFileSize -= (2*KBlockSize);
sl@0
  1421
		}
sl@0
  1422
sl@0
  1423
	TReal32 small = (TReal32)(gSmallFileSize/KOneK);
sl@0
  1424
	TReal32 big = (TReal32)(gBigFileSize/KOneK);
sl@0
  1425
	
sl@0
  1426
	
sl@0
  1427
	test.Printf(_L("Small File Size: %.2f KB\n"), small); 
sl@0
  1428
	test.Printf(_L("Big File Size: %.2f KB (%.2f MB)\n"), big, big / KOneK); 
sl@0
  1429
	
sl@0
  1430
	if(gBigFileSize< (3*gSmallFileSize)) 
sl@0
  1431
		return EFalse;
sl@0
  1432
	else 
sl@0
  1433
		return ETrue;
sl@0
  1434
}
sl@0
  1435
sl@0
  1436
/** Formats the drive 
sl@0
  1437
sl@0
  1438
	@param aDrive 	Drive to be formatted
sl@0
  1439
*/
sl@0
  1440
void Format(TInt aDrive)
sl@0
  1441
	{
sl@0
  1442
sl@0
  1443
	test.Next(_L("Format"));
sl@0
  1444
	TBuf<4> driveBuf = _L("?:\\");
sl@0
  1445
	driveBuf[0] = (TText)(aDrive+'A');
sl@0
  1446
	RFormat format;
sl@0
  1447
	TInt count, prevcount = 0;
sl@0
  1448
	TInt r = format.Open(TheFs, driveBuf, EQuickFormat, count);
sl@0
  1449
	TESTERROR(r);
sl@0
  1450
	
sl@0
  1451
	while(count)
sl@0
  1452
		{
sl@0
  1453
		TInt r = format.Next(count);
sl@0
  1454
        if(count != prevcount)
sl@0
  1455
	        {
sl@0
  1456
			test.Printf(_L("."));
sl@0
  1457
			prevcount = count;
sl@0
  1458
			}
sl@0
  1459
		TESTERROR(r);
sl@0
  1460
		}
sl@0
  1461
sl@0
  1462
	format.Close();
sl@0
  1463
	}
sl@0
  1464
sl@0
  1465
/** Main function
sl@0
  1466
sl@0
  1467
	@return KErrNone if everything was ok, panics otherwise
sl@0
  1468
*/
sl@0
  1469
TInt E32Main()
sl@0
  1470
    {
sl@0
  1471
	RThread t;
sl@0
  1472
	gMainThreadId = t.Id();
sl@0
  1473
	
sl@0
  1474
	CTrapCleanup* cleanup;
sl@0
  1475
	cleanup = CTrapCleanup::New();
sl@0
  1476
sl@0
  1477
	__UHEAP_MARK;
sl@0
  1478
	test.Start(_L("Starting tests... T_FSCHED"));
sl@0
  1479
	parseCommandLine();
sl@0
  1480
	
sl@0
  1481
	TInt r = TheFs.Connect();
sl@0
  1482
	TESTERROR(r);
sl@0
  1483
	
sl@0
  1484
	TDriveInfo info;
sl@0
  1485
	TVolumeInfo volInfo;
sl@0
  1486
	r = TheFs.Drive(info, gDrive);
sl@0
  1487
	TESTERROR(r);
sl@0
  1488
	
sl@0
  1489
	if(info.iMediaAtt&KMediaAttVariableSize)
sl@0
  1490
		{
sl@0
  1491
		test.Printf(_L("Tests skipped in RAM drive\n"));
sl@0
  1492
		goto out;
sl@0
  1493
		}
sl@0
  1494
sl@0
  1495
	r = TheFs.Volume(volInfo, gDrive);
sl@0
  1496
	if (r == KErrNotReady)
sl@0
  1497
		{
sl@0
  1498
		if (info.iType == EMediaNotPresent)
sl@0
  1499
			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDrive + 'A');
sl@0
  1500
		else
sl@0
  1501
			test.Printf(_L("medium found (type %d) but drive %c: not ready\nPrevious test may have hung; else, check hardware.\n"), (TInt)info.iType, (TUint)gDrive + 'A');
sl@0
  1502
		}
sl@0
  1503
	else if (r == KErrCorrupt)
sl@0
  1504
		{
sl@0
  1505
		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDrive + 'A');
sl@0
  1506
		}
sl@0
  1507
	TESTERROR(r);
sl@0
  1508
#if !defined(__WINS__)
sl@0
  1509
	if ((volInfo.iDrive.iMediaAtt & KMediaAttFormattable))
sl@0
  1510
		Format(gDrive);
sl@0
  1511
#endif
sl@0
  1512
sl@0
  1513
	if(CheckForDiskSize())
sl@0
  1514
		{
sl@0
  1515
		DoTests();
sl@0
  1516
		}
sl@0
  1517
	else 
sl@0
  1518
		{
sl@0
  1519
		test.Printf(_L("Skipping tests due to lack of space to perform them in this drive\n"));
sl@0
  1520
		}
sl@0
  1521
out:
sl@0
  1522
	test.End();
sl@0
  1523
sl@0
  1524
	TheFs.Close();
sl@0
  1525
	test.Close();
sl@0
  1526
sl@0
  1527
	__UHEAP_MARKEND;
sl@0
  1528
	delete cleanup;
sl@0
  1529
	return(KErrNone);
sl@0
  1530
    }