kerneltest/f32test/bench/t_fcachebm.cpp
changeset 0 a41df078684a
child 245 647ab20fee2e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/f32test/bench/t_fcachebm.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1500 @@
+// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// f32test/bench/t_fcachebm.cpp
+// 
+//
+
+#include <f32file.h>
+#include <e32test.h>
+#include <e32math.h>
+#include "t_select.h"
+#include "t_benchmain.h"
+
+//----------------------------------------------------------------------------------------------
+//! @SYMTestCaseID      PBASE-T_RCACHE-0192
+//! @SYMTestType        CIT
+//! @SYMPREQ            PREQ914
+//! @SYMTestCaseDesc    This test case is testing performance of the File Server Cache.  
+//! @SYMTestActions     0   setup the environment to execute the tests
+//!						1	small random reads/writes
+//!						2	large sequential reads/writes
+//!						3 	streaming test (100, 200 and 500 kbps)
+//! @SYMTestExpectedResults Finishes if the system behaves as expected, panics otherwise
+//! @SYMTestPriority        High
+//! @SYMTestStatus          Implemented
+//----------------------------------------------------------------------------------------------
+
+
+GLDEF_D RTest test(_L("File Cache BM"));
+
+LOCAL_D RSemaphore client;
+LOCAL_D const TInt KHeapSize = 0x4000;
+LOCAL_D const TInt KTobps = 1000;
+LOCAL_D const TInt KByte = 8;
+LOCAL_D const TInt KOneSec = 1000000; // One second in microseconds
+
+// Tests setup
+LOCAL_D const TInt KSmallRow = 11;
+LOCAL_D const TInt KSmallCol = 7;
+LOCAL_D const TInt KSmallThreshold = 64;
+LOCAL_D const TInt KSeveralTimes = 10;
+
+LOCAL_D const TInt KLargeRow = 19;
+LOCAL_D const TInt KLargeCol = 3;
+
+LOCAL_D TInt gCurrentSpeed = 0; 
+LOCAL_D TInt gCurrentBS = 0;
+
+
+LOCAL_D TBuf8<4096> buf;
+LOCAL_D TDriveList gDriveList;
+
+// Concurrent thread
+RThread gSpeedy;
+RThread gSpeedyII;
+
+TBuf16<25> gBaseFile;
+TBuf16<25> gFileA;
+TBuf16<25> gFileB;
+TBuf16<25> gStreamFile;
+TInt64 gMediaSize;
+
+HBufC8* gBuf = NULL;
+TPtr8 gBufReadPtr(NULL, 0);	
+HBufC8* gBufSec = NULL;
+TPtr8 gBufWritePtr(NULL, 0);	
+
+
+HBufC8* gBufB = NULL;
+TPtr8 gBufReadBPtr(NULL, 0);	
+TBool gWriting = EFalse;
+
+LOCAL_D TInt ThreadCount=0;
+
+enum TTestState 
+	{
+	ENoThreads,			// No threads 
+	ETwoThreadsDif,		// Accessing to different files 
+	ETwoThreadsDifDif, 	// Accessing to different files, different blocksizes
+	ETwoThreadsSame		// Accessing the same file
+	};
+
+
+/** 2 ^ b
+
+	@param b Power 
+*/
+LOCAL_C TInt Pow(TInt b)
+{
+	return 1 << b;
+}
+
+/** Pseudo-random number generator, random enough for the purpose
+
+	@param aMax Upper limit of the number. The interval of generated numbers is [0,aMax)
+*/
+LOCAL_C TInt Rand(TInt aMax) 
+{
+	return (Math::Random() % aMax);
+}
+
+
+/** Fills a buffer with character aC, aC+1, aC+2, ..., aC+32, aC, etc 
+
+	@param aBuffer 	Buffer to fill out
+	@param aLength 	Length to be filled with characters
+	@param aC 		Base character to fill the buffer
+*/
+LOCAL_C void FillBuffer(TDes8& aBuffer, TInt aLength, TChar aC)
+	{
+	test (aBuffer.MaxLength() >= aLength);
+	
+	for(TInt i = 0; i < aLength; i++)
+		{
+		aBuffer.Append((i%32)+aC);
+		}
+	}
+	
+/** Send content through the RDebug for trgtest 
+	not to hung, when the test is not writing
+
+*/
+LOCAL_C TInt noise(TAny* )
+{
+	FOREVER
+	{	
+		User::After(2147483647); // max value, 35 minutes, 47 seconds
+		if(!gWriting)
+			RDebug::Print(_L("."));
+	}
+}
+
+/**  Delete content of directory
+
+	@param aDir Directory to be emptied
+*/
+LOCAL_C TInt DeleteAll(TDes16& aDir) 
+	{
+		TBuf16<100> dir;
+		CFileMan* fMan = CFileMan::NewL(TheFs);
+		TInt r = 0;
+		
+		dir = aDir;
+		dir.Append(_L("F*.*"));
+		r = fMan->Delete(dir);	
+
+		delete fMan;
+		return r;
+	}
+
+
+/**   Creates a file of aSize KBytes
+
+	@param aFile File name 
+	@param aSize Size of the file to be created
+*/
+LOCAL_C void CreateFile(TDes16& aFile, TInt aSize)
+{
+	TInt r = 0;
+	RFile file;
+	
+	
+	r = file.Replace(TheFs, aFile, EFileShareAny|EFileWrite);
+	FailIfError(r);
+
+	TInt j = 0;
+	while(j <= aSize)
+		{
+			r = file.Write(gBufWritePtr, KOneK);
+			FailIfError(r);
+			j += KOneK;
+		}					
+	file.Close();
+}
+
+/**   Kills the concurrent session
+
+*/
+LOCAL_C void DoTestKill()
+{
+	TInt r = 0;
+	
+	gSpeedy.Kill(KErrNone);
+	FailIfError(r);
+	gSpeedy.Close();	
+	
+	gSpeedyII.Kill(KErrNone);
+	FailIfError(r);
+	gSpeedyII.Close();	
+}
+
+/** Read aSize KBs from aFile file in blocks of aBlockSize bytes
+
+	@param aFile 		Name of the file
+	@param aPos			Position from where the read starts within the file
+	@param aBlockSize 	Block size for the I/O operation
+	@param aSize 		
+*/
+LOCAL_C TInt ReadFromFile(TDes16& aFile, TInt aPos, TInt aBlockSize, TInt aSize) 
+{
+	TInt r = 0;
+	TTime startTime;
+	TTime endTime;
+	RFile file;
+	TInt j = 0;
+	TInt size = aSize * KOneK;
+	TTimeIntervalMicroSeconds timeTaken(0);
+
+	r = file.Open(TheFs,aFile,EFileShareAny|EFileRead);
+	FailIfError(r);
+	
+	startTime.HomeTime();	
+	r = file.Seek(ESeekStart, aPos);
+	FailIfError(r);	
+	
+	while(j <= size)
+		{
+			r = file.Read(gBufReadPtr, aBlockSize);
+			FailIfError(r);
+			j += aBlockSize;
+		}					
+	endTime.HomeTime();
+	
+	file.Close();
+	timeTaken = endTime.MicroSecondsFrom(startTime);
+	
+	return I64LOW(timeTaken.Int64() / gTimeUnit);
+}
+
+/** Read aSize KBs from aFile file in blocks of aBlockSize bytes several times
+
+	@param aFile 		Name of the file
+	@param ayMax 		Maximum for the position
+	@param aBlockSize 	Block size for the I/O operation
+	@param aSize 		Size of the file in KB
+*/
+LOCAL_C TInt ReadFromFileSeveralTimes(TDes16& aFile, TInt ayMax, TInt aBlockSize, TInt aSize) 
+{
+	TInt r = 0;
+	TTime startTime;
+	TTime endTime;
+	RFile file;
+	TInt j = 0, i, pos;
+	TInt size = aSize * KOneK;
+	TTimeIntervalMicroSeconds timeTaken(0);
+	TInt64 time = 0;
+	
+
+	r = file.Open(TheFs, aFile, EFileShareAny|EFileRead);
+	FailIfError(r);
+	
+	i = 0;
+	while( i < KSeveralTimes ) 
+		{
+		pos = Rand(Pow(ayMax - 1));
+		startTime.HomeTime();	
+		r = file.Seek(ESeekStart, pos); 
+		FailIfError(r);	
+		
+		j = 0;
+		while(j <= size)
+			{
+				r = file.Read(gBufReadPtr, aBlockSize);
+				FailIfError(r);
+				j += aBlockSize;
+			}					
+		endTime.HomeTime();
+
+		timeTaken = endTime.MicroSecondsFrom(startTime);
+		time += I64LOW(timeTaken.Int64());
+		i++;
+		}
+	
+	file.Close();
+	
+	return I64LOW((time / gTimeUnit) / KSeveralTimes); // Overflow not expected here, since the number is not big enough
+}
+
+
+/** Write aSize KBs to  aFile file in blocks of aBlockSize bytes
+
+	@param aFile 		Name of the file
+	@param aPos			Position from where the read starts within the file
+	@param aBlockSize 	Block size for the I/O operation
+	@param aSize 		Size of the file in KB
+*/
+LOCAL_C TInt WriteToFile(TDes16& aFile, TInt aPos, TInt aBlockSize, TInt aSize) 
+{
+	TInt r = 0;
+	TTime startTime;
+	TTime endTime;
+	RFile file;
+	TInt j = 0;
+	TInt size = aSize * KOneK;
+	TTimeIntervalMicroSeconds timeTaken(0);
+	
+	r = file.Open(TheFs, aFile, EFileShareAny|EFileWrite);
+	FailIfError(r);
+	
+	startTime.HomeTime();	
+	r = file.Seek(ESeekStart, aPos);
+	FailIfError(r);	
+	while(j <= size)
+		{
+			r = file.Write(gBufWritePtr, aBlockSize);
+			FailIfError(r);
+			j += aBlockSize;
+		}					
+	endTime.HomeTime();
+	
+	file.Close();
+	timeTaken = endTime.MicroSecondsFrom(startTime);
+	
+	return I64LOW(timeTaken.Int64() / gTimeUnit);
+}
+
+/** Write aSize KBs to  aFile file in blocks of aBlockSize bytes several times
+
+	@param aFile 		Name of the file
+	@param ayMax 		Maximum for the position
+	@param aBlockSize 	Block size for the I/O operation
+	@param aSize 		Size of the file in KB
+*/
+LOCAL_C TInt WriteToFileSeveralTimes(TDes16& aFile, TInt ayMax, TInt aBlockSize, TInt aSize) 
+{
+	TInt r = 0;
+	TTime startTime;
+	TTime endTime;
+	RFile file;
+	TInt i, j = 0, pos;
+	TInt size = aSize * KOneK;
+	TTimeIntervalMicroSeconds timeTaken(0);
+	TInt64 time = 0;
+	
+	r = file.Open(TheFs, aFile, EFileShareAny|EFileWrite);
+	FailIfError(r);
+	
+	i = 0;
+	while( i < KSeveralTimes ) 
+		{
+		pos = Rand(Pow(ayMax - 1));
+		startTime.HomeTime();	
+		r = file.Seek(ESeekStart, pos);
+		FailIfError(r);	
+		
+		j = 0;
+		while(j <= size)
+			{
+				r = file.Write(gBufWritePtr, aBlockSize);
+				FailIfError(r);
+				j += aBlockSize;
+			}					
+		endTime.HomeTime();
+	
+		timeTaken = endTime.MicroSecondsFrom(startTime);
+		time += I64LOW(timeTaken.Int64());
+		i++;
+		}
+		
+	file.Close();
+
+	return I64LOW((time / gTimeUnit) / KSeveralTimes); // Overflow not expected here, since the number is not big enough
+}
+
+/** Read small blocks in the gBaseFile
+
+*/
+LOCAL_C TInt ReadSmallBase(TAny* )
+{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TBuf8<1024> dummy(1024);
+	TInt blockSize = 0;
+	TInt randPos = 0;
+	TInt i = 0;
+
+	TInt r = fs.Connect();
+	
+	fs.SetSessionPath(gSessionPath);
+	r = file.Open(fs, gBaseFile, EFileShareAny|EFileRead);
+	client.Signal();
+	
+	FailIfError(r);
+		
+	FOREVER
+	{	
+			randPos = Rand(64) * KOneK ; 
+			r = file.Seek(ESeekStart, randPos);
+			FailIfError(r);
+			blockSize = i;
+			
+			r = file.Read(dummy, blockSize); // Sync operation
+			if(i >= 1023) i = 0;
+			else i++;
+	}
+}
+	
+/** Read small blocks in gFileA
+
+*/
+LOCAL_C TInt ReadSmallA(TAny* )
+{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TInt blockSize = 0;
+	TInt randPos = 0;
+	TBuf8<1024> dummy(1024);
+	TInt i = 0;
+
+	TInt r = fs.Connect();
+	
+	fs.SetSessionPath(gSessionPath);
+
+	r = file.Open(fs,gFileA,EFileShareAny|EFileRead);
+	
+	client.Signal();
+	FailIfError(r);
+	
+	FOREVER
+	{	
+			randPos = Rand(64) * KOneK ; 
+			r = file.Seek(ESeekStart, randPos);
+			FailIfError(r);
+			
+			blockSize = i;
+			
+			r = file.Read(dummy, blockSize); // Sync operation
+			FailIfError(r);
+			if(i >= 1023) i = 0;
+			else i++;
+	}
+}
+	
+/** Read small blocks in gFileB
+
+*/
+LOCAL_C TInt ReadSmallB(TAny* )
+	{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TBuf8<1024> dummy(1024);
+	TInt blockSize = 0;
+	TInt randPos = 0;
+	TInt i = 0;
+
+	TInt r = fs.Connect();
+	
+	fs.SetSessionPath(gSessionPath);
+	r = file.Open(fs, gFileB, EFileShareAny|EFileRead);
+	
+	client.Signal();
+	FailIfError(r);
+	
+	FOREVER
+	{
+		randPos = Rand(64) * KOneK ; 
+		r = file.Seek(ESeekStart, randPos);
+		FailIfError(r);
+		blockSize = i;
+		
+		r = file.Read(dummy, blockSize); // Sync operation
+		FailIfError(r);
+		if(i >= 1023) i = 0;
+		else i++;
+	}
+}
+
+
+/** Read large blocks in gBaseFile
+
+*/
+LOCAL_C TInt ReadLargeBase(TAny* )
+	{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TInt pos = 0;
+	TInt blockSize = 128 * KOneK;
+	
+	TInt r = fs.Connect();
+	
+	fs.SetSessionPath(gSessionPath);
+	r = file.Open(fs,gBaseFile,EFileShareAny|EFileRead);
+	
+	client.Signal();
+	FailIfError(r);
+	
+	FOREVER
+	{	
+			r = file.Seek(ESeekStart, pos);
+			FailIfError(r);
+			
+			r = file.Read(gBufReadBPtr, blockSize); // Sync operation
+			FailIfError(r);
+	}
+}
+
+/** Read large blocks in gFileA
+
+*/
+LOCAL_C TInt ReadLargeA(TAny* )
+{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TInt blockSize = 128 * KOneK;
+	TInt pos = 0;
+
+	TInt r = fs.Connect();
+
+	fs.SetSessionPath(gSessionPath);
+	
+	r = file.Open(fs,gFileA,EFileShareAny|EFileRead);
+	
+	client.Signal();
+	FailIfError(r);
+		
+	FOREVER
+	{	
+		r = file.Seek(ESeekStart, pos);
+		FailIfError(r);
+		
+		r = file.Read(gBufReadBPtr, blockSize); // Sync operation
+		FailIfError(r);
+	}
+}
+	
+/** Read large blocks in gFileB
+
+*/
+LOCAL_C TInt ReadLargeB(TAny* )
+{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TInt blockSize = 128 * KOneK;
+	TInt pos = 0;
+
+	TInt r=fs.Connect();
+	FailIfError(r);
+	
+	fs.SetSessionPath(gSessionPath);
+
+	r = file.Open(fs,gFileB,EFileShareAny|EFileRead);
+
+	client.Signal();
+	FailIfError(r);
+	
+	FOREVER
+	{
+		r = file.Seek(ESeekStart, pos);
+		FailIfError(r);
+		
+		r = file.Read(gBufReadBPtr, blockSize); // Sync operation
+		FailIfError(r);
+	}
+}
+
+/** Small reads from a file
+ 
+	@param xMax 	Maximum position on the x axe
+	@param yMax		Maximum position on the y axe
+	@param aCase	Type of test. Possible values:
+		 - ENoThreads : isolated
+		 - ETwoThreadsSame : with two threads accessing same file
+		 - ETwoThreadsDif : with two threads accessing dif. files 
+*/
+LOCAL_C void smallReads(TInt xMax, TInt yMax, TTestState aCase)
+	{	
+	TInt i = 0;
+	TInt j = 0;
+	TInt r = 0;
+	TInt timeRes = 0;
+	
+	CreateFile(gBaseFile, Pow(yMax-1));
+	
+	if(aCase == ETwoThreadsSame) 
+		{ // Start two different threads accessing the same file
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadSmallBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadSmallBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+
+		client.Wait();
+		client.Wait();
+		}
+	
+	if(aCase == ETwoThreadsDif)
+		{ // Start two different threads accessing different files
+		CreateFile(gFileA, Pow(yMax-1));
+		CreateFile(gFileB, Pow(yMax-1));
+		
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadSmallA, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadSmallB, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+				
+		client.Wait();
+		client.Wait();
+		}
+	
+	while(i < xMax)
+		{ // Actual accesses and timing to the main file
+		j = 0;
+		PrintResult(i + 1, j + 1, Pow(i));
+		while(j < yMax) 
+			{
+			if(Pow(i) < KSmallThreshold) 
+				{
+				timeRes = ReadFromFile(gBaseFile, Rand(Pow(yMax - 1)), Pow(i), Pow(j));
+				}
+			else
+				{ // Too small for only one time measure
+				timeRes = ReadFromFileSeveralTimes(gBaseFile, yMax, Pow(i), Pow(j)); 			
+				}
+			
+			gWriting = ETrue; 
+			User::After(1000000);
+
+			PrintResultTime(i + 1, j + 2, timeRes); 
+			
+			gWriting = EFalse;
+			
+			j++;
+			}
+		i++;
+		}
+		
+	
+	if((aCase == ETwoThreadsSame) || (aCase == ETwoThreadsDif))
+		{ // Finish the threads
+		DoTestKill();			
+		}
+	}
+
+/** Large reads from a file
+ 
+ 	@param xMax 	Maximum position on the x axe
+	@param yMax		Maximum position on the y axe
+	@param aCase	Type of test. Possible values:
+		 - ENoThreads : isolated
+		 - ETwoThreadsSame : with two threads accessing same file
+		 - ETwoThreadsDif : with two threads accessing dif. files 
+		 - ETwoThreadsDifDif : with two threads accessing dif. files, different block sizes (big/small)
+*/
+LOCAL_C void largeReads(TInt xMax, TInt yMax, TTestState aCase)
+{
+	TInt i = 0;
+	TInt j = 0;
+	TInt r = 0;
+	TInt timeRes = 0;
+	
+	CreateFile(gBaseFile, 10 * KOneK * KOneK); // 10 Mb 
+	
+	if(aCase == ETwoThreadsSame) 
+	{ // Start two different threads accessing the same file
+
+		TRAPD(res, gBufB = HBufC8::NewL(256 * KOneK));
+		test(res == KErrNone && gBufB != NULL);
+		gBufReadBPtr.Set(gBufSec->Des());
+
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadLargeBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadLargeBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+
+		client.Wait();
+		client.Wait();
+	}
+	
+	if(aCase == ETwoThreadsDif)
+	{ // Start two different threads accessing different files
+	
+		CreateFile(gFileA, KOneK * KOneK);
+		CreateFile(gFileB, KOneK * KOneK);
+		
+		TRAPD(res, gBufB = HBufC8::NewL(256 * KOneK));
+		test(res == KErrNone && gBufB != NULL);
+		gBufReadBPtr.Set(gBufSec->Des());
+		
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadLargeA, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadLargeB, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+				
+		client.Wait();
+		client.Wait();
+	}
+	
+	if(aCase == ETwoThreadsDifDif)
+	{ // Start two different threads accessing different files
+	
+		CreateFile(gFileA, KOneK * KOneK);
+		CreateFile(gFileB, KOneK * KOneK);
+		
+		TRAPD(res,gBufB = HBufC8::NewL(256 * KOneK));
+		test(res == KErrNone && gBufB != NULL);
+		gBufReadBPtr.Set(gBufSec->Des());
+		
+		TBuf<20> buf=_L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadLargeA, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadSmallB, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+				
+		client.Wait();
+		client.Wait();
+	}
+
+	i = 11;
+	while(i < xMax )
+	{ // Actual accesses and timing to the main file
+		j = 0;
+		PrintResult(i - 10, j + 1, Pow(i));
+		while(j < yMax) 
+		{
+			TInt size=0;
+			if(j == 0) 	size = 100 ; // 100 Kb
+			if(j == 1) 	size = KOneK ; // 1 Mb
+			if(j == 2) 	size = 10 * KOneK ; // 10 Mb
+			
+			timeRes = ReadFromFile(gBaseFile, 0, Pow(i), size); 
+
+			gWriting = ETrue; 
+			User::After(1000000);
+
+			PrintResultTime(i - 10, j + 2, timeRes); 
+				
+			gWriting = EFalse;
+
+			j++;
+		}
+		i++;
+	}
+	
+	if((aCase == ETwoThreadsSame) || (aCase == ETwoThreadsDif) || (aCase == ETwoThreadsDifDif))
+	{ // Finish the threads
+		DoTestKill();			
+		delete gBufB;
+	}
+	
+}
+
+/** Large writes to a file
+ 
+	@param xMax 	Maximum position on the x axe
+	@param yMax		Maximum position on the y axe
+	@param aCase	Type of test. Possible values:
+		 - ENoThreads : isolated
+		 - ETwoThreadsSame : with two threads accessing same file
+		 - ETwoThreadsDif : with two threads accessing dif. files 
+*/
+LOCAL_C void largeWrites(TInt xMax, TInt yMax, TTestState aCase)
+{
+	TInt i = 0;
+	TInt j = 0;
+	TInt r = 0;
+	TInt timeRes = 0;
+		
+	CreateFile(gBaseFile, 10 * KOneK * KOneK); // 10 Mb 
+	
+	if(aCase == ETwoThreadsSame) 
+	{ // Start two different threads accessing the same file
+
+		TRAPD(res, gBufB = HBufC8::NewL(256 * KOneK));
+		test(res == KErrNone && gBufB != NULL);
+		gBufReadBPtr.Set(gBufSec->Des());
+
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadLargeBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadLargeBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+
+		client.Wait();
+		client.Wait();
+	}
+	
+	if(aCase == ETwoThreadsDif)
+	{ // Start two different threads accessing different files
+	
+		CreateFile(gFileA, KOneK * KOneK);
+		CreateFile(gFileB, KOneK * KOneK);
+		
+		TRAPD(res, gBufB = HBufC8::NewL(256 * KOneK));
+		test(res == KErrNone && gBufB != NULL);
+		gBufReadBPtr.Set(gBufSec->Des());
+		
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadLargeA, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadLargeB, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+				
+		client.Wait();
+		client.Wait();
+	}
+	
+	i = 11;
+	while(i < xMax )
+	{ // Actual accesses and timing to the main file
+		j = 0;
+		PrintResult(i - 10 , j + 1, Pow(i));
+		while(j < yMax) 
+		{
+			TInt size=0;
+			if(j == 0) 	size = 100 ; // 100 Kb
+			if(j == 1) 	size = KOneK ; // 1 Mb
+			if(j == 2) 	size = 10 * KOneK ; // 10 Mb
+			timeRes = WriteToFile(gBaseFile, 0, Pow(i), size); 
+			
+			gWriting = ETrue; 
+			User::After(1000000);
+
+			PrintResultTime(i - 10, j + 2, timeRes); 
+			
+			gWriting = EFalse;			
+			j++;
+		}
+		i++;
+	}
+	
+	if((aCase == ETwoThreadsSame) || (aCase == ETwoThreadsDif) || (aCase == ETwoThreadsDifDif))
+	{ // Finish the threads
+		DoTestKill();			
+		delete gBufB;
+	}
+	
+}
+
+/** Small writes to a file
+ 
+	@param xMax 	Maximum position on the x axe
+	@param yMax		Maximum position on the y axe
+	@param aCase	Type of test. Possible values:
+		 - ENoThreads : isolated
+		 - ETwoThreadsSame : with two threads accessing same file
+		 - ETwoThreadsDif : with two threads accessing dif. files 
+*/
+LOCAL_C void smallWrites(TInt xMax, TInt yMax, TTestState aCase)
+{
+	TInt i = 0;
+	TInt j = 0;
+	TInt r = 0;
+	TInt timeRes = 0;
+	
+	CreateFile(gBaseFile, Pow(yMax-1));
+	
+	if(aCase == ETwoThreadsSame) 
+	{ // Start two different threads accessing the same file
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadSmallBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadSmallBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+
+		client.Wait();
+		client.Wait();
+	}
+	
+	if(aCase == ETwoThreadsDif)
+	{ // Start two different threads accessing different files
+		CreateFile(gFileA, Pow(yMax-1));
+		CreateFile(gFileB, Pow(yMax-1));
+		
+		TBuf<20> buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		r = gSpeedy.Create(buf, ReadSmallA, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		buf = _L("Speedy");
+		buf.AppendNum(ThreadCount++);
+		
+		r = gSpeedyII.Create(buf, ReadSmallB, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+		FailIfError(r);
+		
+		gSpeedy.Resume();
+		gSpeedyII.Resume();
+				
+		client.Wait();
+		client.Wait();
+	}
+	
+	while(i < xMax)
+	{
+		j = 0;
+		PrintResult(i + 1, j + 1, Pow(i));
+		while(j < yMax) 
+		{
+			if(Pow(i) < KSmallThreshold) 
+				{
+				timeRes = WriteToFile(gBaseFile, Rand(Pow(yMax-1)), Pow(i), Pow(j)); 
+				}
+			else
+				{
+				timeRes = WriteToFileSeveralTimes(gBaseFile, yMax, Pow(i), Pow(j)); 
+				}
+							
+			gWriting = ETrue; 
+			User::After(1000000);
+
+			PrintResultTime(i + 1, j + 2, timeRes); 
+			
+			gWriting = EFalse;
+				
+			j++;
+		}
+		i++;
+	}
+	
+	if((aCase == ETwoThreadsSame) || (aCase == ETwoThreadsDif))
+	{ // Finish the threads
+		DoTestKill();
+	}
+	
+}
+
+/** This test benchmarks small random r/w (e.g. database access)
+
+	@param aSelector Selection array for manual tests
+*/
+LOCAL_C TInt TestSmall(TAny* aSelector)
+{
+	
+	Validate(aSelector);
+	
+	// Each test case of the suite has an identifyer for parsing purposes of the results
+	gTestHarness = 7;	
+	gTestCase = 1;
+	gTimeUnit = 1;
+	
+	PrintHeaders(4, _L("t_fcachebm. Small Random r/w"));
+	
+	// Small reads
+	test.Printf(_L("#~TS_Title_%d,%d: Small reads, no threads \n"), gTestHarness, gTestCase);
+
+	smallReads(KSmallRow, KSmallCol, ENoThreads); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Small reads, threads accessing same file \n"), 
+														gTestHarness, gTestCase);
+	
+	smallReads(KSmallRow, KSmallCol, ETwoThreadsSame); 
+	
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Small reads, threads accessing dif files \n"),
+															 gTestHarness, gTestCase);
+	
+	smallReads(KSmallRow, KSmallCol, ETwoThreadsDif); 
+	
+	gTestCase++;
+	DeleteAll(gSessionPath);
+	
+	// Small writes test case 
+	
+	test.Printf(_L("#~TS_Title_%d,%d: Test small writes\n"), gTestHarness, gTestCase);
+
+	smallWrites(KSmallRow, KSmallCol, ENoThreads); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Small writes, threads accessing same file \n"), 
+															gTestHarness, gTestCase);
+	smallWrites(KSmallRow, KSmallCol, ETwoThreadsSame); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Small writes, threads accessing dif files \n"),
+															 gTestHarness, gTestCase);
+	smallWrites(KSmallRow, KSmallCol, ETwoThreadsDif); 
+
+	gTestCase++;
+	DeleteAll(gSessionPath);
+	test.Printf(_L("#~TestEnd_%d\n"), gTestHarness);
+	
+	return(KErrNone);
+}
+
+/** This test benchmarks large sequential r/w (e.g. MM)
+
+	@param aSelector Selection array for manual tests
+*/
+LOCAL_C TInt TestLarge(TAny* aSelector)
+{
+	
+	Validate(aSelector);
+
+	// Each test case of the suite has an identifyer for parsing purposes of the results
+	gTestHarness = 8;	
+	gTestCase = 1;
+	gTimeUnit = 1000;
+	
+	PrintHeaders(3, _L("t_fcachebm. Large sequential r/w"));
+	
+	// Large reads
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential reads\n"), gTestHarness, gTestCase);
+	
+	largeReads(KLargeRow, KLargeCol, ENoThreads); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential reads, threads accessing same file\n"), 
+																	gTestHarness, gTestCase);
+	largeReads(KLargeRow, KLargeCol, ETwoThreadsSame); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential reads, threads accessing dif files\n"), 
+																	gTestHarness, gTestCase);
+	largeReads(KLargeRow, KLargeCol, ETwoThreadsDif); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential reads, threads accessing dif files some big some small blocks\n"),
+																	gTestHarness, gTestCase);
+	largeReads(KLargeRow, KLargeCol, ETwoThreadsDifDif); 
+
+	gTestCase++;
+	DeleteAll(gSessionPath);
+
+	// Large writings		
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential writes\n"), gTestHarness, gTestCase);
+
+	largeWrites(KLargeRow, KLargeCol, ENoThreads); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential writes, threads accessing same file\n"), 
+																	gTestHarness, gTestCase);
+	largeWrites(KLargeRow, KLargeCol, ETwoThreadsSame); 
+
+	gTestCase++;
+	test.Printf(_L("#~TS_Title_%d,%d: Large sequential writes, threads accessing dif files\n"), 
+																	gTestHarness, gTestCase);
+	largeWrites(KLargeRow, KLargeCol, ETwoThreadsDif); 
+
+	gTestCase++;
+	DeleteAll(gSessionPath);
+	test.Printf(_L("#~TestEnd_%d\n"), gTestHarness);
+	
+	return(KErrNone);
+}
+
+/** Writes aSize bytes of data in aBlockSize during aTime seconds 
+	if the aSize bps is not met, it fails
+
+	@param f 			File to write to
+	@param aSize 		Size in bytes of data to be written 
+	@param aBlockSize 	Block size to be used
+	@param aTime 		Time during which the write has to happen in seconds 
+*/
+LOCAL_C TBool writeStr( RFile f, TInt aSize, TInt aBlockSize, TInt aTime) 
+{
+	TInt r = 0, j = 0;
+	TTime startTime, endTime;
+	TTimeIntervalMicroSeconds timeTaken(0);
+	TTimeIntervalMicroSeconds32 timeLeft(0);
+	TBool onTarget = ETrue;
+	
+	TInt time;
+
+	TInt i = 0;
+	while((i < aTime) && onTarget) 
+	{
+		// If measuring the CPU time
+		
+		startTime.HomeTime();	
+		j = 0;
+		while(j < aSize)
+			{
+				r = f.Write(gBufWritePtr, aBlockSize);
+				FailIfError(r);
+				j += aBlockSize;
+			}					
+		endTime.HomeTime();
+		
+		timeTaken = endTime.MicroSecondsFrom(startTime);	
+		time = I64LOW(timeTaken.Int64());
+		if(time > KOneSec) 
+		{
+			onTarget = EFalse; 			
+		}
+		
+		timeLeft = KOneSec - time;
+		if(timeLeft.Int() >= 0) 
+		{
+			User::After(timeLeft);
+		}
+		i++;
+	}
+	
+	return onTarget;
+}
+
+/** Reads streaming
+
+*/
+LOCAL_C TInt ReadStream(TAny*)
+{
+	RTest test(_L("test 2"));
+	RFs fs;
+	RFile file;
+	TInt j = 0;
+	TTime startTime, endTime;
+	TTimeIntervalMicroSeconds timeTaken(0);
+	TTimeIntervalMicroSeconds32 timeLeft(0);
+	TInt time;
+	TInt size , currentPos = 0; 
+
+	TInt r = fs.Connect();
+	
+	fs.SetSessionPath(gSessionPath);
+	
+	r = file.Open(fs, gStreamFile, EFileShareAny|EFileRead);
+	
+	client.Signal();
+
+	FailIfError(r);
+	r = file.Size(size);
+	FailIfError(r);
+
+	FOREVER
+	{
+		startTime.HomeTime();	
+		j = 0;
+		while(j < (gCurrentSpeed * KOneK))
+			{
+				r=file.Read(gBufReadPtr,gCurrentBS);
+				FailIfError(r);
+				j += gCurrentBS;
+			}					
+		endTime.HomeTime();
+		
+		timeTaken = endTime.MicroSecondsFrom(startTime);	
+		time = I64LOW(timeTaken.Int64());
+		
+		if(time > KOneSec) 
+		{
+			test.Printf(_L("Background Thread: Speed failed to be achieved: %d kbps\n"), gCurrentSpeed);			
+		}
+		
+
+		
+		timeLeft = KOneSec - time;
+		User::After(timeLeft);
+		currentPos += (gCurrentSpeed * KOneK); 
+		r = file.Size(size);
+		FailIfError(r);
+		if(currentPos > size ) 
+		{
+			currentPos = 0;
+			file.Seek(ESeekStart, currentPos);
+		}
+
+	}
+	
+}
+
+/** Test case layout, read/write at aSpeed during aWtime and aRTime
+
+	@param aSpeed 		Target speed in kbps
+	@param aBlockSize 	Block size for the I/O operation
+	@param aWTime		Writing time
+	@param aRTime 		Reading time 		
+*/
+LOCAL_C void streamIt ( TInt aSpeed, TInt aBlockSize, TInt aWTime, TInt aRTime, TInt aStep)
+{
+	TInt iSize = (aSpeed * KTobps) / KByte;  // Size in bytes
+	RFile file;
+	TInt pos = 0;
+	TInt r = 0;
+	
+	PrintResult(aStep, 1, aBlockSize);
+	
+	r = file.Replace(TheFs, gStreamFile, EFileShareAny|EFileWrite);
+	FailIfError(r);
+
+	// Streaming to the media during aWTime seconds
+	if(writeStr(file, iSize, aBlockSize, aWTime))
+	{	//Pass (1)
+		PrintResult(aStep, 2, 1); 
+	}
+	else 
+	{ //Fail (0)
+		PrintResult(aStep, 2, 0); 
+	}
+	
+	// Create a different thread for reading from the beginning during aRTime
+	TBuf<20> buf = _L("Speedy");
+	buf.AppendNum(ThreadCount++);
+	
+	gCurrentSpeed = aSpeed; 
+	gCurrentBS = aBlockSize; 
+	r = gSpeedy.Create(buf, ReadStream, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+	FailIfError(r);
+
+	gSpeedy.Resume();
+	client.Wait();
+
+	// Keep writing during the time the other thread is reading
+	if(writeStr(file, iSize, aBlockSize, aRTime))
+	{ //Pass (1)
+		PrintResult(aStep, 3, 1); 	
+	}
+	else
+	{ //Fail (0)
+		PrintResult(aStep, 3, 0); 
+	}
+	
+	// Writing from the beginning again 
+	file.Seek(ESeekStart, pos);
+	if(writeStr(file, iSize, aBlockSize, aRTime))
+	{ //Pass (1)
+		PrintResult(aStep, 4, 1); 	
+	}
+	else
+	{ //Fail (0)
+		PrintResult(aStep, 4, 0); 
+	}
+	
+
+	// Kill the thread for reading
+	gSpeedy.Kill(KErrNone);
+	FailIfError(r);
+	gSpeedy.Close();	
+	
+	file.Close();	
+}
+
+/** Iterating through different blocksizes
+
+	@param aSpeed Speed at which the test happens
+*/
+LOCAL_C void streaming(TInt aSpeed)
+{
+	TInt i = 9; // Pow(i) = 512 bytes
+	TInt blockSize = 0;
+	TInt testStep = 1;
+	
+	while( i < 15 ) // Pow(i) = 16 Kb
+	{
+		blockSize = Pow(i) ; 
+		streamIt(aSpeed, blockSize, 5 * 60, 15, testStep++); // 5 minutes writing , then 15 secs reading
+		i++;
+	}
+}
+
+/** High level test routine. Different test cases executed
+
+	@param aSelector 	Test case configuration in case of manual execution
+*/
+LOCAL_C TInt TestStreaming(TAny* aSelector)
+{
+	
+	Validate(aSelector);
+	// Each test case of the suite has an identifyer for parsing purposes of the results
+	gTestHarness = 9;	
+	gTestCase = 1;
+
+
+	PrintHeaders(5, _L("t_fcachebm. Streaming"));
+	
+	test.Printf(_L("#~TS_Title_%d,%d: Writing / reading at 100 kbps\n"), 
+												gTestHarness, gTestCase);
+	
+	streaming(100);
+	
+	test.Printf(_L("#~TS_Title_%d,%d: Writing / reading at 200 kbps\n"), 
+												gTestHarness, ++gTestCase);
+
+	streaming(200);
+
+	test.Printf(_L("#~TS_Title_%d,%d: Writing / reading at 500 kbps\n"), 
+												gTestHarness, ++gTestCase);
+
+	streaming(500);
+
+
+	DeleteAll(gSessionPath);
+
+	// Start the small random reads in the background
+	CreateFile(gBaseFile, Pow(KSmallCol-1));
+	
+	TBuf<20> buf=_L("Speedy");
+	buf.AppendNum(ThreadCount++);
+	
+	TInt r = gSpeedyII.Create(buf, ReadSmallBase, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+	FailIfError(r);
+
+	gSpeedyII.Resume();
+	client.Wait();
+	
+	// Measure the throughput with background activity
+	test.Printf(_L("#~TS_Title_%d,%d: Writing / reading at 100 kbps, while small reads\n"), 
+																gTestHarness, ++gTestCase);
+
+	streaming(100);	
+
+	test.Printf(_L("#~TS_Title_%d,%d: Writing / reading at 200 kbps, while small reads\n"), 
+																gTestHarness, ++gTestCase);
+
+	streaming(200);
+	
+	test.Printf(_L("#~TS_Title_%d,%d: Writing / reading at 500 kbps, while small reads\n"), 
+																gTestHarness, ++gTestCase);
+	
+	streaming(500);
+	
+	// Kill the small random reads and writes 
+	gSpeedyII.Kill(KErrNone);
+	FailIfError(r);
+	
+	gSpeedyII.Close();	
+	
+	DeleteAll(gSessionPath);
+
+	gTestCase++;
+	test.Printf(_L("#~TestEnd_%d\n"), gTestHarness);
+	
+	return(KErrNone);
+}
+
+/** It goes automatically through all the options
+
+	@param aSelector Configuration in case of manual execution
+*/
+LOCAL_C TInt TestAll(TAny* aSelector)
+{
+ 	TestSmall(aSelector);
+ 	TestLarge(aSelector);
+ 	TestStreaming(aSelector);
+
+	return(KErrNone);
+}
+
+/** Call all tests
+
+*/
+GLDEF_C void CallTestsL()
+{
+	TBuf16<25> temp;
+	
+	TInt r=client.CreateLocal(0);
+	FailIfError(r);
+	
+	// Setting up the environment and creating the needed files
+	gSessionPath = _L("?:\\F32-TST\\");
+	gSessionPath[0] = (TText) gDriveToTest;
+	
+	FileNamesGeneration(temp, 8, 0, 1);	
+	gBaseFile = gSessionPath;
+	gBaseFile.Append(temp);
+	
+	FileNamesGeneration(temp, 8, 1, 1);	
+	gFileA = gSessionPath;
+	gFileA.Append(temp);
+	
+	FileNamesGeneration(temp, 8, 2, 1);	
+	gFileB = gSessionPath;
+	gFileB.Append(temp);
+
+	FileNamesGeneration(temp, 8, 3, 1);	
+	gStreamFile = gSessionPath;
+	gStreamFile.Append(temp);
+
+	TRAPD(res,gBuf = HBufC8::NewL(256 * KOneK));
+	test(res == KErrNone && gBuf != NULL);
+		
+	gBufWritePtr.Set(gBuf->Des());
+	FillBuffer(gBufWritePtr, 256 * KOneK, 'A');
+	
+	TRAPD(res2, gBufSec = HBufC8::NewL(256 * KOneK));
+	test(res2 == KErrNone && gBufSec != NULL);
+	gBufReadPtr.Set(gBufSec->Des());
+
+	TVolumeInfo volInfo;
+	TInt drive;
+	
+	r = TheFs.CharToDrive(gDriveToTest,drive);
+	FailIfError(r);
+	r = TheFs.Volume(volInfo, drive);
+	FailIfError(r);
+	
+	gMediaSize = volInfo.iSize;
+	
+	FormatFat(gSessionPath[0]-'A');
+	TheFs.MkDirAll(gSessionPath);
+
+	RThread noisy; 
+	TBuf<20> buf = _L("Noisy");
+	r = noisy.Create(buf, noise, KDefaultStackSize, KHeapSize, KHeapSize, NULL);
+	FailIfError(r);
+	
+	noisy.Resume();
+
+	CSelectionBox* TheSelector=CSelectionBox::NewL(test.Console());
+	
+	if(gMode == 0) 
+	{ // Manual
+		gSessionPath=_L("?:\\");
+		TCallBack smallOps(TestSmall, TheSelector);
+		TCallBack largeOps(TestLarge, TheSelector);
+		TCallBack simulOps(TestStreaming, TheSelector);
+		TCallBack tAll(TestAll, TheSelector);
+		TheSelector->AddDriveSelectorL(TheFs);
+		TheSelector->AddLineL(_L("Small random r/w"), smallOps);
+		TheSelector->AddLineL(_L("Large conseq r/w"), largeOps);
+		TheSelector->AddLineL(_L("Streaming"), simulOps);
+		TheSelector->AddLineL(_L("Execute all options"), tAll);
+		TheSelector->Run();
+	}
+	else 
+	{ // Automatic
+		TestAll(TheSelector);
+	}
+	
+	DeleteAll(gSessionPath);
+			
+	client.Close();
+	delete TheSelector;
+	delete gBuf;
+	delete gBufSec;
+	noisy.Kill(KErrNone);
+	noisy.Close();	
+}