kerneltest/f32test/server/t_fsched.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
child 175 5af6c74cd793
child 256 c1f20ce4abcf
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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     }