kerneltest/f32test/concur/t_cfsperform.cpp
changeset 0 a41df078684a
child 109 b3a1d9898418
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2004-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 // tests read/write throughput on two drives simultaneously
       
    15 // 
       
    16 //
       
    17 
       
    18 //! @file f32test\concur\t_cfsbench.cpp
       
    19 
       
    20 #include <f32file.h>
       
    21 #include <e32test.h>
       
    22 #include <f32dbg.h>
       
    23 #include "t_server.h"
       
    24 #include "t_tdebug.h"
       
    25 
       
    26 //IMPORT_C TUint32 DebugRegister();
       
    27 
       
    28 
       
    29 GLDEF_D RTest test(_L("T_CFSBENCH"));
       
    30 GLDEF_D	RFs TheFs;
       
    31 
       
    32 LOCAL_D TFullName gFsName;
       
    33 LOCAL_D TFullName gFsName1;
       
    34 LOCAL_D TFullName gFsName2;
       
    35 LOCAL_D TFullName gOldFsName;
       
    36 LOCAL_D TFullName gNewFsName;
       
    37 LOCAL_D TBool     gNoMedia = ETrue;
       
    38 
       
    39 _LIT(KFsFile, "CFAFSDLY");
       
    40 _LIT(KFsName, "DelayFS");
       
    41 
       
    42 LOCAL_D const TInt32 KSecond = 1000000;
       
    43 LOCAL_D const TInt32 KTimeBM = 20;
       
    44 
       
    45 
       
    46 LOCAL_D const TInt32 KBufLen = 0x100;
       
    47 
       
    48 LOCAL_D const TInt32 KMaxLag = 4;
       
    49 
       
    50 LOCAL_D TBool gVerbose = EFalse;
       
    51 
       
    52 TBuf16<KBufLen> gResults;
       
    53 
       
    54 const TInt KMaxFileSize = (4*1024*1024);
       
    55 const TInt KMinBufferSize = (16);
       
    56 const TInt KMaxBufferSize = (512*1024);
       
    57 const TInt KMaxIter = 17;
       
    58 
       
    59 
       
    60 TBool gReadTests = EFalse;
       
    61 TBool gWriteTests = EFalse;
       
    62 TBool gAsyncTests = EFalse;
       
    63 TBool gSyncTests = EFalse;
       
    64 
       
    65 
       
    66 LOCAL_C TInt32 GetSpeed(TInt aOps, TInt aBufSize, TInt64 aDtime)
       
    67 /// Calculate and return the throughput from the umber of blocks transferred
       
    68 /// and the elapsed time.
       
    69 	{
       
    70 	TInt64 dsize = MAKE_TINT64(0, aOps) * MAKE_TINT64(0, aBufSize) * MAKE_TINT64(0, KSecond);
       
    71 	TInt32 speed = I64LOW((dsize + aDtime/2) / aDtime);
       
    72 	return speed;
       
    73 	}
       
    74 
       
    75 LOCAL_C TBool DriveIsOK(TChar c)
       
    76 /// Test that a selected drive leter is OK to write files.
       
    77 	{
       
    78 	TInt r;
       
    79 	TInt drv;
       
    80 	r=TheFs.CharToDrive(c, drv);
       
    81 	if (r != KErrNone)
       
    82 		return EFalse;
       
    83 	TDriveInfo info;
       
    84 	r=TheFs.Drive(info,drv);
       
    85 	test(r==KErrNone);
       
    86 	return (info.iDriveAtt != 0 && !(info.iDriveAtt & KDriveAttRom));
       
    87 	}
       
    88 
       
    89 LOCAL_C TChar MountTestFileSystem(TInt aDrive)
       
    90 //
       
    91 // Mount a new CTestFileSystem on the drive under test
       
    92 //
       
    93 	{
       
    94 	TInt r;
       
    95 	TBuf<64> b;
       
    96 	TChar c;
       
    97 	r=TheFs.DriveToChar(aDrive,c);
       
    98 	test(r==KErrNone);
       
    99 	b.Format(_L("Mount test file system on %c:"),(TUint)c);
       
   100 	test.Next(b);
       
   101 
       
   102 	r=TheFs.AddFileSystem(KFsFile);
       
   103 	test(r==KErrNone || r==KErrAlreadyExists);
       
   104 	
       
   105 	r=TheFs.FileSystemName(gOldFsName,aDrive);
       
   106 	test(r==KErrNone || r==KErrNotFound);
       
   107 
       
   108 	TDriveInfo drv;
       
   109 	r = TheFs.Drive(drv, aDrive);
       
   110 	test(r == KErrNone);
       
   111 
       
   112 	gNoMedia = (drv.iType == EMediaUnknown || drv.iType == EMediaNotPresent);
       
   113 
       
   114 	if (gOldFsName.Length() > 0)
       
   115 		{
       
   116 		TTest::Printf(_L("Dismount %C: %S"), (TUint)c, &gOldFsName);
       
   117 		r=TheFs.DismountFileSystem(gOldFsName,aDrive);
       
   118 		test(r==KErrNone);
       
   119 		}
       
   120 
       
   121 	r=TheFs.MountFileSystem(KFsName,aDrive);
       
   122 	test(r==KErrNone);
       
   123 
       
   124 	r=TheFs.FileSystemName(gNewFsName,aDrive);
       
   125 	test(r==KErrNone);
       
   126 	test(gNewFsName.CompareF(KFsName)==0);
       
   127 	return c;
       
   128 	}
       
   129 
       
   130 LOCAL_C void UnmountFileSystem(TInt aDrive)
       
   131 /// Unmount a test filesystem and mount the old one.
       
   132 	{
       
   133 	TChar c;
       
   134 	TInt r=TheFs.DriveToChar(aDrive,c);
       
   135 	test(r==KErrNone);
       
   136 	r=TheFs.DismountFileSystem(gNewFsName,aDrive);
       
   137 	test(r==KErrNone);
       
   138 	// if there's no media present, don't try to mount it
       
   139 	if (gNoMedia)
       
   140 		{
       
   141 		test.Printf(_L("No media on %C: so don't remount it"), (TUint)c);
       
   142 		}
       
   143 	else if (gOldFsName.Length() > 0)
       
   144 		{
       
   145 		test.Printf(_L("Mount    %C: %S"), (TUint)c, &gOldFsName);
       
   146 		r=TheFs.MountFileSystem(gOldFsName,aDrive);
       
   147 		test(r==KErrNone);
       
   148 		}
       
   149 	if (r != KErrNone)
       
   150 		test.Printf(_L("Error %d remounting %S on %C\n"), r, &gOldFsName, (TUint)c);
       
   151 	}
       
   152 
       
   153 LOCAL_C void RemountFileSystem(TInt aDrive, TBool aSync)
       
   154 /// Unmount and remount the file system on the specified drive in the
       
   155 /// selected mode.
       
   156 /// @param aDrive Drive number (EDriveC etc.).
       
   157 /// @param aSync  Mount synchronous if true, asynchronous if not.
       
   158 	{
       
   159 	TChar c;
       
   160 	TInt r=TheFs.DriveToChar(aDrive,c);
       
   161 	r=TheFs.FileSystemName(gFsName, aDrive);
       
   162 	test(r==KErrNone || r==KErrNotFound);
       
   163 
       
   164 	if (gFsName.Length() > 0)
       
   165 		{
       
   166 		r=TheFs.DismountFileSystem(gFsName, aDrive);
       
   167 		if(r!=KErrNone)
       
   168 			{
       
   169 			test.Printf(_L("Error = %d"),r);
       
   170 			test(EFalse);
       
   171 			}
       
   172 		}
       
   173 
       
   174 	TBufC<16> type = _L("asynchronous");
       
   175 	if (aSync)
       
   176 		type = _L("synchronous");
       
   177 	if (gVerbose)
       
   178 		test.Printf(_L("Mount filesystem %c: %-8S as %S\n"), (TUint)c, &gFsName, &type);
       
   179 
       
   180 #ifdef __CONCURRENT_FILE_ACCESS__
       
   181 	r=TheFs.MountFileSystem(gFsName, aDrive, aSync);
       
   182 #else
       
   183 	r=TheFs.MountFileSystem(gFsName, aDrive);
       
   184 #endif
       
   185 
       
   186 	test(r==KErrNone);
       
   187 	}
       
   188 
       
   189 enum TOper
       
   190 	{
       
   191 	ERead,
       
   192 	EWrite
       
   193 	};
       
   194 
       
   195 
       
   196 // ---------------------------------------------------------------------------
       
   197 
       
   198 class RFileOps
       
   199 /// Do operations on a file.
       
   200 	{
       
   201 public:
       
   202 	RFileOps();
       
   203 
       
   204 	enum TOper
       
   205 	{
       
   206 	ERead,
       
   207 	EWrite
       
   208 	};
       
   209 	
       
   210 	
       
   211 	TInt Init(TChar dr, TInt aBufSize);
       
   212 	void DeInit();
       
   213 	void CalculateFreeSpace();
       
   214 
       
   215 	TInt Open(TOper aOper);
       
   216 	TInt Close();
       
   217 	TInt Delete();
       
   218 	TInt Reset();
       
   219 	TInt Erase();
       
   220 	TInt Write();
       
   221 	TInt Read();
       
   222 	TInt End();
       
   223 	TInt CreateReadFile();
       
   224 
       
   225 public:
       
   226 	TFileName      iNameRead;
       
   227 	TFileName      iNameWrite;
       
   228 	RFile          iF;
       
   229 
       
   230 	HBufC8* iBuffer[KMaxLag];
       
   231 	TPtr8* iBufPtr[KMaxLag];
       
   232 
       
   233 	TRequestStatus iStatus[KMaxLag];
       
   234 	TInt iPtr;
       
   235 	TInt iNum;
       
   236 	TInt iOps;
       
   237 	TInt iMax;
       
   238 	TBool iOpen;
       
   239 	TInt iBufSize;
       
   240 	TChar iDrvCh;
       
   241 	TInt64 iFree;
       
   242 	TInt iFileSize;
       
   243 	// counters
       
   244 	TInt iFileWraps;
       
   245 	TInt iFileSyncAccesses;
       
   246 	TInt iFileAsyncAccesses;
       
   247 	};
       
   248 
       
   249 RFileOps::RFileOps() : iPtr(0), iNum(0), iOps(0), iMax(0), iOpen(EFalse)
       
   250 	{
       
   251 	for (TInt i = 0; i < KMaxLag; i++)
       
   252 		{
       
   253 		iStatus[i] = KErrNone;
       
   254 		iBuffer[i] = NULL;
       
   255 		iBufPtr[i] = NULL;
       
   256 		}
       
   257 
       
   258 	}
       
   259 
       
   260 TInt RFileOps::Init(TChar aDrvCh, TInt aBufSize)
       
   261 	{
       
   262 	TInt r = KErrNone;
       
   263 
       
   264 	test(!iOpen);
       
   265 
       
   266 	iDrvCh = aDrvCh;
       
   267 	iBufSize = aBufSize;
       
   268 	iNameWrite.Format(_L("%c:\\TESTWT"), (TUint)aDrvCh);
       
   269 	iNameRead.Format(_L("%c:\\TESTRD"), (TUint)aDrvCh);
       
   270 	
       
   271 	for (TInt i = 0; i < KMaxLag; i++)
       
   272 		{
       
   273 		iStatus[i] = KErrNone;
       
   274 
       
   275 		iBuffer[i] = HBufC8::NewL(aBufSize);
       
   276 		if (iBuffer[i] == NULL)
       
   277 			return KErrNoMemory;
       
   278 		iBufPtr[i] = new TPtr8(iBuffer[i]->Des());
       
   279 		//TPtr8 buffer(iBuffer[i]->Des());
       
   280 		//buffer.Fill(TChar('_'), aBufSize);
       
   281 		iBufPtr[i]->Fill(TChar('_'), aBufSize);
       
   282 		}
       
   283 
       
   284 	return r;
       
   285 	}
       
   286 
       
   287 void RFileOps::DeInit()
       
   288 	{
       
   289 	test(!iOpen);
       
   290 
       
   291 	for (TInt i = 0; i < KMaxLag; i++)
       
   292 		{
       
   293 		delete iBuffer[i];
       
   294 		iBuffer[i] = NULL;
       
   295 		delete iBufPtr[i];
       
   296 		iBufPtr[i] = NULL;
       
   297 		}
       
   298 
       
   299 	}
       
   300 
       
   301 void RFileOps::CalculateFreeSpace()
       
   302 	{
       
   303 	TVolumeInfo vol;
       
   304 	TInt        drv;
       
   305 	
       
   306 	
       
   307 	TInt r = TheFs.CharToDrive(iDrvCh, drv);
       
   308 	if (r != KErrNone)
       
   309 		TTest::Fail(HERE, _L("CharToDrive(%c) returned %d"), (TUint)iDrvCh, r);
       
   310 
       
   311 	r = TheFs.Volume(vol, drv);
       
   312 	if (r != KErrNone)
       
   313 		TTest::Fail(HERE, _L("Volume(%c:) returned %d"), (TUint)iDrvCh, r);
       
   314 
       
   315 	iFree = vol.iFree;
       
   316 
       
   317 	TInt64 fileSize = iFree / 2;
       
   318 	if (fileSize > KMaxFileSize)
       
   319 		fileSize = KMaxFileSize;
       
   320 	iFileSize = I64LOW(fileSize);
       
   321 
       
   322 
       
   323 	// calculate the number of buffers to use
       
   324 	// if we assume we'll be able to use half the available disk space
       
   325 	TInt max = iFileSize / iBufSize;
       
   326 	iMax = max;
       
   327 
       
   328     if (gVerbose)
       
   329 		{
       
   330 		test.Printf(_L("Free space on drive %c = %d KB\n"), (TUint)iDrvCh, I64LOW(iFree/1024));
       
   331 		test.Printf(_L("File Size = %d KB. Using %d buffers of size %d\n"), iFileSize/1024, iMax, iBufSize);
       
   332 		}
       
   333 
       
   334 	}
       
   335 
       
   336 
       
   337 TInt RFileOps::Open(TOper aOper)
       
   338 /// Open the file for testing, give error if there is not enough space for it.
       
   339 	{
       
   340 	TInt r;
       
   341 
       
   342 	test(!iOpen);
       
   343 
       
   344 
       
   345 	// reset counters
       
   346 	iFileWraps = 0;
       
   347 	iFileSyncAccesses = 0;
       
   348 	iFileAsyncAccesses = 0;
       
   349 	
       
   350 	TheFs.Delete(iNameWrite);
       
   351 
       
   352 	if (aOper == ERead)
       
   353 		{
       
   354 		r = iF.Open(TheFs, iNameRead, EFileStreamText | EFileRead);
       
   355 		if (r != KErrNone)
       
   356 			return r;
       
   357 
       
   358 		TInt sizeFile = 0;
       
   359 		r = iF.Size(sizeFile);
       
   360 		test(r == KErrNone);
       
   361         if (gVerbose)
       
   362 			{
       
   363 			test.Printf(_L("File Size = %d, %d buffers of size %d\n"), sizeFile, iMax, iBufSize);
       
   364 			}
       
   365 		iMax = sizeFile / iBufSize;
       
   366 		}
       
   367 	else
       
   368 		{
       
   369 		CalculateFreeSpace();
       
   370 
       
   371 		if (iMax < KMaxLag)
       
   372 			{
       
   373 			test.Printf(_L("Insufficient free space on drive %c, deleting read file\n"), (TUint)iDrvCh);
       
   374 			TInt maxOld = iMax;
       
   375 			TheFs.Delete(iNameRead);
       
   376 			CalculateFreeSpace();
       
   377 			test.Printf(_L("Old available buffers = %d, new available buffers = %d\n"), maxOld, iMax);
       
   378 			}
       
   379 			if (iMax < KMaxLag)
       
   380 				TTest::Fail(HERE, _L("Not enough space to do test, only %d KB available. Only %d buffers of %d bytes available"),
       
   381 												  I64LOW(iFree/1024), iMax, iBufSize );
       
   382 
       
   383 		r = iF.Replace(TheFs, iNameWrite, EFileStreamText | EFileWrite);
       
   384 		}
       
   385 
       
   386 	if (r == KErrNone)
       
   387 		iOpen = ETrue;
       
   388 
       
   389 	
       
   390 	Reset();
       
   391 
       
   392 	return r;
       
   393 	}
       
   394 
       
   395 // Close and delete the file, returning the number of operations done.
       
   396 TInt RFileOps::Close()
       
   397 	{
       
   398 	if (!iOpen)
       
   399 		return 0;
       
   400 
       
   401 	iF.Close();
       
   402 	iOpen = EFalse;
       
   403 
       
   404 	// always delete the write file
       
   405 	TheFs.Delete(iNameWrite);
       
   406 	
       
   407 	
       
   408 	return iNum;
       
   409 	}
       
   410 
       
   411 TInt RFileOps::Delete()
       
   412 	{
       
   413 	TInt r = TheFs.Delete(iNameRead);
       
   414 	r = TheFs.Delete(iNameWrite);
       
   415 	return r;
       
   416 	}
       
   417 
       
   418 
       
   419 TInt RFileOps::Reset()
       
   420 /// Reset all of the counts.
       
   421 	{
       
   422 	TInt err = KErrNone;
       
   423 
       
   424 	iPtr = 0;
       
   425 	iNum = 0;
       
   426 	iOps = 0;
       
   427 	return err;
       
   428 	}
       
   429 
       
   430 TInt RFileOps::CreateReadFile()
       
   431 	{
       
   432 	TInt r = KErrNone;
       
   433 
       
   434 	CalculateFreeSpace();	// get iMax
       
   435 
       
   436 	if (iOpen)
       
   437 		iF.Close();
       
   438 	iOpen = EFalse;
       
   439 
       
   440 
       
   441 	r = iF.Open(TheFs, iNameRead, EFileStreamText | EFileRead);
       
   442 	if (r == KErrNone)
       
   443 		{
       
   444 		if (gVerbose)
       
   445 			test.Printf(_L("temp file already exists.\n"));
       
   446 		iF.Close();
       
   447 
       
   448 		return r;
       
   449 		}
       
   450 
       
   451 
       
   452 	r = iF.Replace(TheFs, iNameRead, EFileStreamText | EFileWrite);
       
   453 	if (r != KErrNone)
       
   454 		return r;
       
   455 	
       
   456 	iOpen = ETrue;
       
   457 	
       
   458 	Reset();
       
   459 
       
   460 
       
   461 	test.Printf(_L("Creating temp file on drive %c of size %d..."), (TUint)iDrvCh, iFileSize);
       
   462 
       
   463 	HBufC8* buf = HBufC8::NewL(KMaxBufferSize);
       
   464 	TPtr8 bufptr(buf->Des());
       
   465 	bufptr.Fill(TChar('_'), KMaxBufferSize);
       
   466 
       
   467 	test(buf != NULL);
       
   468 	for (TInt pos=0; pos<iFileSize; pos+= buf->Length())
       
   469 		{
       
   470 		r = iF.Write(pos, bufptr);
       
   471 		if (r != KErrNone)
       
   472 			test.Printf(_L("Write() returned %d\n"), r);
       
   473 
       
   474 		test(r == KErrNone);
       
   475 		}
       
   476 	delete buf; buf = NULL;
       
   477 
       
   478 	//	if (gVerbose)
       
   479 		test.Printf(_L("Done.\n"));
       
   480 
       
   481 	iF.Close();
       
   482 	iOpen = EFalse;
       
   483 
       
   484 	return r;
       
   485 	}
       
   486 
       
   487 TInt RFileOps::Write()
       
   488 /// If there is a free buffer available, start a write.
       
   489 	{
       
   490 	if (!iOpen)
       
   491 		return 0;
       
   492 
       
   493 	while (iNum < iOps && iStatus[iNum%KMaxLag] != KRequestPending)
       
   494 		{
       
   495 		TInt status = iStatus[iNum%KMaxLag].Int();
       
   496 		test (status == KErrNone);
       
   497 		iNum++;
       
   498 		}
       
   499 	
       
   500 	if (iOps < KMaxLag || iStatus[iPtr] != KRequestPending)
       
   501 		{
       
   502 		TInt pos = iOps%iMax * iBufSize;
       
   503 
       
   504 		iF.Write(pos, *iBufPtr[iPtr], iStatus[iPtr]);
       
   505 
       
   506 		TInt status = iStatus[iPtr].Int();
       
   507 
       
   508         if (gVerbose)
       
   509 			{
       
   510 			test.Printf(_L("Writing buf #%d to drive %c at pos %d, status = %d\n"), 
       
   511 				iPtr, (TUint)iDrvCh, pos, status);
       
   512 			}
       
   513 		test (status == KErrNone || status == KRequestPending);
       
   514 
       
   515 		iOps++;
       
   516 		iPtr++;
       
   517 		iPtr %= KMaxLag;
       
   518 		return 1;
       
   519 		}
       
   520 	return 0;
       
   521 	}
       
   522 
       
   523 TInt RFileOps::Read()
       
   524 /// If there is a free buffer available, start a read.
       
   525 	{
       
   526 	if (!iOpen)
       
   527 		return 0;
       
   528 
       
   529 	while (iNum < iOps && iStatus[iNum%KMaxLag] != KRequestPending)
       
   530 		{
       
   531 		TInt status = iStatus[iNum%KMaxLag].Int();
       
   532 		if (status != KErrNone)
       
   533 			test.Printf(_L("drive %c, iNum = %d, iOps=%d, Status = %d\n"), (TUint)iDrvCh, iNum, iOps, status);
       
   534 		test (status == KErrNone);
       
   535 
       
   536 		iNum++;
       
   537 		}
       
   538 	if (iOps < KMaxLag || iStatus[iPtr] != KRequestPending)
       
   539 		{
       
   540 		TInt pos = iOps%iMax * iBufSize;
       
   541 
       
   542 		iBufPtr[iPtr]->SetLength(0);
       
   543 
       
   544 		iF.Read(pos, *iBufPtr[iPtr], iStatus[iPtr]);
       
   545 
       
   546 		TInt len = iBufPtr[iPtr]->Length();
       
   547 		TInt status = iStatus[iPtr].Int();
       
   548 		
       
   549 		TInt err = KErrNone;
       
   550 
       
   551 		if (status == KErrNone)
       
   552 			{
       
   553 			iFileSyncAccesses++;
       
   554 			if (len < iBufPtr[iPtr]->MaxLength())
       
   555 				err = KErrUnderflow;
       
   556 			}
       
   557 		else if (status == KRequestPending)
       
   558 			{
       
   559 			iFileAsyncAccesses++;
       
   560 			}
       
   561 		else
       
   562 			{
       
   563 			err = status;
       
   564 			}
       
   565 
       
   566 		if (gVerbose || err != KErrNone)
       
   567 			{
       
   568 			test.Printf(_L("Reading buf #%d, drive %c, pos %d, status %d, len %d, iNum %d, iOps %d, iMax %d\n"), 
       
   569 				iPtr, (TUint)iDrvCh, pos, status, len, iNum, iOps, iMax);
       
   570 			}
       
   571 
       
   572 		test (err == KErrNone);
       
   573 
       
   574 		iOps++;
       
   575 		iPtr++;
       
   576 		iPtr %= KMaxLag;
       
   577 
       
   578 		// have we wrapped to postion zero ?
       
   579 		if (iOps % iMax == 0)
       
   580 			iFileWraps++;
       
   581 
       
   582 		return 1;
       
   583 		}
       
   584 	return 0;
       
   585 	}
       
   586 
       
   587 
       
   588 TInt RFileOps::End()
       
   589 /// Wait until all outstanding operations have ended, then return the number.
       
   590 	{
       
   591 	if (!iOpen)
       
   592 		return 0;
       
   593 
       
   594 	if (gVerbose)
       
   595 		test.Printf(_L("Waiting for reads/writes to %c to complete, iNum=%d, iOps=%d...\n"), (TUint)iDrvCh, iNum, iOps);
       
   596 	
       
   597 	while (iNum < iOps)
       
   598 		{
       
   599 		if (iStatus[iNum%KMaxLag] == KRequestPending)
       
   600 			{
       
   601 			User::WaitForRequest(iStatus[iNum%KMaxLag]);
       
   602 			}
       
   603 		else
       
   604 			{
       
   605 			TInt status = iStatus[iNum%KMaxLag].Int();
       
   606 			if (gVerbose || (status != KErrNone && status != KRequestPending))
       
   607 				test.Printf(_L("Buf#%d: Status = %d\n"), iNum, status);
       
   608 			test (status == KErrNone || status == KRequestPending);
       
   609 			iNum++;
       
   610 			}
       
   611 		}
       
   612 
       
   613 	return iNum;
       
   614 	}
       
   615 
       
   616 LOCAL_C TInt testAsyncAccess(
       
   617 	TInt aDrive1,
       
   618 	TInt aDrive2, 
       
   619 	TInt aBufSize1, 
       
   620 	TInt aBufSize2, 
       
   621 	TBool aSync1, 
       
   622 	TBool aSync2,
       
   623 	TInt& aThroughput1,
       
   624 	TInt& aThroughput2)
       
   625 //
       
   626 // Test one drive against the other.
       
   627 //
       
   628     {
       
   629 	TInt r;
       
   630 
       
   631 	RFileOps f1;
       
   632 	RFileOps f2;
       
   633 
       
   634 	TChar dc1;
       
   635 	TChar dc2;
       
   636 
       
   637 	TInt   op1 = 0;
       
   638 	TInt   op2 = 0;
       
   639 	RTimer timer;
       
   640 	TRequestStatus tstat;
       
   641 	TTime startTime;
       
   642 	TTime endTime;
       
   643 	TTimeIntervalMicroSeconds timeTaken(0);
       
   644 	TInt64 dtime;
       
   645 
       
   646 	aThroughput1 = aThroughput2 = 0;
       
   647 
       
   648 	if (aBufSize1 == 0 && aBufSize2 == 0)
       
   649 		return KErrNone;
       
   650 
       
   651 	timer.CreateLocal();
       
   652 
       
   653 
       
   654 	r = TheFs.DriveToChar(aDrive1, dc1);
       
   655 	test(r == KErrNone);
       
   656 	r = TheFs.DriveToChar(aDrive2, dc2);
       
   657 	test(r == KErrNone);
       
   658 
       
   659 	// allocate buffers
       
   660 	r = f1.Init(dc1, aBufSize1);
       
   661 		test(r == KErrNone);
       
   662 	r = f2.Init(dc2, aBufSize2);
       
   663 	test(r == KErrNone);
       
   664 
       
   665 	
       
   666 	_LIT(KSync, " sync");
       
   667 	_LIT(KAsync, "async");
       
   668 	if (gVerbose)
       
   669 		test.Printf(_L("%c: (%S) %d, %c: (%S) %d\n"), 
       
   670 			(TUint)dc1, 
       
   671 			aSync1?&KSync:&KAsync,
       
   672 			aBufSize1, 
       
   673 			(TUint)dc2, 
       
   674 			aSync2?&KSync:&KAsync,
       
   675 			aBufSize2);
       
   676 
       
   677 	RemountFileSystem(aDrive1, aSync1);
       
   678 	RemountFileSystem(aDrive2, aSync2);
       
   679 
       
   680 	if (gReadTests)
       
   681 		{
       
   682 		//********************************************************************
       
   683 		// read test
       
   684 		//********************************************************************
       
   685 
       
   686 		if (aBufSize1 > 0)
       
   687 			{
       
   688 			r = f1.CreateReadFile();
       
   689 			test(r == KErrNone);
       
   690 			}
       
   691 		if (aBufSize2 > 0)
       
   692 			{
       
   693 			r = f2.CreateReadFile();
       
   694 			test(r == KErrNone);
       
   695 			}
       
   696 
       
   697 		if (aBufSize1 > 0)
       
   698 			r = f1.Open(RFileOps::ERead);
       
   699 		test(r == KErrNone);
       
   700 		
       
   701 		if (aBufSize2 > 0)
       
   702 			r = f2.Open(RFileOps::ERead);
       
   703 		test(r == KErrNone);
       
   704 
       
   705 
       
   706 		timer.After(tstat, KTimeBM * KSecond);
       
   707 
       
   708 		startTime.HomeTime();
       
   709 
       
   710 		while (tstat == KRequestPending)
       
   711 			{
       
   712 			TInt num = 0;
       
   713 			if (aBufSize1 > 0)
       
   714 				num = f1.Read();
       
   715 			if (aBufSize2 > 0)
       
   716 				num += f2.Read();
       
   717 			if (num == 0)
       
   718 				User::WaitForAnyRequest();
       
   719 			}
       
   720 		timer.Cancel();	
       
   721 
       
   722 		if (aBufSize1 > 0)
       
   723 			op1 = f1.End();
       
   724 		if (aBufSize2 > 0)
       
   725 			op2 = f2.End();
       
   726 
       
   727 		endTime.HomeTime();
       
   728 		timeTaken=endTime.MicroSecondsFrom(startTime);
       
   729 
       
   730 		//********************************************************************
       
   731 		// Read test end
       
   732 		//********************************************************************
       
   733 		}	// if (gReadTests)
       
   734 		
       
   735 	if (gWriteTests)
       
   736 		{
       
   737 		//********************************************************************
       
   738 		// write test
       
   739 		//********************************************************************
       
   740 		if (aBufSize1 > 0)
       
   741 			{
       
   742 			r = f1.Open(RFileOps::EWrite);
       
   743 			test(r == KErrNone);
       
   744 			}
       
   745 	
       
   746 		if (aBufSize2 > 0)
       
   747 			{
       
   748 			r = f2.Open(RFileOps::EWrite);
       
   749 			test(r == KErrNone);
       
   750 			}
       
   751 
       
   752 		timer.After(tstat, KTimeBM * KSecond);
       
   753 
       
   754 		startTime.HomeTime();
       
   755 
       
   756 		while (tstat == KRequestPending)
       
   757 			{
       
   758 			TInt num = 0;
       
   759 			if (aBufSize1 > 0)
       
   760 				num = f1.Write();
       
   761 			if (aBufSize2 > 0)
       
   762 				num += f2.Write();
       
   763 			if (num == 0)
       
   764 				User::WaitForAnyRequest();
       
   765 			}
       
   766 		timer.Cancel();
       
   767 
       
   768 		if (aBufSize1 > 0)
       
   769 			op1 = f1.End();
       
   770 		if (aBufSize2 > 0)
       
   771 			op2 = f2.End();
       
   772 
       
   773 
       
   774 		endTime.HomeTime();
       
   775 		timeTaken=endTime.MicroSecondsFrom(startTime);
       
   776 
       
   777 		//********************************************************************
       
   778 		// Write test end
       
   779 		//********************************************************************
       
   780 
       
   781 		}	// if gWriteTests
       
   782 
       
   783 	dtime = timeTaken.Int64();
       
   784 
       
   785 	aThroughput1 = GetSpeed(op1, aBufSize1, dtime);
       
   786 	aThroughput2 = GetSpeed(op2, aBufSize2, dtime);
       
   787 
       
   788 	test.Printf(_L("%c:,%c:,%10d,%10d,%10d,%10d\n"), 
       
   789 		(TUint)dc1, (TUint)dc2, 
       
   790 		aBufSize1,aBufSize2,
       
   791 		aThroughput1,
       
   792 		aThroughput2
       
   793 		);
       
   794 
       
   795 	
       
   796 	if (gVerbose)
       
   797 		{
       
   798 		test.Printf(_L("%c: %d async reads, %d sync reads, wraps = %d\n"), 
       
   799 			(TUint)dc1, f1.iFileAsyncAccesses, f1.iFileSyncAccesses, f1.iFileWraps);
       
   800 		test.Printf(_L("%c: %d async reads, %d sync reads, wraps = %d\n"), 
       
   801 			(TUint)dc2, f2.iFileAsyncAccesses, f2.iFileSyncAccesses, f2.iFileWraps);
       
   802 		}
       
   803 
       
   804 
       
   805 	f1.Close();
       
   806 	f2.Close();
       
   807 
       
   808 
       
   809 	timer.Close();
       
   810 
       
   811 	f1.DeInit();
       
   812 	f2.DeInit();
       
   813 
       
   814 	return KErrNone;
       
   815     }
       
   816 
       
   817 LOCAL_C TInt parseCmd(TChar& aDrvCh1, TChar& aDrvCh2)
       
   818 /// Get parameters from the comand line; if there aren't enough then
       
   819 /// prompt the user for them and return KErrAbort if ^C is pressed.
       
   820 	{
       
   821 	while (aDrvCh1 < 'A' || aDrvCh1 > 'Z')
       
   822 		{
       
   823 		test.Printf(_L("Enter drive letter: "));
       
   824 		while (aDrvCh1 < 'A' || aDrvCh1 > 'Z')
       
   825 			{
       
   826 			if (aDrvCh1 == 0x03)
       
   827 				return KErrAbort;
       
   828 			aDrvCh1 = User::UpperCase(test.Getch());
       
   829 			}
       
   830 		if (!DriveIsOK(aDrvCh1))
       
   831 			{
       
   832 			test.Printf(_L("%c: is not a valid drive\n"), (TUint)aDrvCh1);
       
   833 			aDrvCh1 = 0;
       
   834 			}
       
   835 		else
       
   836 			{
       
   837 			TInt drv;
       
   838 			TheFs.CharToDrive(aDrvCh1, drv);
       
   839 			TheFs.FileSystemName(gFsName1, drv);
       
   840 			test.Printf(_L("%c: (%S)\n"), (TUint)aDrvCh1, &gFsName1);
       
   841 			}
       
   842 		}
       
   843 
       
   844 	while (aDrvCh2 < 'A' || aDrvCh2 > 'Z')
       
   845 		{
       
   846 		test.Printf(_L("Enter drive letter: "));
       
   847 		while (aDrvCh2 < 'A' || aDrvCh2 > 'Z')
       
   848 			{
       
   849 			if (aDrvCh2 == 0x03)
       
   850 				return KErrAbort;
       
   851 			aDrvCh2 = User::UpperCase(test.Getch());
       
   852 			}
       
   853 		if (!DriveIsOK(aDrvCh2))
       
   854 			{
       
   855 			test.Printf(_L("%c: is not a valid drive\n"), (TUint)aDrvCh2);
       
   856 			aDrvCh2 = 0;
       
   857 			}
       
   858 		else
       
   859 			{
       
   860 			TInt drv;
       
   861 			TheFs.CharToDrive(aDrvCh2, drv);
       
   862 			TheFs.FileSystemName(gFsName2, drv);
       
   863 			test.Printf(_L("%c: (%S)\n"), (TUint)aDrvCh2, &gFsName2);
       
   864 			}
       
   865 		}
       
   866 	return KErrNone;
       
   867 	}
       
   868 
       
   869 
       
   870 typedef TInt RESULTS[KMaxIter][KMaxIter]; 
       
   871 LOCAL_C void PrintResults(RESULTS& aResults, TChar aDrvCh, TChar aDrvCh2)
       
   872 	{
       
   873 	TInt bufSize2;
       
   874 	TInt drive1Index, drive2Index;
       
   875 
       
   876 	test.Printf(_L("*** Throughput for drive %c ***\n"), (TUint)aDrvCh);
       
   877 
       
   878 	test.Printf(_L("         BufferSize (%C:)....\n"), (TUint)aDrvCh2);
       
   879 	gResults.Zero();
       
   880 	for (bufSize2 = drive2Index = 0; bufSize2 <= KMaxBufferSize; bufSize2 = bufSize2 << 1, drive2Index++)
       
   881 		{
       
   882 		gResults.AppendFormat(_L("%10d,"), bufSize2);
       
   883 		if (bufSize2 == 0)
       
   884 			bufSize2 = KMinBufferSize >> 1;
       
   885 		}
       
   886 	test.Printf(_L("%S\n"), &gResults);
       
   887 	
       
   888 	for (drive1Index = 0; drive1Index < KMaxIter; drive1Index++)
       
   889 		{
       
   890 		gResults.Zero();
       
   891 		for (drive2Index = 0; drive2Index < KMaxIter; drive2Index++)
       
   892 			{
       
   893 			gResults.AppendFormat(_L("%10d,"), aResults[drive1Index][drive2Index]);
       
   894 			}
       
   895 		test.Printf(_L("%S\n"), &gResults);
       
   896 		}
       
   897 
       
   898 	}
       
   899 
       
   900 
       
   901 //
       
   902 // Do all tests
       
   903 //
       
   904 GLDEF_C void CallTestsL()
       
   905 	{
       
   906 	TInt r = TTest::Init();
       
   907 	test(r == KErrNone);
       
   908 
       
   909 	TChar drvch1 = 0;
       
   910 	TChar drvch2 = 0;
       
   911 	TInt  drive1;
       
   912 	TInt  drive2;
       
   913 
       
   914 	const TInt KMaxArgs = 5;
       
   915 	TPtrC argv[KMaxArgs];
       
   916 	TInt  argc = TTest::ParseCommandArguments(argv, KMaxArgs);
       
   917 	if (argc > 1)
       
   918 		drvch1 = User::UpperCase(argv[1][0]);
       
   919 	if (argc > 2)
       
   920 		drvch2 = User::UpperCase(argv[2][0]);
       
   921 
       
   922 	TBool testFs = EFalse;
       
   923 
       
   924 	for (TInt n=3; n<argc; n++)
       
   925 		{
       
   926 		if (argc > 3)
       
   927 			{
       
   928 			if (argv[n].Compare(_L("verbose")) == 0)
       
   929 				gVerbose = ETrue;
       
   930 			if (argv[n].Compare(_L("read")) == 0)
       
   931 				gReadTests = ETrue;
       
   932 			if (argv[n].Compare(_L("write")) == 0)
       
   933 				gWriteTests = ETrue;
       
   934 
       
   935 			if (argv[n].Compare(_L("async")) == 0)
       
   936 				gAsyncTests = ETrue;
       
   937 			if (argv[n].Compare(_L("sync")) == 0)
       
   938 				gSyncTests = ETrue;
       
   939 
       
   940 			if (argv[n].Compare(_L("testfs")) == 0)
       
   941 				testFs = ETrue;
       
   942 			}
       
   943 		}
       
   944 
       
   945 	if ((!gReadTests && !gWriteTests) ||
       
   946 		(!gAsyncTests && !gSyncTests))
       
   947 		{
       
   948 	    test.Printf(_L("T_CFSPERFORM - tests read/write throughput on two drives simultaneously\n"));
       
   949 	    test.Printf(_L("Syntax : t_cfsperform <Drive1> <Drive2> [verbose] [testfs] read|write sync|async\n"));
       
   950 	    test.Printf(_L("Where  : async = concurrent access, sync = non-concurrent access\n"));
       
   951 	    test.Printf(_L("E.g.   : t_cfsperform c d read async\n"));
       
   952 	    test.Printf(_L("Press any key"));
       
   953 		test.Getch();	
       
   954 		test.Printf(_L("\n"));
       
   955 		return;
       
   956 		}
       
   957 
       
   958 
       
   959 	r = parseCmd(drvch1, drvch2);
       
   960 	if (r != KErrNone)
       
   961 		{
       
   962 		User::Panic(_L("USER ABORT"), 0);
       
   963 		}
       
   964 
       
   965 	r = TheFs.CharToDrive(drvch1, drive1);
       
   966 	test(r == KErrNone);
       
   967 	r = TheFs.CharToDrive(drvch2, drive2);
       
   968 	test(r == KErrNone);
       
   969 	
       
   970 	r = TheFs.FileSystemName(gFsName1, drive1);
       
   971 	test(r == KErrNone || r == KErrNotFound);
       
   972 	r = TheFs.FileSystemName(gFsName2, drive2);
       
   973 	test(r == KErrNone || r == KErrNotFound);
       
   974 
       
   975 	if (testFs)
       
   976 		{
       
   977 		MountTestFileSystem(drive1);
       
   978 		MountTestFileSystem(drive2);
       
   979 		}
       
   980 
       
   981 
       
   982 	TInt bufSize1;
       
   983 	TInt bufSize2;
       
   984 
       
   985 	// delete temp files before starting
       
   986 	RFileOps f;
       
   987 	f.Init(drvch1, 256);
       
   988 	f.Delete();
       
   989 	f.DeInit();
       
   990 	f.Init(drvch2, 256);
       
   991 	f.Delete();
       
   992 	f.DeInit();
       
   993 
       
   994 
       
   995 	TInt resultsDrive1[KMaxIter][KMaxIter];
       
   996 	TInt resultsDrive2[KMaxIter][KMaxIter];
       
   997 	TInt drive1Index;
       
   998 	TInt drive2Index;
       
   999 
       
  1000 	test.Printf(_L("      BufSize(%c) BufSize(%c) ThruPut(%c) ThruPut(%c) \n"),
       
  1001 				(TUint)drvch1, (TUint)drvch2, (TUint)drvch1, (TUint)drvch2);
       
  1002 
       
  1003 	for (bufSize1 = drive1Index = 0; bufSize1 <= KMaxBufferSize; bufSize1 = bufSize1 << 1, drive1Index++)
       
  1004 		{
       
  1005 		for (bufSize2 = drive2Index = 0; bufSize2 <= KMaxBufferSize; bufSize2 = bufSize2 << 1, drive2Index++)
       
  1006 			{
       
  1007 
       
  1008 //			// !!! Disable platform security tests until we get the new APIs
       
  1009 //			if (User::Capability() & KCapabilityRoot)
       
  1010 //				{
       
  1011 //				CheckMountLFFS(TheFs, drvch1);
       
  1012 //				CheckMountLFFS(TheFs, drvch2);
       
  1013 //				}
       
  1014 
       
  1015 			if (gVerbose)
       
  1016 				test.Printf(_L("Using drives %c: (%S) and %c: (%S)\n"),
       
  1017 							(TUint)drvch1, &gFsName1, (TUint)drvch2, &gFsName2);
       
  1018 
       
  1019 			TInt throughputDrive1;
       
  1020 			TInt throughputDrive2;
       
  1021 			TBool sync = EFalse;
       
  1022 			if (gSyncTests)
       
  1023 				sync = ETrue;
       
  1024 
       
  1025 			testAsyncAccess(
       
  1026 				drive1, drive2, 
       
  1027 				bufSize1, bufSize2, 
       
  1028 				sync, sync, 
       
  1029 				throughputDrive1, throughputDrive2);
       
  1030 
       
  1031 			resultsDrive1[drive1Index][drive2Index] = throughputDrive1;
       
  1032 			resultsDrive2[drive1Index][drive2Index] = throughputDrive2;
       
  1033 
       
  1034 			// buffer size sequence is 0,16,32,64,128, ...
       
  1035 			if (bufSize2 == 0)
       
  1036 				bufSize2 = KMinBufferSize >> 1;
       
  1037 			}
       
  1038 		// buffer size sequence is 0,16,32,64,128, ...
       
  1039 		if (bufSize1 == 0)
       
  1040 			bufSize1 = KMinBufferSize >> 1;
       
  1041 		}
       
  1042 
       
  1043 
       
  1044 
       
  1045 	PrintResults(resultsDrive1, drvch1, drvch2);
       
  1046 	PrintResults(resultsDrive2, drvch2, drvch2);
       
  1047 
       
  1048 
       
  1049 	if (testFs)
       
  1050 		{
       
  1051 		UnmountFileSystem(drive1);
       
  1052 		UnmountFileSystem(drive2);
       
  1053 		}
       
  1054 	test(r == 0);
       
  1055 	}
       
  1056 
       
  1057 
       
  1058 GLDEF_C TInt E32Main()
       
  1059 // 
       
  1060 // Main entry point
       
  1061 //
       
  1062     {
       
  1063 	TInt r;
       
  1064     CTrapCleanup* cleanup;
       
  1065     cleanup=CTrapCleanup::New();
       
  1066     __UHEAP_MARK;
       
  1067 
       
  1068     test.Title();
       
  1069     test.Start(_L("Starting tests..."));
       
  1070 
       
  1071     r=TheFs.Connect();
       
  1072     test(r==KErrNone);
       
  1073 
       
  1074     // TheFs.SetAllocFailure(gAllocFailOn);
       
  1075     TTime timerC;
       
  1076     timerC.HomeTime();
       
  1077 	// Do the tests
       
  1078     TRAP(r,CallTestsL());
       
  1079 
       
  1080     // reset the debug register
       
  1081     TheFs.SetDebugRegister(0);
       
  1082 
       
  1083     TTime endTimeC;
       
  1084     endTimeC.HomeTime();
       
  1085     TTimeIntervalSeconds timeTakenC;
       
  1086     r=endTimeC.SecondsFrom(timerC,timeTakenC);
       
  1087     test(r==KErrNone);
       
  1088     test.Printf(_L("Time taken for test = %d seconds\n"),timeTakenC.Int());
       
  1089     // TheFs.SetAllocFailure(gAllocFailOff);
       
  1090     TheFs.Close();
       
  1091     test.End();
       
  1092     test.Close();
       
  1093     __UHEAP_MARKEND;
       
  1094     delete cleanup;
       
  1095     return(KErrNone);
       
  1096     }