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