kerneltest/f32test/server/t_rcache.cpp
changeset 0 a41df078684a
child 42 a179b74831c9
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_rcache.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20  @internalTechnology 
       
    21 */
       
    22 #define __E32TEST_EXTENSION__
       
    23 #include <f32file.h>
       
    24 #include <e32test.h>
       
    25 #include <e32svr.h>
       
    26 #include <e32const.h>
       
    27 #include <e32const_private.h>
       
    28 #include <f32dbg.h>
       
    29 #include "t_server.h"
       
    30 #include <e32twin.h>
       
    31 #include <e32rom.h>
       
    32 #include <hal.h>
       
    33 #include <u32hal.h>
       
    34 
       
    35 const TInt KTotalCacheSize = 32 * 1024 * 1024;
       
    36 const TInt KDefaultCacheSize = (128 + 12) * 1024;
       
    37 const TInt KFilesNeededToFillCache = (KTotalCacheSize / KDefaultCacheSize) + 2;
       
    38 
       
    39 
       
    40 //----------------------------------------------------------------------------------------------
       
    41 //! @SYMTestCaseID      PBASE-T_RCACHE-0190
       
    42 //! @SYMTestType        CIT
       
    43 //! @SYMPREQ            PREQ914
       
    44 //! @SYMTestCaseDesc    This test case is exercising the Read Caching functionality added to
       
    45 //!						the File Server. There are negative and positive tests.
       
    46 //! @SYMTestActions     0   setup the environment to execute the tests
       
    47 //!						1	TestNegative creates situations where the cached content needs to be
       
    48 //!							flushed or removed  from the cache by corrupting files and verifies
       
    49 //!							the cache behaviour
       
    50 //!						2 	TestSimpleRead ensures that the cache is working in the simple cases,
       
    51 //!							with a combination of sync and async reads:
       
    52 //!								a. The file fits in the cache
       
    53 //!								b. The file doesn't fit in the cache
       
    54 //!						3 	TestRepeatedRead verifies the cache behaviour when a file is read an
       
    55 //!							arbitrary number of times, with and without other operations ongoing
       
    56 //!						4	TestReadAhead reads 3 times from a file and verifies that the read
       
    57 //!							ahead functionality acts afterwards.
       
    58 //!						5	TestConcurrent reads files concurrently and verifies how the cache
       
    59 //!							copes with it.
       
    60 //!						6 	TestFillCache fills the cache and then executes TestSimpleRead.
       
    61 //!
       
    62 //! @SYMTestExpectedResults finishes if the read cache behaves as expected, panics otherwise
       
    63 //! @SYMTestPriority        High
       
    64 //! @SYMTestStatus          Implemented
       
    65 //----------------------------------------------------------------------------------------------
       
    66 
       
    67 
       
    68 ////////////////////////////////////////////////////////////
       
    69 // Template functions encapsulating ControlIo magic
       
    70 //
       
    71 GLDEF_D template <class C>
       
    72 GLDEF_C TInt controlIo(RFs &fs, TInt drv, TInt fkn, C &c)
       
    73 {
       
    74     TPtr8 ptrC((TUint8 *)&c, sizeof(C), sizeof(C));
       
    75 
       
    76     TInt r = fs.ControlIo(drv, fkn, ptrC);
       
    77 
       
    78     return r;
       
    79 }
       
    80 
       
    81 GLDEF_D RTest test(_L("T_RCACHE"));
       
    82 
       
    83 GLDEF_D	RFs TheFs;
       
    84 GLDEF_D TInt gDrive;
       
    85 GLDEF_D TFileName gSessionPath;
       
    86 GLDEF_D TChar gDriveToTest;
       
    87 TThreadId gMainThreadId;
       
    88 
       
    89 LOCAL_D HBufC8* gBuf = NULL;
       
    90 LOCAL_D TPtr8 gBufReadPtr(NULL, 0);
       
    91 LOCAL_D HBufC8* gBufSec = NULL;
       
    92 LOCAL_D TPtr8 gBufWritePtr(NULL, 0);
       
    93 
       
    94 LOCAL_D const TInt KOneK = 1024;
       
    95 LOCAL_D const TInt KOneMeg = KOneK * 1024;
       
    96 LOCAL_D const TInt KBlockSize = KOneK;
       
    97 LOCAL_D const TInt KWaitRequestsTableSize = 256;
       
    98 
       
    99 LOCAL_D TInt gSecondFileSize = 0;
       
   100 LOCAL_D TInt gFirstFileSize = 0;
       
   101 LOCAL_D TInt gCurrentFileSize = 0;
       
   102 
       
   103 LOCAL_D TInt64 gMediaSize = 0;
       
   104 
       
   105 LOCAL_D TTimeIntervalMicroSeconds gTimeTakenBigFile(0);
       
   106 LOCAL_D TBuf16<25> gFirstFile;
       
   107 LOCAL_D TBuf16<25> gSecondFile;
       
   108 LOCAL_D TBuf16<25> gCurrentFile;
       
   109 
       
   110 LOCAL_D TInt gNextFile = 0;
       
   111 LOCAL_D TTime gTime1;
       
   112 LOCAL_D TTime gTime2;
       
   113 _LIT(KMsg1, "1st read timing: %d\n");
       
   114 _LIT(KMsg2, "2nd read timing: %d\n");
       
   115 _LIT(KMsg3, "3rd read timing: %d\n");
       
   116 
       
   117 LOCAL_D RSemaphore gSync;
       
   118 
       
   119 // Concurrent Threads
       
   120 LOCAL_D RThread gThread1;
       
   121 LOCAL_D RThread gThread2;
       
   122 LOCAL_D RSemaphore client;
       
   123 LOCAL_D const TInt KHeapSize = 0x4000;
       
   124 LOCAL_D const TInt KMaxHeapSize = 0x100000;
       
   125 LOCAL_D TBool gPagedRom = EFalse;
       
   126 
       
   127 enum TTestState
       
   128 	{
       
   129 	EThreadWait,
       
   130 	EThreadSignal,
       
   131 	ENoThreads
       
   132 	};
       
   133 
       
   134 /** Formats the drive
       
   135 
       
   136 	@param aDrive 	Drive to be formatted
       
   137 	@param aFormatMode Mode for the format operation
       
   138 */
       
   139 LOCAL_C void Formatting(TInt aDrive, TUint aFormatMode )
       
   140 	{
       
   141 
       
   142 	test.Next(_L("Format"));
       
   143 	TBuf<4> driveBuf = _L("?:\\");
       
   144 	driveBuf[0]=(TText)(aDrive+'A');
       
   145 	RFormat format;
       
   146 	TInt count;
       
   147 	TInt r = format.Open(TheFs,driveBuf,aFormatMode,count);
       
   148 	test_KErrNone(r);
       
   149 	while(count)
       
   150 		{
       
   151 		TInt r = format.Next(count);
       
   152 		test_KErrNone(r);
       
   153 		}
       
   154 	format.Close();
       
   155 	}
       
   156 
       
   157 /** Verifies the content of a buffer (all the letters are like the first one)
       
   158 
       
   159 	@param aBuffer  Buffer to be verified
       
   160 
       
   161 	@return KErrNone if all the letters are the same, KErrCorrupt otherwise
       
   162 */
       
   163 LOCAL_C TInt VerifyBuffer(TDes8& aBuffer)
       
   164 	{
       
   165 	TChar c = aBuffer[0];
       
   166 
       
   167 	for(TInt i = 1; i < aBuffer.Length(); i++)
       
   168 		{
       
   169 		if(i%32 != 0)
       
   170 		{
       
   171 			if(c != (TChar)(aBuffer[i] - 1))
       
   172 				return KErrCorrupt;
       
   173 		}
       
   174 		else
       
   175 		{
       
   176 			if(aBuffer[i] != aBuffer[0])
       
   177 				return KErrCorrupt;
       
   178 		}
       
   179 		c = aBuffer[i];
       
   180 		}
       
   181 
       
   182 	return KErrNone;
       
   183 	}
       
   184 
       
   185 /**  Fills a buffer with character aC, aC+1, aC+2, ..., aC+20, aC, etc
       
   186 
       
   187 	@param aBuffer  Buffer to be filled, output
       
   188 	@param aLength  Length to be filled
       
   189 	@param aC		Character to be used to fill the buffer
       
   190 */
       
   191 LOCAL_C void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC)
       
   192 	{
       
   193 	test (aBuffer.MaxLength() >= aLength);
       
   194 	for(TInt i = 0; i < aLength; i++)
       
   195 		{
       
   196 		aBuffer.Append((i%32) + aC);
       
   197 		}
       
   198 	}
       
   199 
       
   200 /**  Returns true if fat filesystem present on aDrive
       
   201 
       
   202 	@param aFsSession 	Session on the File Server
       
   203 	@param aDrive 		Drive to be looked at
       
   204 */
       
   205 LOCAL_C TBool IsFSFAT(RFs &aFsSession,TInt aDrive)
       
   206 	{
       
   207 	TFileName f;
       
   208 	TInt r = aFsSession.FileSystemName(f,aDrive);
       
   209 
       
   210 	if (r != KErrNone)
       
   211 		{
       
   212 		test.Printf(_L("Unable to get file system name\n"));
       
   213 		return EFalse;
       
   214 		}
       
   215 
       
   216 	return (f.CompareF(_L("Fat")) == 0);
       
   217 	}
       
   218 
       
   219 /** Generates a file name of the form FFFFF*<aPos>.TXT (aLong.3)
       
   220 
       
   221 	@param aBuffer The filename will be returned here
       
   222 	@param aLong   Defines the longitude of the file name
       
   223 	@param aPos	   Defines the number that will be attached to the filename
       
   224 */
       
   225 GLDEF_C void FileNameGen(TDes16& aBuffer, TInt aLong, TInt aPos)
       
   226 {
       
   227 	TInt padding;
       
   228 	TInt i = 0;
       
   229 	TBuf16<10> tempbuf;
       
   230 
       
   231 	_LIT(KNumber,"%d");
       
   232 	tempbuf.Format(KNumber,aPos);
       
   233 	padding = aLong-tempbuf.Size()/2;
       
   234 	aBuffer = _L("");
       
   235 	while(i < padding)
       
   236 	{
       
   237 		aBuffer.Append('F');
       
   238 		i++;
       
   239 	}
       
   240 	aBuffer.Append(tempbuf);
       
   241 
       
   242 	_LIT(KExtension1, ".TXT");
       
   243 	aBuffer.Append(KExtension1);
       
   244 }
       
   245 
       
   246 /**  Delete content of directory
       
   247 
       
   248 	@param aDir	Target directory
       
   249 
       
   250 	@return Error returned if any, otherwise KErrNone
       
   251 */
       
   252 LOCAL_C TInt DeleteAll(TDes16& aDir)
       
   253 {
       
   254 	TBuf16<100> dir;
       
   255 	CFileMan* fMan = CFileMan::NewL(TheFs);
       
   256 	TInt r=0;
       
   257 
       
   258 	dir = aDir;
       
   259 	dir.Append(_L("F*.*"));
       
   260 	r = fMan->Delete(dir);
       
   261 
       
   262 	delete fMan;
       
   263 	return r;
       
   264 }
       
   265 
       
   266 /**  Waits for all the TRequestStatus in status[] to complete
       
   267 
       
   268 	@param status 	Array of TRequestStatus
       
   269 	@param aLength  Length to be filled
       
   270 	@param aC		Character to be used to fill the buffer
       
   271 */
       
   272 LOCAL_C void WaitForAll(TRequestStatus* status, TInt aSize)
       
   273 {
       
   274 	TInt i = 0;
       
   275 
       
   276 	RTest test(_L("T_RCACHE"));
       
   277 
       
   278 	while(i < aSize)
       
   279 		{
       
   280 		User::WaitForRequest(status[i]);
       
   281 		test(status[i] == KErrNone);
       
   282 		i++;
       
   283 		}
       
   284 
       
   285 	test.Close();
       
   286 }
       
   287 
       
   288 /**  Reads the parameters from the comand line
       
   289 	 and updates the appropriate variables
       
   290 */
       
   291 LOCAL_C void parseCommandLine()
       
   292 {
       
   293 	TBuf<0x100> cmd;
       
   294 	User::CommandLine(cmd);
       
   295 	TLex lex(cmd);
       
   296 	TPtrC token = lex.NextToken();
       
   297 	TInt r=0;
       
   298 
       
   299 	if(token.Length() != 0)
       
   300 		{
       
   301 		gDriveToTest = token[0];
       
   302 		gDriveToTest.UpperCase();
       
   303 		}
       
   304 	else
       
   305 		{
       
   306 		gDriveToTest = 'C';
       
   307 		}
       
   308 
       
   309 	r = TheFs.CharToDrive(gDriveToTest,gDrive);
       
   310 	test_KErrNone(r);
       
   311 	gSessionPath = _L("?:\\F32-TST\\");
       
   312 	gSessionPath[0] = (TUint16) gDriveToTest;
       
   313 	test.Printf(_L("\nCLP=%C\n"),(TInt)gDriveToTest);
       
   314 }
       
   315 
       
   316 /**  Writes a file synchronously in blocks of aBlockSize size
       
   317 
       
   318 	@param fs			RFs object
       
   319 	@param aFile		File name
       
   320 	@param aSize		Size of the file in bytes
       
   321 	@param aBlockSize	Size of the blocks to be used in bytes
       
   322 	@param aState		Determines if the operation is being done in the main process
       
   323 						or in a thread
       
   324 	@param aReadBack	Reads the file back if ETrue. This is used for Read-ahead testing to ensure
       
   325 						what is written is also read back through the media driver's cache. If the
       
   326 						file is bigger than the cache, then subsequent streaming reads starting from
       
   327 						position zero will have to be re-read from the media.
       
   328 
       
   329 	@return Returns KErrNone if everything ok, otherwise it panics
       
   330 */
       
   331 LOCAL_C TInt WriteFile(RFs& fs, TDes16& aFile, TInt aSize, TInt aBlockSize, TDes8& aBuf, TTestState aState, TBool aReadBack = EFalse)
       
   332 {
       
   333 	RTest test(_L("T_RCACHE"));
       
   334 
       
   335 	TInt r = 0;
       
   336 	RFile fileWrite;
       
   337 	TInt pos = 0;
       
   338 
       
   339 	test(aBlockSize>0);
       
   340 	test((aSize%aBlockSize) == 0); 	// Ensure the size of the file is a multiple of the block size
       
   341 
       
   342 	if(aState == EThreadWait)
       
   343 	{
       
   344 		gSync.Wait();
       
   345 	}
       
   346 
       
   347 	// delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
       
   348 	r = fs.Delete(aFile);
       
   349 	test_Value(r, r == KErrNone || r == KErrNotFound);
       
   350 
       
   351 	r = fileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
   352 	test_KErrNone(r);
       
   353 
       
   354 	TInt j = 0;
       
   355 	while(j < aSize)
       
   356 		{
       
   357 			r = fileWrite.Write(pos, aBuf);
       
   358 			test_KErrNone(r);
       
   359 
       
   360 			if (aReadBack)
       
   361 				{
       
   362 				r = fileWrite.Read(pos, aBuf);
       
   363 				test_KErrNone(r);
       
   364 				}
       
   365 
       
   366 			if((j>(aSize/2))&&(aState == EThreadSignal))
       
   367 			{
       
   368 				gSync.Signal();
       
   369 				aState = ENoThreads;
       
   370 			}
       
   371 			j += aBlockSize;
       
   372 			pos += aBlockSize;
       
   373 		}
       
   374 	fileWrite.Close();
       
   375 	test.Close();
       
   376 
       
   377 	return KErrNone;
       
   378 }
       
   379 
       
   380 /**  Read File in blocks of size aBlockSize
       
   381 
       
   382 	@param fs			RFs object
       
   383 	@param aFile		File name
       
   384 	@param aBlockSize	Size of the blocks to be used in bytes
       
   385 
       
   386 	@return Returns KErrNone if everything ok, otherwise it panics
       
   387 */
       
   388 LOCAL_C TInt ReadFile(RFs& fs, TDes16& aFile, TInt aBlockSize)
       
   389 {
       
   390 	RTest test(_L("T_RCACHE"));
       
   391 
       
   392 	TInt r = 0, size = 0;
       
   393 	RFile fileRead;
       
   394 
       
   395 	test(aBlockSize>0);				// Block size must be greater than 0
       
   396 
       
   397 	r = fileRead.Open(fs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
       
   398 	test_KErrNone(r);
       
   399 
       
   400 	r = fileRead.Size(size);
       
   401 	test_KErrNone(r);
       
   402 
       
   403 	TInt j = 0;
       
   404 	while(j < size)
       
   405 	{
       
   406 		r = fileRead.Read(gBufReadPtr, aBlockSize);
       
   407 		test_KErrNone(r);
       
   408 		j += aBlockSize;
       
   409 	}
       
   410 	fileRead.Close();
       
   411 	test.Close();
       
   412 
       
   413 	return KErrNone;
       
   414 }
       
   415 
       
   416 /** Write a file asynchronously in blocks of aBlockSize size
       
   417 
       
   418 	@param fs			RFs object
       
   419 	@param aFileWrite	RFile object, needs to exist beyond the scope of this function
       
   420 	@param aFile		File name
       
   421 	@param aSize		Size of the file in bytes
       
   422 	@param aBlockSize	Size of the blocks to be used in bytes
       
   423 	@param aStatus		TRequestStatus array for all the requests
       
   424 */
       
   425 LOCAL_C void WriteFileAsync(RFs& fs, RFile& aFileWrite, TDes16& aFile, TInt aSize, TInt aBlockSize, TRequestStatus aStatus[])
       
   426 {
       
   427 	RTest test(_L("T_RCACHE"));
       
   428 
       
   429 	TInt r = 0;
       
   430 
       
   431 	test(aBlockSize>0);
       
   432 	test((aSize%aBlockSize) == 0); 	// Ensure the size of the file is a multiple of the block size
       
   433 
       
   434 
       
   435 	// delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
       
   436 	r = fs.Delete(aFile);
       
   437 	test(r == KErrNone || r == KErrNotFound);
       
   438 
       
   439 	r = aFileWrite.Replace(fs,aFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
   440 	test_KErrNone(r);
       
   441 
       
   442 	TInt j = 0, i = 0;
       
   443 	while(j < aSize)
       
   444 	{
       
   445 		aFileWrite.Write(gBufWritePtr,aStatus[i]);
       
   446 		r = aStatus[i].Int();
       
   447 		if (r != KErrNone && r != KRequestPending)
       
   448 			{
       
   449 			test.Printf(_L("Write %d returned %d\n"), i, r);
       
   450 			test(0);
       
   451 			}
       
   452 		i++;
       
   453 
       
   454 		j += aBlockSize;
       
   455 	}
       
   456 	test.Close();
       
   457 }
       
   458 
       
   459 /**  Read a file asynchronously in blocks of aBlockSize size
       
   460 
       
   461 	@param fs			RFs object
       
   462 	@param aFileRead	RFile object, needs to exist beyond the scope of this function
       
   463 	@param aFile		File name
       
   464 	@param aSize		Size of the file in bytes
       
   465 	@param aBlockSize	Size of the blocks to be used in bytes
       
   466 	@param aStatus		TRequestStatus array for all the requests
       
   467 
       
   468 	@return KErrNone
       
   469 */
       
   470 LOCAL_C TInt ReadFileAsync(RFs& fs,RFile& aFileRead, TDes16& aFile, TInt aBlockSize,TRequestStatus aStatus[], TInt aFileSize)
       
   471 	{
       
   472 	RTest test(_L("T_RCACHE"));
       
   473 
       
   474 	TInt r = 0;
       
   475 	TInt size = 0;
       
   476 
       
   477 	test(aBlockSize > 0);
       
   478 
       
   479 	r = aFileRead.Open(fs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
       
   480 	test_KErrNone(r);
       
   481 
       
   482 	r = aFileRead.Size(size);
       
   483 	test_KErrNone(r);
       
   484 
       
   485 	test(size == aFileSize);
       
   486 
       
   487 	TInt j = 0, i = 0;
       
   488 	while(j < size)
       
   489 		{
       
   490 		aFileRead.Read(gBufReadPtr,aStatus[i]);
       
   491 		r = aStatus[i].Int();
       
   492 		if (r != KErrNone && r != KRequestPending)
       
   493 			{
       
   494 			test.Printf(_L("Read %d returned %d\n"), i, r);
       
   495 			test(0);
       
   496 			}
       
   497 		i++;
       
   498 
       
   499 		j += aBlockSize;
       
   500 		}
       
   501 
       
   502 	test.Close();
       
   503 	return KErrNone;
       
   504 	}
       
   505 
       
   506 /** Measure the time taken for this file to be written synchronously
       
   507 */
       
   508 LOCAL_C TInt WriteTestFile(TDes16& aFile, TInt aSize, TBool aReadBack = EFalse)
       
   509 {
       
   510 	RTest test(_L("T_RCACHE"));
       
   511 
       
   512 	TTime startTime;
       
   513 	TTime endTime;
       
   514 	TInt r = 0;
       
   515 
       
   516 	startTime.HomeTime();
       
   517 
       
   518 	r = WriteFile(TheFs,aFile, aSize, KBlockSize, gBufWritePtr, ENoThreads, aReadBack);
       
   519 	test_KErrNone(r);
       
   520 
       
   521 	endTime.HomeTime();
       
   522 
       
   523 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
       
   524 
       
   525 	test.Close();
       
   526 	return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   527 }
       
   528 
       
   529 /** Measure the time taken for this file to be read synchronously
       
   530 */
       
   531 LOCAL_C TInt ReadTestFile(TDes16& aFile)
       
   532 {
       
   533 	TTime startTime;
       
   534 	TTime endTime;
       
   535 
       
   536 	startTime.HomeTime();
       
   537 	ReadFile(TheFs,aFile, KBlockSize);
       
   538 	endTime.HomeTime();
       
   539 
       
   540 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
       
   541 
       
   542 	return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   543 }
       
   544 
       
   545 /** Read asynchronously the test file from the disc
       
   546 
       
   547 */
       
   548 LOCAL_C TInt ReadAsyncTestFile(TDes16& aFile, TInt aSize)
       
   549 {
       
   550 	RTest test(_L("T_RCACHE"));
       
   551 
       
   552 	TTime startTime;
       
   553 	TTime endTime;
       
   554 	TRequestStatus status[KWaitRequestsTableSize];
       
   555 	RFs fs;
       
   556 	RFile file;
       
   557 
       
   558 	TInt r = fs.Connect();
       
   559 	test (r == KErrNone);
       
   560 
       
   561 	startTime.HomeTime();
       
   562 
       
   563 	ReadFileAsync(fs, file, aFile, KBlockSize, status, aSize);
       
   564 	WaitForAll(status, aSize/KBlockSize);
       
   565 
       
   566 	endTime.HomeTime();
       
   567 
       
   568 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
       
   569 
       
   570 	file.Close();
       
   571 	fs.Close();
       
   572 	test.Close();
       
   573 	return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   574 }
       
   575 
       
   576 /** Write a file for the simple case
       
   577 
       
   578 */
       
   579 LOCAL_C TInt WriteFileT(TAny* )
       
   580 {
       
   581 	RTest test(_L("T_RCACHE"));
       
   582 	RFs fs;
       
   583 	TInt r = fs.Connect();
       
   584 	test_KErrNone(r);
       
   585 
       
   586 	r = fs.SetSessionPath(gSessionPath);
       
   587 	test_KErrNone(r);
       
   588 	gTime1.HomeTime();
       
   589 
       
   590 	r = WriteFile(fs,gCurrentFile,gCurrentFileSize, KBlockSize,gBufWritePtr, ENoThreads);
       
   591 	test_KErrNone(r);
       
   592 
       
   593 	gTime2.HomeTime();
       
   594 
       
   595 	fs.Close();
       
   596 	test.Close();
       
   597 
       
   598 	gTimeTakenBigFile = I64LOW(gTime2.MicroSecondsFrom(gTime1).Int64());
       
   599 
       
   600 	client.Signal();
       
   601 
       
   602 	return ETrue;
       
   603 }
       
   604 
       
   605 /** Write a file for the concurrent case
       
   606 
       
   607 */
       
   608 LOCAL_C TInt WriteFileT2(TAny* )
       
   609 {
       
   610 	RTest test(_L("T_RCACHE"));
       
   611 	RFs fs;
       
   612 	TInt r = fs.Connect();
       
   613 	test_KErrNone(r);
       
   614 	RFile file;
       
   615 	TRequestStatus status[KWaitRequestsTableSize];
       
   616 
       
   617 
       
   618 	r = fs.SetSessionPath(gSessionPath);
       
   619 	test_KErrNone(r);
       
   620 
       
   621 	WriteFileAsync(fs,file,gFirstFile,gSecondFileSize, KBlockSize, status);
       
   622 	WaitForAll(status,gSecondFileSize/KBlockSize);
       
   623 
       
   624 	TInt size = 0;
       
   625 	file.Size(size);
       
   626 	test( size == gSecondFileSize );
       
   627 
       
   628 	file.Close();
       
   629 	fs.Close();
       
   630 
       
   631 	test.Close();
       
   632 
       
   633 	client.Signal();
       
   634 
       
   635 	return ETrue;
       
   636 }
       
   637 
       
   638 /**  Write a file for the simple case
       
   639 
       
   640 */
       
   641 LOCAL_C TInt ReadFileT(TAny* )
       
   642 {
       
   643 	RTest test(_L("T_RCACHE"));
       
   644 	RFs fs;
       
   645 	TInt r = fs.Connect();
       
   646 	test_KErrNone(r);
       
   647 
       
   648 	r = fs.SetSessionPath(gSessionPath);
       
   649 	test_KErrNone(r);
       
   650 	gTime1.HomeTime();
       
   651 
       
   652 	ReadFile(fs,gCurrentFile, KBlockSize);
       
   653 
       
   654 	gTime2.HomeTime();
       
   655 
       
   656 	fs.Close();
       
   657 	test.Close();
       
   658 
       
   659 	gTimeTakenBigFile = I64LOW(gTime2.MicroSecondsFrom(gTime1).Int64());
       
   660 
       
   661 	client.Signal();
       
   662 
       
   663 	return ETrue;
       
   664 }
       
   665 
       
   666 /**  Simple case, cache effect shown
       
   667 
       
   668 */
       
   669 LOCAL_C void TestSimpleRead()
       
   670 {
       
   671 	TInt r = 0;
       
   672 	TInt time = 0;
       
   673 	TInt time2 = 0;
       
   674 	TInt time3 = 0;
       
   675 	TInt tcreate = 0;
       
   676 
       
   677 	test.Start(_L(""));
       
   678 
       
   679 	test.Next(_L("File fits in: read sync + read sync + read async\n"));
       
   680 
       
   681 	tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
       
   682 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
   683 
       
   684 	time = ReadTestFile(gSecondFile);
       
   685 	test.Printf(KMsg1,time);
       
   686 	time2 = ReadTestFile(gSecondFile);
       
   687 	test.Printf(KMsg2,time2);
       
   688 	time3 = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
       
   689 	test.Printf(KMsg3,time3);
       
   690 #if !defined(__WINS__)
       
   691 	if (gPagedRom)
       
   692 		test.Printf(_L("Skipping timing test on paged ROM\n"));
       
   693 	else
       
   694 		test((time2 <= time) && (time3 < time));
       
   695 #endif
       
   696 
       
   697 	r = DeleteAll(gSessionPath);
       
   698 	test(r == KErrNone || r == KErrInUse);
       
   699 
       
   700 	// Simple case filling/reading the cache from different threads
       
   701 	test.Next(_L("File fits in: read sync (another thread) + read sync + read async\n"));
       
   702 	gCurrentFile = gSecondFile;
       
   703 	gCurrentFileSize = gSecondFileSize;
       
   704 
       
   705 	TBuf<20> buf = _L("Write File");
       
   706 	r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
   707 	test_KErrNone(r);
       
   708 
       
   709 	gThread1.Resume();
       
   710 	client.Wait();
       
   711 
       
   712 	tcreate = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   713 
       
   714 	test.Printf(_L("Time to create the file from a thread: %d ms\n"),tcreate);
       
   715 
       
   716 	buf = _L("Read File");
       
   717 	r = gThread2.Create(buf,ReadFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
   718 	test(r == KErrNone);
       
   719 
       
   720 	gThread2.Resume();
       
   721 	client.Wait();
       
   722 
       
   723 	gThread1.Close();
       
   724 	gThread2.Close();
       
   725 
       
   726 	time = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   727 	test.Printf(KMsg1,time);
       
   728 	time2 = ReadTestFile(gSecondFile);
       
   729 	test.Printf(KMsg2,time2);
       
   730 	time3 = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
       
   731 	test.Printf(KMsg3,time3);
       
   732 #if !defined(__WINS__)
       
   733 	if (gPagedRom)
       
   734 		test.Printf(_L("Skipping timing test on paged ROM\n"));
       
   735 	else
       
   736 		test((time2<=time) && (time3<time));
       
   737 #endif
       
   738 
       
   739 	r = DeleteAll(gSessionPath);
       
   740 	test(r == KErrNone || r == KErrInUse);
       
   741 
       
   742 
       
   743 	test.Next(_L("File doesn't fit in: read sync + read sync + read async\n"));
       
   744 
       
   745 	tcreate = WriteTestFile(gFirstFile,gFirstFileSize);
       
   746 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
   747 
       
   748 	time = ReadTestFile(gFirstFile);
       
   749 	test.Printf(KMsg1,time);
       
   750 	time2 = ReadTestFile(gFirstFile);
       
   751 	test.Printf(KMsg2,time2);
       
   752 	time3 = ReadAsyncTestFile(gFirstFile,gFirstFileSize);
       
   753 	test.Printf(KMsg3,time3);
       
   754 
       
   755 	#if !defined(__WINS__)
       
   756 	// this isn't valid as the file doesn't fit in the cache, so there's no reason why
       
   757 	// the second read should be any faster than the first
       
   758 	// test((time2 <= time) && (time3 < time));
       
   759 	#endif
       
   760 
       
   761 
       
   762 	r = DeleteAll(gSessionPath);
       
   763 	test(r == KErrNone || r == KErrInUse);
       
   764 
       
   765 
       
   766 	test.Next(_L("File doesn't fit in: read sync (another thread) + read sync + read async\n"));
       
   767 	gCurrentFile = gFirstFile;
       
   768 	gCurrentFileSize = gFirstFileSize;
       
   769 
       
   770 	buf = _L("Write Big File");
       
   771 	r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
   772 	test_KErrNone(r);
       
   773 
       
   774 	gThread1.Resume();
       
   775 	client.Wait();
       
   776 
       
   777 	tcreate = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   778 
       
   779 	test.Printf(_L("Time to create the file from a thread: %d ms\n"),tcreate);
       
   780 
       
   781 	buf = _L("Read Big File");
       
   782 	r = gThread2.Create(buf,ReadFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
   783 	test(r == KErrNone);
       
   784 
       
   785 	gThread2.Resume();
       
   786 	client.Wait();
       
   787 
       
   788 	gThread1.Close();
       
   789 	gThread2.Close();
       
   790 
       
   791 	time = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
   792 	test.Printf(KMsg1,time);
       
   793 	time2 = ReadTestFile(gFirstFile);
       
   794 	test.Printf(KMsg2,time2);
       
   795 	time3 = ReadAsyncTestFile(gFirstFile,gFirstFileSize);
       
   796 	test.Printf(KMsg3,time3);
       
   797 
       
   798 	#if !defined(__WINS__)
       
   799 	// this isn't valid as the file doesn't fit in the cache, so there's no reason why
       
   800 	// the second read should be any faster than the first
       
   801 	// test((time2 <= time) && (time3 < time));
       
   802 	#endif
       
   803 
       
   804 	r = DeleteAll(gSessionPath);
       
   805 	test(r == KErrNone || r == KErrInUse);
       
   806 
       
   807 	test.End();
       
   808 }
       
   809 
       
   810 /**  Thread to create file and read from it
       
   811 
       
   812 */
       
   813 LOCAL_C TInt ReadAnotherEntry(TAny* )
       
   814 {
       
   815 	RTest test(_L("T_RCACHE"));
       
   816 	RFs fs;
       
   817 	TInt r = fs.Connect();
       
   818 	RFile file;
       
   819 	HBufC8* lBufSec = NULL;
       
   820 	TPtr8 lBufReadPtr(NULL, 0);
       
   821 
       
   822 	TRAPD(res2,lBufSec = HBufC8::NewL(KBlockSize+1));
       
   823 	test(res2 == KErrNone && lBufSec != NULL);
       
   824 	lBufReadPtr.Set(lBufSec->Des());
       
   825 
       
   826 	test(r == KErrNone);
       
   827 	r = fs.SetSessionPath(gSessionPath);
       
   828 
       
   829 
       
   830 	// delete file first to ensure it's contents are not in the cache (file may be be on the closed file queue)
       
   831 	r = fs.Delete(gFirstFile);
       
   832 	test(r == KErrNone || r == KErrNotFound);
       
   833 
       
   834 	r = file.Create(fs,gFirstFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
   835 
       
   836 	if(r == KErrAlreadyExists)
       
   837 	{
       
   838 		r = file.Open(fs,gFirstFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
   839 		test_KErrNone(r);
       
   840 	}
       
   841 
       
   842 	r = file.Write(gBufWritePtr);
       
   843 	test_KErrNone(r);
       
   844 
       
   845 	client.Signal();
       
   846 
       
   847 	FOREVER
       
   848 		{
       
   849 			r = file.Read(gBufReadPtr, KBlockSize);
       
   850 			test_KErrNone(r);
       
   851 		}
       
   852 
       
   853 }
       
   854 
       
   855 /**  Test the cache behaviour in repeated call situations
       
   856 
       
   857 */
       
   858 LOCAL_C void TestRepeatedRead()
       
   859 {
       
   860 	TInt r = 0;
       
   861 	TInt time = 0;
       
   862 	TInt i = 0;
       
   863 	TInt tcreate = 0;
       
   864 
       
   865 
       
   866 	test.Start(_L(""));
       
   867 	test.Next(_L("File fits in: read sync / read async \n"));
       
   868 
       
   869 	tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
       
   870 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
   871 	while(i < 20)
       
   872 	{
       
   873 		if(!(i % 2))
       
   874 		{
       
   875 			time = ReadTestFile(gSecondFile);
       
   876 			test.Printf(_L("%d)  Sync Read: %d\n"), i+1 , time);
       
   877 		}
       
   878 		else
       
   879 		{
       
   880 			time = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
       
   881 			test.Printf(_L("%d) Async Read: %d\n"), i+1 , time);
       
   882 		}
       
   883 		i++;
       
   884 	}
       
   885 
       
   886 	r = DeleteAll(gSessionPath);
       
   887 	test_KErrNone(r);
       
   888 
       
   889 	test.Next(_L("File fits in: read sync / read async, with another thread using the drive \n"));
       
   890 
       
   891 	TBuf<20> buf = _L("Noise Thread");
       
   892 	r = gThread1.Create(buf,ReadAnotherEntry,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
   893 	test_KErrNone(r);
       
   894 
       
   895 	tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
       
   896 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
   897 
       
   898 	gThread1.Resume();
       
   899 	client.Wait();
       
   900 
       
   901 	i = 0;
       
   902 	while(i < 20)
       
   903 	{
       
   904 		if(!(i%2))
       
   905 		{
       
   906 			time = ReadTestFile(gSecondFile);
       
   907 			test.Printf(_L("%d)  Sync Read: %d\n"), i+1 , time);
       
   908 		}
       
   909 		else
       
   910 		{
       
   911 			time = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
       
   912 			test.Printf(_L("%d) Async Read: %d\n"), i+1 , time);
       
   913 		}
       
   914 		i++;
       
   915 	}
       
   916 
       
   917 	gThread1.Kill(KErrNone);
       
   918 	gThread1.Close();
       
   919 
       
   920 	r = DeleteAll(gSessionPath);
       
   921 	test_KErrNone(r);
       
   922 
       
   923 	test.End();
       
   924 }
       
   925 
       
   926 /**  Concurrent operations testing
       
   927 
       
   928 */
       
   929 LOCAL_C void TestConcurrent()
       
   930 {
       
   931 	TInt r = 0;
       
   932 	TInt time = 0;
       
   933 	TInt time2 = 0;
       
   934 	TInt time3 = 0;
       
   935 
       
   936 	test.Start(_L("Write two files concurrently\n"));
       
   937 
       
   938 	gCurrentFile = gSecondFile;
       
   939 	gCurrentFileSize = gSecondFileSize;
       
   940 
       
   941 	TBuf<20> buf = _L("Write Two Files 1");
       
   942 	r = gThread1.Create(buf,WriteFileT,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
   943 	test_KErrNone(r);
       
   944 
       
   945 	TBuf<20> buf2 = _L("Write Two Files 2");
       
   946 	r = gThread2.Create(buf2,WriteFileT2,KDefaultStackSize*2,KHeapSize,KMaxHeapSize,NULL);
       
   947 	test(r == KErrNone);
       
   948 
       
   949 	gThread1.Resume();
       
   950 	gThread2.Resume();
       
   951 	client.Wait();
       
   952 	client.Wait();
       
   953 
       
   954 	test.Next(_L("Read the two files repeatedly\n"));
       
   955 
       
   956 	test.Printf(_L("File 1:\n"));
       
   957 	time = ReadTestFile(gSecondFile);
       
   958 	test.Printf(KMsg1,time);
       
   959 	time2 = ReadTestFile(gSecondFile);
       
   960 	test.Printf(KMsg2,time2);
       
   961 	time3 = ReadAsyncTestFile(gSecondFile,gSecondFileSize);
       
   962 	test.Printf(KMsg3,time3);
       
   963 
       
   964 	test.Printf(_L("File 2:\n"));
       
   965 
       
   966 	time = ReadTestFile(gFirstFile);
       
   967 	test.Printf(KMsg1,time);
       
   968 	time2 = ReadTestFile(gFirstFile);
       
   969 	test.Printf(KMsg2,time2);
       
   970 	time3 = ReadAsyncTestFile(gFirstFile,gSecondFileSize);
       
   971 	test.Printf(KMsg3,time3);
       
   972 
       
   973 	test.End();
       
   974 
       
   975 	r = DeleteAll(gSessionPath);
       
   976 	test_KErrNone(r);
       
   977 }
       
   978 
       
   979 /**  Create file from other thread, to be cached
       
   980 
       
   981 */
       
   982 LOCAL_C TInt CreateFile(TAny* )
       
   983 {
       
   984 	RTest test(_L("T_RCACHE"));
       
   985 	RFs fs;
       
   986 	TInt r = fs.Connect();
       
   987 	test(r == KErrNone);
       
   988 
       
   989 	r = fs.SetSessionPath(gSessionPath);
       
   990 	test(r == KErrNone);
       
   991 
       
   992 	r = WriteFile(fs, gSecondFile, gSecondFileSize, KBlockSize, gBufWritePtr, EThreadSignal);
       
   993 	test_KErrNone(r);
       
   994 
       
   995 	return KErrNone;
       
   996 }
       
   997 
       
   998 LOCAL_C TBool FindPattern(TUint8 *aBuf, TUint8 *aPattern, TInt aLong, TInt *aOffSet)
       
   999 {
       
  1000 	TInt i = 0;
       
  1001 	TBool found = EFalse;
       
  1002 
       
  1003 	while((i < (aLong-4)) && !found)
       
  1004 	{
       
  1005 		found = (
       
  1006 			(aBuf[i] == aPattern[0])&&
       
  1007 			(aBuf[i+1] == aPattern[1])&&
       
  1008 			(aBuf[i+2] == aPattern[2])&&
       
  1009 			(aBuf[i+3] == aPattern[3])
       
  1010 			);
       
  1011 	i++;
       
  1012 	}
       
  1013 
       
  1014 	if(found)
       
  1015 		*aOffSet = --i;
       
  1016 
       
  1017 	return found;
       
  1018 }
       
  1019 
       
  1020 /**  Corrupts the second file with Raw access
       
  1021 
       
  1022 */
       
  1023 LOCAL_C void CorruptSecondFileRaw()
       
  1024 {
       
  1025 	RRawDisk rDisk;
       
  1026 	TUint8 gBuffer[4] =
       
  1027 	{
       
  1028 		65,66,67,68
       
  1029 	};
       
  1030 	TUint8 gBufferB[4] =
       
  1031 	{
       
  1032 		33,33,33,33
       
  1033 	};
       
  1034 	TPtr8 gBufferBPtr(&gBufferB[0], 4, 4);
       
  1035 
       
  1036 	TUint8 gBuffer2[KBlockSize];
       
  1037 	TPtr8 gBuffer2Ptr(&gBuffer2[0], KBlockSize);
       
  1038 
       
  1039 	TInt r = rDisk.Open(TheFs,gDrive);
       
  1040 	test_KErrNone(r);
       
  1041 
       
  1042 	TInt64 pos = 0;
       
  1043 	TBool found = EFalse;
       
  1044 	TInt offset = 0;
       
  1045 
       
  1046 	while(!found)
       
  1047 	{
       
  1048 		rDisk.Read(pos, gBuffer2Ptr);
       
  1049 		found = FindPattern(gBuffer2, gBuffer, KBlockSize, &offset);
       
  1050 		pos += (KBlockSize);
       
  1051 	}
       
  1052 	pos -= (KBlockSize+1);
       
  1053 	pos = pos+offset;
       
  1054 
       
  1055 	r = rDisk.Write(pos+4, gBufferBPtr);
       
  1056 	test_KErrNone(r);
       
  1057 
       
  1058 	rDisk.Close();
       
  1059 }
       
  1060 
       
  1061 /**  Modifies the second file
       
  1062 
       
  1063 */
       
  1064 LOCAL_C TInt CorruptSecondFile()
       
  1065 {
       
  1066 	TInt r = 0;
       
  1067 	RFile fileWrite;
       
  1068 	HBufC8* dummy = NULL;
       
  1069 	TPtr8 dummyPtr(NULL, 0);
       
  1070 
       
  1071 	TRAPD(res,dummy = HBufC8::NewL(4));
       
  1072 	test(res == KErrNone && dummy != NULL);
       
  1073 
       
  1074 	dummyPtr.Set(dummy->Des());
       
  1075 	FillBuffer(dummyPtr, 4, '1');
       
  1076 
       
  1077 	r = fileWrite.Open(TheFs,gSecondFile,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
  1078 	if(r != 0)
       
  1079 		return r;
       
  1080 	TInt pos = 30;
       
  1081 	r = fileWrite.Seek(ESeekStart,pos);
       
  1082 
       
  1083 	r = fileWrite.Write(dummyPtr);
       
  1084 	if(r != 0)
       
  1085 		return r;
       
  1086 
       
  1087 	fileWrite.Close();
       
  1088 
       
  1089 	delete dummy;
       
  1090 
       
  1091 	return KErrNone;
       
  1092 }
       
  1093 
       
  1094 //
       
  1095 // Read the file verifying content
       
  1096 //
       
  1097 LOCAL_C TInt ReadTestFileVerif(TDes16& aFile, TBool aRaw)
       
  1098 {
       
  1099 	TTime startTime;
       
  1100 	TTime endTime;
       
  1101 	TInt r = 0, size = 0;
       
  1102 	RFile fileRead;
       
  1103 	TInt corrupt = 0;
       
  1104 	TBool isFat=IsFSFAT(TheFs,gDrive);
       
  1105 
       
  1106 	startTime.HomeTime();
       
  1107 
       
  1108 	r = fileRead.Open(TheFs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
       
  1109 	test_KErrNone(r);
       
  1110 
       
  1111 	r = fileRead.Size(size);
       
  1112 	test_KErrNone(r);
       
  1113 
       
  1114 	TInt j = 0;
       
  1115 	while(j < size)
       
  1116 		{
       
  1117 			r = fileRead.Read(gBufReadPtr, KBlockSize);
       
  1118 			if(aRaw)
       
  1119 			{
       
  1120 				if(isFat)
       
  1121 				{
       
  1122 					test_KErrNone(r);
       
  1123 				}
       
  1124 				else
       
  1125 				{
       
  1126 				if(r == KErrCorrupt)
       
  1127 					corrupt++;
       
  1128 				}
       
  1129 			}
       
  1130 			else
       
  1131 			{
       
  1132 				test_KErrNone(r);
       
  1133 			}
       
  1134 			j += KBlockSize;
       
  1135 			r = VerifyBuffer(gBufReadPtr);
       
  1136 			if(r == KErrCorrupt)
       
  1137 				corrupt++;
       
  1138 		}
       
  1139 
       
  1140 	fileRead.Close();
       
  1141 
       
  1142 	test(corrupt>0); // Ensure the cache returns the changed content
       
  1143 
       
  1144 	endTime.HomeTime();
       
  1145 
       
  1146 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
       
  1147 
       
  1148 	return I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
  1149 }
       
  1150 
       
  1151 
       
  1152 /** Negative testing
       
  1153 
       
  1154 */
       
  1155 LOCAL_C void TestNegative()
       
  1156 {
       
  1157 	TInt r = 0;
       
  1158 	TInt time, time2, time3;
       
  1159 	TInt tcreate = 0;
       
  1160 
       
  1161 	test.Start(_L(""));
       
  1162 	// Kill a thread while writing, then read content
       
  1163 	TBuf<20> buf = _L("A thread to kill");
       
  1164 	gCurrentFile = gSecondFile;
       
  1165 	gCurrentFileSize = gSecondFileSize;
       
  1166 
       
  1167 	r = gThread1.Create(buf,CreateFile,KDefaultStackSize,KHeapSize,KMaxHeapSize,NULL);
       
  1168 	test_KErrNone(r);
       
  1169 
       
  1170 	gThread1.Resume();
       
  1171 	gSync.Wait();
       
  1172 	gThread1.Kill(KErrGeneral);
       
  1173 	gThread1.Close();
       
  1174 	test.Next(_L("Read after killing the write in the middle\n"));
       
  1175 	time = ReadTestFile(gSecondFile);
       
  1176 	test.Printf(KMsg1,time);
       
  1177 	time2 = ReadTestFile(gSecondFile);
       
  1178 	test.Printf(KMsg2,time2);
       
  1179 
       
  1180 	// Read async the content
       
  1181 	TInt size = 0;
       
  1182 	TRequestStatus status[KWaitRequestsTableSize];
       
  1183 	TTime startTime;
       
  1184 	TTime endTime;
       
  1185 	RFile fileRead;
       
  1186 
       
  1187 	startTime.HomeTime();
       
  1188 
       
  1189 	r = fileRead.Open(TheFs,gSecondFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
       
  1190 	test_KErrNone(r);
       
  1191 
       
  1192 	r = fileRead.Size(size);
       
  1193 	test_KErrNone(r);
       
  1194 
       
  1195 	TInt j = 0, i = 0;
       
  1196 	while(j < size)
       
  1197 		{
       
  1198 			fileRead.Read(gBufReadPtr,status[i++]);
       
  1199 			test_KErrNone(r);
       
  1200 			j += KBlockSize;
       
  1201 		}
       
  1202 
       
  1203 	j = i;
       
  1204 	i = 0;
       
  1205 	while(i < j)
       
  1206 	{
       
  1207 		User::WaitForRequest(status[i++]);
       
  1208 	}
       
  1209 	fileRead.Close();
       
  1210 	endTime.HomeTime();
       
  1211 	gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64());
       
  1212  	time3 = I64LOW(gTimeTakenBigFile.Int64()) / 1000;
       
  1213 
       
  1214 	test.Printf(KMsg3,time3);
       
  1215 
       
  1216 	// Modify file in some position
       
  1217 	test.Next(_L("Overwrite partially a file\n"));
       
  1218 	Formatting(gDrive, EFullFormat);
       
  1219 	r = TheFs.MkDirAll(gSessionPath);
       
  1220 	if (r != KErrNone && r != KErrAlreadyExists)
       
  1221 		{
       
  1222 		test_KErrNone(r);
       
  1223 		}
       
  1224 
       
  1225 	tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
       
  1226 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
  1227 
       
  1228 	time = ReadTestFile(gSecondFile);
       
  1229 	test.Printf(KMsg1,time);
       
  1230 
       
  1231 	time = ReadTestFile(gSecondFile);
       
  1232 	test.Printf(KMsg2,time);
       
  1233 
       
  1234 	CorruptSecondFile();
       
  1235 
       
  1236 	time = ReadTestFileVerif(gSecondFile,EFalse);
       
  1237 	test.Printf(KMsg1,time);
       
  1238 
       
  1239 	time = ReadTestFileVerif(gSecondFile,EFalse);
       
  1240 	test.Printf(KMsg2,time);
       
  1241 
       
  1242 	// Modify the file in disk, raw access
       
  1243 	test.Next(_L("Overwrite file with raw access\n"));
       
  1244 
       
  1245 	Formatting(gDrive,EFullFormat);
       
  1246 
       
  1247 	r = TheFs.MkDirAll(gSessionPath);
       
  1248 	if (r != KErrNone && r != KErrAlreadyExists)
       
  1249 		{
       
  1250 		test_KErrNone(r);
       
  1251 		}
       
  1252 
       
  1253 
       
  1254 	tcreate = WriteTestFile(gSecondFile, gSecondFileSize);
       
  1255 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
  1256 
       
  1257 	time = ReadTestFile(gSecondFile);
       
  1258 	test.Printf(KMsg1,time);
       
  1259 
       
  1260 	time = ReadTestFile(gSecondFile);
       
  1261 	test.Printf(KMsg2,time);
       
  1262 
       
  1263 	CorruptSecondFileRaw();
       
  1264 
       
  1265 	time = ReadTestFileVerif(gSecondFile,ETrue);
       
  1266 	test.Printf(KMsg1,time);
       
  1267 
       
  1268 	time = ReadTestFileVerif(gSecondFile,ETrue);
       
  1269 	test.Printf(KMsg2,time);
       
  1270 
       
  1271 
       
  1272 	r = DeleteAll(gSessionPath);
       
  1273 	test_KErrNone(r);
       
  1274 
       
  1275 	test.End();
       
  1276 }
       
  1277 
       
  1278 /**  Creates the files to fill the read cache
       
  1279 
       
  1280 	@param aFiles 	 Number of files needed to fill the cache
       
  1281 	@param aFileSize The file size
       
  1282 */
       
  1283 LOCAL_C void CreateFiles(TInt aFiles, TInt aFileSize)
       
  1284 {
       
  1285 	TInt i = 0, r = 0;
       
  1286 	RFile file;
       
  1287 	TBuf16<50> directory;
       
  1288 
       
  1289 	TBuf16<50> path;
       
  1290 	TBuf16<50> buffer(50);
       
  1291 
       
  1292 	directory = gSessionPath;
       
  1293 
       
  1294 	test.Printf(_L("Creating %d files for filling the cache (size %d)\n"), aFiles, aFileSize);
       
  1295 
       
  1296 	// create a big buffer to speed things up
       
  1297 	HBufC8* bigBuf = NULL;
       
  1298 	const TInt KBigBifferSize = 32 * 1024;
       
  1299 	TRAPD(res,bigBuf = HBufC8::NewL(KBigBifferSize));
       
  1300 	test(res == KErrNone && bigBuf != NULL);
       
  1301 
       
  1302 	TPtr8 bigBufWritePtr(NULL, 0);
       
  1303 	bigBufWritePtr.Set(bigBuf->Des());
       
  1304 	FillBuffer(bigBufWritePtr, KBigBifferSize, 'A');
       
  1305 
       
  1306 
       
  1307 	i = 0;
       
  1308 	while(i < aFiles)
       
  1309 	{
       
  1310 		if (i % 10 == 0)
       
  1311 			test.Printf(_L("Creating file %d of %d...\r"), i, aFiles);
       
  1312 		FileNameGen(buffer, 8, i+3) ;
       
  1313 		path = directory;
       
  1314 		path.Append(buffer);
       
  1315 
       
  1316 		// delete file first to ensure it's contents are not in the cache (file may be on the closed file queue)
       
  1317 		r = TheFs.Delete(path);
       
  1318 		test(r == KErrNone || r == KErrNotFound);
       
  1319 
       
  1320 		r = file.Create(TheFs,path,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
  1321 		if(r == KErrAlreadyExists)
       
  1322 			r = file.Open(TheFs,path,EFileShareAny|EFileWrite|EFileReadDirectIO|EFileWriteDirectIO);
       
  1323 		TInt j = 0;
       
  1324 		while(j < aFileSize)
       
  1325 			{
       
  1326 			bigBufWritePtr.SetLength(Min(KBigBifferSize, aFileSize - j));
       
  1327 			r = file.Write(bigBufWritePtr);
       
  1328 			test_KErrNone(r);
       
  1329 			j += bigBufWritePtr.Length();
       
  1330 			}
       
  1331 
       
  1332 		file.Close();
       
  1333 		i++;
       
  1334 	}
       
  1335 	test.Printf(_L("\nFiles created\n"));
       
  1336 	delete bigBuf;
       
  1337 }
       
  1338 
       
  1339 /**  Fills the read cache
       
  1340 
       
  1341 	@param aFile	 Array of files needed to fill the cache
       
  1342 	@param aFiles 	 Number of files needed to fill the cache
       
  1343 	@param aFileSize The file size
       
  1344 */
       
  1345 LOCAL_C void FillCache(RFile aFile[KFilesNeededToFillCache], TInt aFiles, TInt aFileSize)
       
  1346 {
       
  1347 	TInt i = 0, r = 0;
       
  1348 	TBuf16<50> directory;
       
  1349 
       
  1350 	TBuf16<50> path;
       
  1351 	TBuf16<50> buffer(50);
       
  1352 	HBufC8* buf = NULL;
       
  1353 	TPtr8 bufPtr(NULL, 0);
       
  1354 
       
  1355 	TRAPD(res,buf = HBufC8::NewL(2));
       
  1356 	test(res == KErrNone && buf != NULL);
       
  1357 	bufPtr.Set(buf->Des());
       
  1358 
       
  1359 	directory = gSessionPath;
       
  1360 
       
  1361 	i = 0;
       
  1362 	while(i < aFiles)
       
  1363 	{
       
  1364 		FileNameGen(buffer, 8, i+3) ;
       
  1365 		path = directory;
       
  1366 		path.Append(buffer);
       
  1367 		r = aFile[i].Open(TheFs,path,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff);
       
  1368 		test_KErrNone(r);
       
  1369 
       
  1370 		TInt j = 0;
       
  1371 		while(j < aFileSize)
       
  1372 			{
       
  1373 				r = aFile[i].Read(j,bufPtr);
       
  1374 				test_KErrNone(r);
       
  1375 				j += 4*KOneK;
       
  1376 			}
       
  1377 
       
  1378 		i++;
       
  1379 	}
       
  1380 
       
  1381 	delete buf;
       
  1382 	test.Printf(_L("Cache filled\n"));
       
  1383 }
       
  1384 
       
  1385 /** Fills the default cache
       
  1386 
       
  1387 */
       
  1388 LOCAL_C void TestFillCache()
       
  1389 {
       
  1390 	TInt nFiles = KFilesNeededToFillCache;
       
  1391 	TInt fSize = KDefaultCacheSize;
       
  1392 	RFile file[KFilesNeededToFillCache];
       
  1393 
       
  1394 	if(gMediaSize> ((fSize * nFiles)+gSecondFileSize+gFirstFileSize))
       
  1395 	{
       
  1396 		test.Start(_L("Creating files for filling the cache\n"));
       
  1397 		CreateFiles(nFiles,fSize);
       
  1398 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1399 		// get number of items on Page Cache
       
  1400 		TFileCacheStats startPageCacheStats;
       
  1401 		TInt r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
       
  1402 		test(r==KErrNone || r == KErrNotSupported);
       
  1403 		test.Printf(_L("Number of page cache lines on free list at beginning=%d\n"),startPageCacheStats.iFreeCount);
       
  1404 		test.Printf(_L("Number of page cache lines on used list at beginning=%d\n"),startPageCacheStats.iUsedCount);
       
  1405 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
       
  1406 #endif
       
  1407 		FillCache(file,nFiles,fSize);
       
  1408 
       
  1409 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1410 		// get number of items on Page Cache
       
  1411 		r = controlIo(TheFs,gDrive, KControlIoFileCacheStats, startPageCacheStats);
       
  1412 		test(r==KErrNone || r == KErrNotSupported);
       
  1413 		test.Printf(_L("Number of page cache lines on free list at end=%d\n"),startPageCacheStats.iFreeCount);
       
  1414 		test.Printf(_L("Number of page cache lines on used list at end=%d\n"),startPageCacheStats.iUsedCount);
       
  1415 		test.Printf(_L("Number of files on closed queue=%d\n"),startPageCacheStats.iFilesOnClosedQueue);
       
  1416 #endif
       
  1417 		TestSimpleRead();
       
  1418 
       
  1419 		TInt i = 0;
       
  1420 		while( i < KFilesNeededToFillCache )
       
  1421 			{
       
  1422 			file[i++].Close();
       
  1423 			}
       
  1424 
       
  1425 		test.End();
       
  1426 	}
       
  1427 	else
       
  1428 		test.Printf(_L("Skipping the fill of the cache due to lack of space in the current drive\n"));
       
  1429 }
       
  1430 
       
  1431 /**	Overflow-safe tick deltas
       
  1432 
       
  1433 */
       
  1434 static TInt64 TicksToMsec(TUint32 aInitTicks, TUint32 aFinalTicks, TInt aFastCounterFreq)
       
  1435 	{
       
  1436 	TUint32 timeDelta;
       
  1437 	if (aFinalTicks >= aInitTicks)
       
  1438 		timeDelta = aFinalTicks - aInitTicks;
       
  1439 	else
       
  1440 		timeDelta = aFinalTicks + (KMaxTUint32 - aInitTicks);		// must've wrapped
       
  1441 
       
  1442 	return TInt64(timeDelta) * TInt64(1000000) / TInt64(aFastCounterFreq);
       
  1443 	}
       
  1444 
       
  1445 /** Read three blocks and waits for the read ahead on the File Server to do its job
       
  1446 
       
  1447 */
       
  1448 LOCAL_C void TestReadAhead()
       
  1449 {
       
  1450 	TInt r = 0,tcreate;
       
  1451 	RFile fileRead;
       
  1452 	HBufC8* dummy = NULL;
       
  1453 	TPtr8 dummyPtr(NULL, 0);
       
  1454 
       
  1455 	TUint32 initTicks = 0;
       
  1456 	TUint32 finalTicks = 0;
       
  1457 	TTimeIntervalMicroSeconds timeTakenReadFirst(0);
       
  1458 	TTimeIntervalMicroSeconds timeTakenReadSubsequent(0);
       
  1459 
       
  1460 	// On NAND/FAT and NOR/LFFS drives, due to the lack of DMA support, the read-ahead is likely to happen
       
  1461 	// BEFORE control is returned to this test app - for NAND this could be fixed by adding
       
  1462 	// "FileCacheReadAsync OFF" to the estart.txt file, but we can't do this on the integrator as it has no
       
  1463 	// estart.txt file. Also, we can't set "FileCacheReadAsync OFF" for LFFS as it kills the LFFS background
       
  1464 	// processing (!)
       
  1465 	// So... it's only really worth testing on MMC.
       
  1466 	_LIT(KFATName,"FAT");
       
  1467 	TDriveInfo driveInfo;
       
  1468 	test(TheFs.Drive(driveInfo, gDrive) == KErrNone);
       
  1469 	TFileName fileSystem;
       
  1470 	r = TheFs.FileSystemName(fileSystem, gDrive);
       
  1471 	fileSystem.UpperCase();
       
  1472 	test((r==KErrNone)||(r==KErrNotFound));
       
  1473 	// ONLY test on MMC
       
  1474 	if ((driveInfo.iType != EMediaHardDisk) || (fileSystem.Compare(KFATName) != 0))
       
  1475 		{
       
  1476 		test.Printf(_L("Skipping read-ahead testing (drive is not MMC)...\n"));
       
  1477 		return;
       
  1478 		}
       
  1479 
       
  1480 	//--Find out if the drive is sync/async at this point and print information
       
  1481     TPckgBuf<TBool> drvSyncBuf;
       
  1482     r = TheFs.QueryVolumeInfoExt(gDrive, EIsDriveSync, drvSyncBuf);
       
  1483     test(r == KErrNone);
       
  1484 	const TBool bDrvSync = drvSyncBuf();
       
  1485     if(bDrvSync)
       
  1486 		test.Printf(_L("Drive D: is synchronous\n"));
       
  1487 	else
       
  1488 		test.Printf(_L("Drive D: is asynchronous\n"));
       
  1489 
       
  1490 	// use a fast counter as this is more accurate than using TTime
       
  1491 	TInt fastCounterFreq;
       
  1492 	r = HAL::Get(HAL::EFastCounterFrequency, fastCounterFreq);
       
  1493 	test(r == KErrNone);
       
  1494 	test.Printf(_L("HAL::EFastCounterFrequency %d\n"), fastCounterFreq);
       
  1495 
       
  1496 	// Bind this thread to CPU 0. This is so that timer deltas don't drift from
       
  1497 	// scheduling - else, it causes spurious failures.
       
  1498 	if (UserSvr::HalFunction(EHalGroupKernel, EKernelHalNumLogicalCpus, 0, 0) > 1)
       
  1499 		(void)UserSvr::HalFunction(EHalGroupKernel, EKernelHalLockThreadToCpu, (TAny *)0, 0);
       
  1500 
       
  1501 	const TInt KReadLen = 28 * KOneK;
       
  1502 
       
  1503 	TRAPD(res,dummy = HBufC8::NewL(KReadLen));
       
  1504 	test(res == KErrNone && dummy != NULL);
       
  1505 
       
  1506 	dummyPtr.Set(dummy->Des());
       
  1507 
       
  1508 	test.Start(_L("Creating test file..."));
       
  1509 
       
  1510 
       
  1511 	tcreate = WriteTestFile(gFirstFile, gFirstFileSize, ETrue);
       
  1512 	test.Printf(_L("Time to create the file: %d ms\n"),tcreate);
       
  1513 
       
  1514 	r = fileRead.Open(TheFs,gFirstFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOn);
       
  1515 	test_KErrNone(r);
       
  1516 
       
  1517 	// Read #1
       
  1518 	test.Printf(_L("Issuing read #1...\n"));
       
  1519 	initTicks = User::FastCounter();
       
  1520 	r = fileRead.Read(dummyPtr);
       
  1521 	finalTicks = User::FastCounter();
       
  1522 	test_KErrNone(r);
       
  1523 
       
  1524 	timeTakenReadFirst = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
       
  1525 	test.Printf(_L("first read time %d \n"), I64LOW(timeTakenReadFirst.Int64()));
       
  1526 
       
  1527 	// Read #2
       
  1528 	test.Printf(_L("Issuing read #2...\n"));
       
  1529 	r = fileRead.Read(dummyPtr);
       
  1530 
       
  1531 	// Read #3
       
  1532 	test.Printf(_L("Issuing read #3......resulting in read-ahead #1\n"));
       
  1533 	r = fileRead.Read(dummyPtr);
       
  1534 
       
  1535 	// Wait for the read ahead #1 to be done - this should be approx the same size as previous read (KReadLen)
       
  1536 	test.Printf(_L("Wait for read-ahead #1...\n"));
       
  1537 	User::After(I64LOW(timeTakenReadFirst.Int64()) * 3 / 2);
       
  1538 
       
  1539 
       
  1540 	test.Printf(_L("Issuing read #4...resulting in read-ahead #2\n"));
       
  1541 	initTicks = User::FastCounter();
       
  1542 	r = fileRead.Read(dummyPtr);
       
  1543 	finalTicks = User::FastCounter();
       
  1544 	test_KErrNone(r);
       
  1545 	timeTakenReadSubsequent = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
       
  1546 
       
  1547 	test.Printf(_L("read time:  %d \n"), I64LOW(timeTakenReadSubsequent.Int64()));
       
  1548 
       
  1549 #if !defined(__WINS__)
       
  1550 	// NB the read-ahead on LFFS occurs "synchronously" i.e. it occurs before control is returned
       
  1551 	// to the caller. However it's not a good idea to mark the drive as synchronous (FileCacheReadAsync OFF)
       
  1552 	// as this causes the drive thread's priority to be lowered which kills the LFFS background processing (!)
       
  1553 	if (gPagedRom)
       
  1554 		test.Printf(_L("Skipping timing test on paged ROM\n"));
       
  1555 	else
       
  1556 		test(timeTakenReadSubsequent.Int64() < timeTakenReadFirst.Int64());
       
  1557 #endif
       
  1558 
       
  1559 	// The read ahead #2 should now be in progress - this should be approx KReadLen * 2
       
  1560 	// so this read will take result in the next read taking longer than normal (about double)
       
  1561 	test.Printf(_L("Issuing read #5......resulting in read-ahead #3\n"));
       
  1562 	initTicks = User::FastCounter();
       
  1563 	r = fileRead.Read(dummyPtr);
       
  1564 	finalTicks = User::FastCounter();
       
  1565 	test_KErrNone(r);
       
  1566 	timeTakenReadSubsequent = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
       
  1567 	test.Printf(_L("read time:  %d\n"), I64LOW(timeTakenReadSubsequent.Int64()));
       
  1568 
       
  1569 
       
  1570 	// this read should take a long time, so don't test
       
  1571 //#if !defined(__WINS__)
       
  1572 //	test(gTimeTakenReadBlockFile.Int64() < gTimeTakenBigFile.Int64());
       
  1573 //#endif
       
  1574 
       
  1575 	// The third read should be very quick as the previous read-ahead should have already buffered the data
       
  1576 	test.Printf(_L("Issuing read #6......resulting in read-ahead #4\n"));
       
  1577 	initTicks = User::FastCounter();
       
  1578 	r = fileRead.Read(dummyPtr);
       
  1579 	finalTicks = User::FastCounter();
       
  1580 	test_KErrNone(r);
       
  1581 	timeTakenReadSubsequent = TicksToMsec(initTicks, finalTicks, fastCounterFreq);
       
  1582 	test.Printf(_L("read time:  %d\n"), I64LOW(timeTakenReadSubsequent.Int64()));
       
  1583 
       
  1584 
       
  1585 #if !defined(__WINS__)
       
  1586 	if (gPagedRom)
       
  1587 		test.Printf(_L("Skipping timing test on paged ROM\n"));
       
  1588 	else
       
  1589 		test(timeTakenReadSubsequent.Int64() < timeTakenReadFirst.Int64());
       
  1590 #endif
       
  1591 
       
  1592 
       
  1593 	fileRead.Close();
       
  1594 
       
  1595 	r = DeleteAll(gSessionPath);
       
  1596 	test_KErrNone(r);
       
  1597 
       
  1598 	delete dummy;
       
  1599 	test.End();
       
  1600 
       
  1601 }
       
  1602 
       
  1603 /** Main tests function
       
  1604 */
       
  1605 GLDEF_C void CallTestsL()
       
  1606 	{
       
  1607 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1608 	test.Printf(_L("Disabling Lock Fail simulation ...\n"));
       
  1609 	// turn OFF lock failure mode
       
  1610 	TBool simulatelockFailureMode = EFalse;
       
  1611 	TInt r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
       
  1612 	test (r == KErrNone);
       
  1613 #endif
       
  1614 
       
  1615 	TBuf16<45> dir;
       
  1616 
       
  1617 	RProcess().SetPriority(EPriorityBackground);
       
  1618 
       
  1619 	// FileNames/File generation
       
  1620 	test.Start(_L("Preparing the environmnet\n"));
       
  1621 	FileNameGen(gFirstFile, 8, gNextFile++);
       
  1622 	FileNameGen(gSecondFile, 8, gNextFile++);
       
  1623 	dir = gSessionPath;
       
  1624 	dir.Append(gFirstFile);
       
  1625 	gFirstFile = dir;
       
  1626 	dir = gSessionPath;
       
  1627 	dir.Append(gSecondFile);
       
  1628 	gSecondFile = dir;
       
  1629 
       
  1630 
       
  1631 	TRAPD(res,gBuf = HBufC8::NewL(KBlockSize+1));
       
  1632 	test(res == KErrNone && gBuf != NULL);
       
  1633 
       
  1634 	gBufWritePtr.Set(gBuf->Des());
       
  1635 	FillBuffer(gBufWritePtr, KBlockSize, 'A');
       
  1636 
       
  1637 	TRAPD(res2,gBufSec = HBufC8::NewL(KBlockSize+1));
       
  1638 	test(res2 == KErrNone && gBufSec != NULL);
       
  1639 	gBufReadPtr.Set(gBufSec->Des());
       
  1640 
       
  1641 	test.Next(_L("Negative test\n"));
       
  1642 	TestNegative();
       
  1643 
       
  1644 	test.Next(_L("Simple cases, use of the cache from same location/different"));
       
  1645 	TestSimpleRead();
       
  1646 
       
  1647 	test.Next(_L("Repeated reads, same file\n"));
       
  1648 	TestRepeatedRead();
       
  1649 
       
  1650 	test.Next(_L("Read ahead testing\n"));
       
  1651 	TestReadAhead();
       
  1652 
       
  1653 	test.Next(_L("Concurrent read cases\n"));
       
  1654 	TestConcurrent();
       
  1655 
       
  1656 	test.Next(_L("Fill the cache, boundary testing\n"));
       
  1657 	TestFillCache();
       
  1658 
       
  1659 	test.End();
       
  1660 	delete gBuf;
       
  1661 	delete gBufSec;
       
  1662 
       
  1663 #if defined(_DEBUG) || defined(_DEBUG_RELEASE)
       
  1664 	// turn lock failure mode back ON (if enabled)
       
  1665 	simulatelockFailureMode = ETrue;
       
  1666 	r = controlIo(TheFs, gDrive, KControlIoSimulateLockFailureMode, simulatelockFailureMode);
       
  1667 	test (r == KErrNone);
       
  1668 #endif
       
  1669 
       
  1670 	}
       
  1671 
       
  1672 /** Initialises semaphores and call the tests
       
  1673 */
       
  1674 LOCAL_C void DoTests()
       
  1675 	{
       
  1676 	TInt r = 0;
       
  1677 
       
  1678 	r = client.CreateLocal(0);
       
  1679  	test_KErrNone(r);
       
  1680 
       
  1681   	r = gSync.CreateLocal(0);
       
  1682  	test_KErrNone(r);
       
  1683 
       
  1684 
       
  1685 	r = TheFs.SetSessionPath(gSessionPath);
       
  1686 	test_KErrNone(r);
       
  1687 
       
  1688 	r = TheFs.MkDirAll(gSessionPath);
       
  1689 	if (r != KErrNone && r != KErrAlreadyExists)
       
  1690 		{
       
  1691 		test_KErrNone(r);
       
  1692 		}
       
  1693 	TheFs.ResourceCountMarkStart();
       
  1694 	TRAP(r,CallTestsL());
       
  1695 	if (r == KErrNone)
       
  1696 		TheFs.ResourceCountMarkEnd();
       
  1697 	else
       
  1698 		{
       
  1699 		test_KErrNone(r);
       
  1700 		}
       
  1701 	}
       
  1702 
       
  1703 /** Determines the space that can be used for the files
       
  1704 
       
  1705 */
       
  1706 TBool CheckForDiskSize()
       
  1707 {
       
  1708 	TVolumeInfo volInfo;
       
  1709 	TInt r = TheFs.Volume(volInfo, gDrive);
       
  1710 	test_KErrNone(r);
       
  1711 	gMediaSize = volInfo.iSize;
       
  1712 	gSecondFileSize = KBlockSize*92;
       
  1713 	gFirstFileSize = KBlockSize*(256);
       
  1714 	while(((2*gFirstFileSize)+KOneMeg) > gMediaSize )
       
  1715 		{
       
  1716 			gFirstFileSize -= (2*KBlockSize);
       
  1717 		}
       
  1718 
       
  1719 	TReal32 small = (TReal32)(gSecondFileSize/KOneK);
       
  1720 	TReal32 big = (TReal32)(gFirstFileSize/KOneK);
       
  1721 
       
  1722 	test.Printf(_L("Test File: %.2f KB\n"), small );
       
  1723 	test.Printf(_L("Too big for the cache file: %.2f KB (%.2f MB)\n"), big, big / KOneK );
       
  1724 
       
  1725 	if(gFirstFileSize < gSecondFileSize)
       
  1726 		return EFalse;
       
  1727 	else
       
  1728 		return ETrue;
       
  1729 }
       
  1730 
       
  1731 /** Main function
       
  1732 
       
  1733 	@return KErrNone if everything was ok, panics otherwise
       
  1734 */
       
  1735 GLDEF_C TInt E32Main()
       
  1736     {
       
  1737 	// Determine whether this is a paged ROM -
       
  1738 	// if it is we bypass some of the timimg tests as the default paging ROMs have a deliberately
       
  1739 	// small pool of pages (in order to stress the system) and reading things through the file cache
       
  1740 	// in this "artificial" environment can cause code to be evicted which can result in the read timings
       
  1741 	// going AWOL. In a more real-world environment, file caching should turn itself off if the amount of
       
  1742 	// memory falls below a threshold.
       
  1743 #if !defined(__WINS__)
       
  1744 	TRomHeader* romHeader = (TRomHeader*)UserSvr::RomHeaderAddress();
       
  1745 	gPagedRom = romHeader->iPageableRomStart ? (TBool)ETrue : (TBool)EFalse;
       
  1746 #endif
       
  1747 
       
  1748 	RThread t;
       
  1749 	gMainThreadId = t.Id();
       
  1750 
       
  1751 	CTrapCleanup* cleanup;
       
  1752 	cleanup = CTrapCleanup::New();
       
  1753 
       
  1754 	__UHEAP_MARK;
       
  1755 	test.Start(_L("Starting tests... T_RCACHE"));
       
  1756 	parseCommandLine();
       
  1757 
       
  1758 	TInt r = TheFs.Connect();
       
  1759 	test_KErrNone(r);
       
  1760 
       
  1761 	TDriveInfo info;
       
  1762 	TVolumeInfo volInfo;
       
  1763 	r = TheFs.Drive(info,gDrive);
       
  1764 	test_KErrNone(r);
       
  1765 
       
  1766 	if(info.iMediaAtt&KMediaAttVariableSize)
       
  1767 		{
       
  1768 		test.Printf(_L("Tests skipped in RAM drive\n"));
       
  1769 		goto out;
       
  1770 		}
       
  1771 
       
  1772 	r = TheFs.Volume(volInfo, gDrive);
       
  1773 	if (r == KErrNotReady)
       
  1774 		{
       
  1775 		if (info.iType == EMediaNotPresent)
       
  1776 			test.Printf(_L("%c: Medium not present - cannot perform test.\n"), (TUint)gDriveToTest);
       
  1777 		else
       
  1778 			test.Printf(_L("%c: medium found (type %d) but drive not ready\nPrevious test may have hung; else, check hardware.\n"), (TUint)gDriveToTest, (TInt)info.iType);
       
  1779 		}
       
  1780 	else if (r == KErrCorrupt)
       
  1781 		{
       
  1782 		test.Printf(_L("%c: Media corruption; previous test may have aborted; else, check hardware\n"), (TUint)gDriveToTest);
       
  1783 		}
       
  1784 	test_KErrNone(r);
       
  1785 
       
  1786 	if(!(volInfo.iFileCacheFlags & (EFileCacheReadEnabled | EFileCacheReadAheadEnabled)))
       
  1787 		{
       
  1788 		test.Printf(_L("Skipping tests, Read caching not enabled in this drive\n"));
       
  1789 		goto out;
       
  1790 		}
       
  1791 	
       
  1792 	if (((volInfo.iDrive.iMediaAtt & KMediaAttFormattable)))
       
  1793 		Formatting(gDrive,ESpecialFormat);
       
  1794 
       
  1795 	if(CheckForDiskSize())
       
  1796 		{
       
  1797 		DoTests();
       
  1798 		}
       
  1799 	else
       
  1800 		{
       
  1801 		test.Printf(_L("Skipping tests due to lack of space to perform them in this drive\n"));
       
  1802 		}
       
  1803 out:
       
  1804 	test.End();
       
  1805 
       
  1806 	TheFs.Close();
       
  1807 	test.Close();
       
  1808 
       
  1809 	__UHEAP_MARKEND;
       
  1810 	delete cleanup;
       
  1811 	return(KErrNone);
       
  1812     }
       
  1813