sl@0: // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // tests read/write throughput on two drives simultaneously sl@0: // sl@0: // sl@0: sl@0: //! @file f32test\concur\t_cfsbench.cpp sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include "t_server.h" sl@0: #include "t_tdebug.h" sl@0: sl@0: //IMPORT_C TUint32 DebugRegister(); sl@0: sl@0: sl@0: GLDEF_D RTest test(_L("T_CFSBENCH")); sl@0: GLDEF_D RFs TheFs; sl@0: sl@0: LOCAL_D TFullName gFsName; sl@0: LOCAL_D TFullName gFsName1; sl@0: LOCAL_D TFullName gFsName2; sl@0: LOCAL_D TFullName gOldFsName; sl@0: LOCAL_D TFullName gNewFsName; sl@0: LOCAL_D TBool gNoMedia = ETrue; sl@0: sl@0: _LIT(KFsFile, "CFAFSDLY"); sl@0: _LIT(KFsName, "DelayFS"); sl@0: sl@0: LOCAL_D const TInt32 KSecond = 1000000; sl@0: LOCAL_D const TInt32 KTimeBM = 20; sl@0: sl@0: sl@0: LOCAL_D const TInt32 KBufLen = 0x100; sl@0: sl@0: LOCAL_D const TInt32 KMaxLag = 4; sl@0: sl@0: LOCAL_D TBool gVerbose = EFalse; sl@0: sl@0: TBuf16 gResults; sl@0: sl@0: const TInt KMaxFileSize = (4*1024*1024); sl@0: const TInt KMinBufferSize = (16); sl@0: const TInt KMaxBufferSize = (512*1024); sl@0: const TInt KMaxIter = 17; sl@0: sl@0: sl@0: TBool gReadTests = EFalse; sl@0: TBool gWriteTests = EFalse; sl@0: TBool gAsyncTests = EFalse; sl@0: TBool gSyncTests = EFalse; sl@0: sl@0: sl@0: LOCAL_C TInt32 GetSpeed(TInt aOps, TInt aBufSize, TInt64 aDtime) sl@0: /// Calculate and return the throughput from the umber of blocks transferred sl@0: /// and the elapsed time. sl@0: { sl@0: TInt64 dsize = MAKE_TINT64(0, aOps) * MAKE_TINT64(0, aBufSize) * MAKE_TINT64(0, KSecond); sl@0: TInt32 speed = I64LOW((dsize + aDtime/2) / aDtime); sl@0: return speed; sl@0: } sl@0: sl@0: LOCAL_C TBool DriveIsOK(TChar c) sl@0: /// Test that a selected drive leter is OK to write files. sl@0: { sl@0: TInt r; sl@0: TInt drv; sl@0: r=TheFs.CharToDrive(c, drv); sl@0: if (r != KErrNone) sl@0: return EFalse; sl@0: TDriveInfo info; sl@0: r=TheFs.Drive(info,drv); sl@0: test(r==KErrNone); sl@0: return (info.iDriveAtt != 0 && !(info.iDriveAtt & KDriveAttRom)); sl@0: } sl@0: sl@0: LOCAL_C TChar MountTestFileSystem(TInt aDrive) sl@0: // sl@0: // Mount a new CTestFileSystem on the drive under test sl@0: // sl@0: { sl@0: TInt r; sl@0: TBuf<64> b; sl@0: TChar c; sl@0: r=TheFs.DriveToChar(aDrive,c); sl@0: test(r==KErrNone); sl@0: b.Format(_L("Mount test file system on %c:"),(TUint)c); sl@0: test.Next(b); sl@0: sl@0: r=TheFs.AddFileSystem(KFsFile); sl@0: test(r==KErrNone || r==KErrAlreadyExists); sl@0: sl@0: r=TheFs.FileSystemName(gOldFsName,aDrive); sl@0: test(r==KErrNone || r==KErrNotFound); sl@0: sl@0: TDriveInfo drv; sl@0: r = TheFs.Drive(drv, aDrive); sl@0: test(r == KErrNone); sl@0: sl@0: gNoMedia = (drv.iType == EMediaUnknown || drv.iType == EMediaNotPresent); sl@0: sl@0: if (gOldFsName.Length() > 0) sl@0: { sl@0: TTest::Printf(_L("Dismount %C: %S"), (TUint)c, &gOldFsName); sl@0: r=TheFs.DismountFileSystem(gOldFsName,aDrive); sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: r=TheFs.MountFileSystem(KFsName,aDrive); sl@0: test(r==KErrNone); sl@0: sl@0: r=TheFs.FileSystemName(gNewFsName,aDrive); sl@0: test(r==KErrNone); sl@0: test(gNewFsName.CompareF(KFsName)==0); sl@0: return c; sl@0: } sl@0: sl@0: LOCAL_C void UnmountFileSystem(TInt aDrive) sl@0: /// Unmount a test filesystem and mount the old one. sl@0: { sl@0: TChar c; sl@0: TInt r=TheFs.DriveToChar(aDrive,c); sl@0: test(r==KErrNone); sl@0: r=TheFs.DismountFileSystem(gNewFsName,aDrive); sl@0: test(r==KErrNone); sl@0: // if there's no media present, don't try to mount it sl@0: if (gNoMedia) sl@0: { sl@0: test.Printf(_L("No media on %C: so don't remount it"), (TUint)c); sl@0: } sl@0: else if (gOldFsName.Length() > 0) sl@0: { sl@0: test.Printf(_L("Mount %C: %S"), (TUint)c, &gOldFsName); sl@0: r=TheFs.MountFileSystem(gOldFsName,aDrive); sl@0: test(r==KErrNone); sl@0: } sl@0: if (r != KErrNone) sl@0: test.Printf(_L("Error %d remounting %S on %C\n"), r, &gOldFsName, (TUint)c); sl@0: } sl@0: sl@0: LOCAL_C void RemountFileSystem(TInt aDrive, TBool aSync) sl@0: /// Unmount and remount the file system on the specified drive in the sl@0: /// selected mode. sl@0: /// @param aDrive Drive number (EDriveC etc.). sl@0: /// @param aSync Mount synchronous if true, asynchronous if not. sl@0: { sl@0: TChar c; sl@0: TInt r=TheFs.DriveToChar(aDrive,c); sl@0: r=TheFs.FileSystemName(gFsName, aDrive); sl@0: test(r==KErrNone || r==KErrNotFound); sl@0: sl@0: if (gFsName.Length() > 0) sl@0: { sl@0: r=TheFs.DismountFileSystem(gFsName, aDrive); sl@0: if(r!=KErrNone) sl@0: { sl@0: test.Printf(_L("Error = %d"),r); sl@0: test(EFalse); sl@0: } sl@0: } sl@0: sl@0: TBufC<16> type = _L("asynchronous"); sl@0: if (aSync) sl@0: type = _L("synchronous"); sl@0: if (gVerbose) sl@0: test.Printf(_L("Mount filesystem %c: %-8S as %S\n"), (TUint)c, &gFsName, &type); sl@0: sl@0: #ifdef __CONCURRENT_FILE_ACCESS__ sl@0: r=TheFs.MountFileSystem(gFsName, aDrive, aSync); sl@0: #else sl@0: r=TheFs.MountFileSystem(gFsName, aDrive); sl@0: #endif sl@0: sl@0: test(r==KErrNone); sl@0: } sl@0: sl@0: enum TOper sl@0: { sl@0: ERead, sl@0: EWrite sl@0: }; sl@0: sl@0: sl@0: // --------------------------------------------------------------------------- sl@0: sl@0: class RFileOps sl@0: /// Do operations on a file. sl@0: { sl@0: public: sl@0: RFileOps(); sl@0: sl@0: enum TOper sl@0: { sl@0: ERead, sl@0: EWrite sl@0: }; sl@0: sl@0: sl@0: TInt Init(TChar dr, TInt aBufSize); sl@0: void DeInit(); sl@0: void CalculateFreeSpace(); sl@0: sl@0: TInt Open(TOper aOper); sl@0: TInt Close(); sl@0: TInt Delete(); sl@0: TInt Reset(); sl@0: TInt Erase(); sl@0: TInt Write(); sl@0: TInt Read(); sl@0: TInt End(); sl@0: TInt CreateReadFile(); sl@0: sl@0: public: sl@0: TFileName iNameRead; sl@0: TFileName iNameWrite; sl@0: RFile iF; sl@0: sl@0: HBufC8* iBuffer[KMaxLag]; sl@0: TPtr8* iBufPtr[KMaxLag]; sl@0: sl@0: TRequestStatus iStatus[KMaxLag]; sl@0: TInt iPtr; sl@0: TInt iNum; sl@0: TInt iOps; sl@0: TInt iMax; sl@0: TBool iOpen; sl@0: TInt iBufSize; sl@0: TChar iDrvCh; sl@0: TInt64 iFree; sl@0: TInt iFileSize; sl@0: // counters sl@0: TInt iFileWraps; sl@0: TInt iFileSyncAccesses; sl@0: TInt iFileAsyncAccesses; sl@0: }; sl@0: sl@0: RFileOps::RFileOps() : iPtr(0), iNum(0), iOps(0), iMax(0), iOpen(EFalse) sl@0: { sl@0: for (TInt i = 0; i < KMaxLag; i++) sl@0: { sl@0: iStatus[i] = KErrNone; sl@0: iBuffer[i] = NULL; sl@0: iBufPtr[i] = NULL; sl@0: } sl@0: sl@0: } sl@0: sl@0: TInt RFileOps::Init(TChar aDrvCh, TInt aBufSize) sl@0: { sl@0: TInt r = KErrNone; sl@0: sl@0: test(!iOpen); sl@0: sl@0: iDrvCh = aDrvCh; sl@0: iBufSize = aBufSize; sl@0: iNameWrite.Format(_L("%c:\\TESTWT"), (TUint)aDrvCh); sl@0: iNameRead.Format(_L("%c:\\TESTRD"), (TUint)aDrvCh); sl@0: sl@0: for (TInt i = 0; i < KMaxLag; i++) sl@0: { sl@0: iStatus[i] = KErrNone; sl@0: sl@0: iBuffer[i] = HBufC8::NewL(aBufSize); sl@0: if (iBuffer[i] == NULL) sl@0: return KErrNoMemory; sl@0: iBufPtr[i] = new TPtr8(iBuffer[i]->Des()); sl@0: //TPtr8 buffer(iBuffer[i]->Des()); sl@0: //buffer.Fill(TChar('_'), aBufSize); sl@0: iBufPtr[i]->Fill(TChar('_'), aBufSize); sl@0: } sl@0: sl@0: return r; sl@0: } sl@0: sl@0: void RFileOps::DeInit() sl@0: { sl@0: test(!iOpen); sl@0: sl@0: for (TInt i = 0; i < KMaxLag; i++) sl@0: { sl@0: delete iBuffer[i]; sl@0: iBuffer[i] = NULL; sl@0: delete iBufPtr[i]; sl@0: iBufPtr[i] = NULL; sl@0: } sl@0: sl@0: } sl@0: sl@0: void RFileOps::CalculateFreeSpace() sl@0: { sl@0: TVolumeInfo vol; sl@0: TInt drv; sl@0: sl@0: sl@0: TInt r = TheFs.CharToDrive(iDrvCh, drv); sl@0: if (r != KErrNone) sl@0: TTest::Fail(HERE, _L("CharToDrive(%c) returned %d"), (TUint)iDrvCh, r); sl@0: sl@0: r = TheFs.Volume(vol, drv); sl@0: if (r != KErrNone) sl@0: TTest::Fail(HERE, _L("Volume(%c:) returned %d"), (TUint)iDrvCh, r); sl@0: sl@0: iFree = vol.iFree; sl@0: sl@0: TInt64 fileSize = iFree / 2; sl@0: if (fileSize > KMaxFileSize) sl@0: fileSize = KMaxFileSize; sl@0: iFileSize = I64LOW(fileSize); sl@0: sl@0: sl@0: // calculate the number of buffers to use sl@0: // if we assume we'll be able to use half the available disk space sl@0: TInt max = iFileSize / iBufSize; sl@0: iMax = max; sl@0: sl@0: if (gVerbose) sl@0: { sl@0: test.Printf(_L("Free space on drive %c = %d KB\n"), (TUint)iDrvCh, I64LOW(iFree/1024)); sl@0: test.Printf(_L("File Size = %d KB. Using %d buffers of size %d\n"), iFileSize/1024, iMax, iBufSize); sl@0: } sl@0: sl@0: } sl@0: sl@0: sl@0: TInt RFileOps::Open(TOper aOper) sl@0: /// Open the file for testing, give error if there is not enough space for it. sl@0: { sl@0: TInt r; sl@0: sl@0: test(!iOpen); sl@0: sl@0: sl@0: // reset counters sl@0: iFileWraps = 0; sl@0: iFileSyncAccesses = 0; sl@0: iFileAsyncAccesses = 0; sl@0: sl@0: TheFs.Delete(iNameWrite); sl@0: sl@0: if (aOper == ERead) sl@0: { sl@0: r = iF.Open(TheFs, iNameRead, EFileStreamText | EFileRead); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: TInt sizeFile = 0; sl@0: r = iF.Size(sizeFile); sl@0: test(r == KErrNone); sl@0: if (gVerbose) sl@0: { sl@0: test.Printf(_L("File Size = %d, %d buffers of size %d\n"), sizeFile, iMax, iBufSize); sl@0: } sl@0: iMax = sizeFile / iBufSize; sl@0: } sl@0: else sl@0: { sl@0: CalculateFreeSpace(); sl@0: sl@0: if (iMax < KMaxLag) sl@0: { sl@0: test.Printf(_L("Insufficient free space on drive %c, deleting read file\n"), (TUint)iDrvCh); sl@0: TInt maxOld = iMax; sl@0: TheFs.Delete(iNameRead); sl@0: CalculateFreeSpace(); sl@0: test.Printf(_L("Old available buffers = %d, new available buffers = %d\n"), maxOld, iMax); sl@0: } sl@0: if (iMax < KMaxLag) sl@0: TTest::Fail(HERE, _L("Not enough space to do test, only %d KB available. Only %d buffers of %d bytes available"), sl@0: I64LOW(iFree/1024), iMax, iBufSize ); sl@0: sl@0: r = iF.Replace(TheFs, iNameWrite, EFileStreamText | EFileWrite); sl@0: } sl@0: sl@0: if (r == KErrNone) sl@0: iOpen = ETrue; sl@0: sl@0: sl@0: Reset(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: // Close and delete the file, returning the number of operations done. sl@0: TInt RFileOps::Close() sl@0: { sl@0: if (!iOpen) sl@0: return 0; sl@0: sl@0: iF.Close(); sl@0: iOpen = EFalse; sl@0: sl@0: // always delete the write file sl@0: TheFs.Delete(iNameWrite); sl@0: sl@0: sl@0: return iNum; sl@0: } sl@0: sl@0: TInt RFileOps::Delete() sl@0: { sl@0: TInt r = TheFs.Delete(iNameRead); sl@0: r = TheFs.Delete(iNameWrite); sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt RFileOps::Reset() sl@0: /// Reset all of the counts. sl@0: { sl@0: TInt err = KErrNone; sl@0: sl@0: iPtr = 0; sl@0: iNum = 0; sl@0: iOps = 0; sl@0: return err; sl@0: } sl@0: sl@0: TInt RFileOps::CreateReadFile() sl@0: { sl@0: TInt r = KErrNone; sl@0: sl@0: CalculateFreeSpace(); // get iMax sl@0: sl@0: if (iOpen) sl@0: iF.Close(); sl@0: iOpen = EFalse; sl@0: sl@0: sl@0: r = iF.Open(TheFs, iNameRead, EFileStreamText | EFileRead); sl@0: if (r == KErrNone) sl@0: { sl@0: if (gVerbose) sl@0: test.Printf(_L("temp file already exists.\n")); sl@0: iF.Close(); sl@0: sl@0: return r; sl@0: } sl@0: sl@0: sl@0: r = iF.Replace(TheFs, iNameRead, EFileStreamText | EFileWrite); sl@0: if (r != KErrNone) sl@0: return r; sl@0: sl@0: iOpen = ETrue; sl@0: sl@0: Reset(); sl@0: sl@0: sl@0: test.Printf(_L("Creating temp file on drive %c of size %d..."), (TUint)iDrvCh, iFileSize); sl@0: sl@0: HBufC8* buf = HBufC8::NewL(KMaxBufferSize); sl@0: TPtr8 bufptr(buf->Des()); sl@0: bufptr.Fill(TChar('_'), KMaxBufferSize); sl@0: sl@0: test(buf != NULL); sl@0: for (TInt pos=0; posLength()) sl@0: { sl@0: r = iF.Write(pos, bufptr); sl@0: if (r != KErrNone) sl@0: test.Printf(_L("Write() returned %d\n"), r); sl@0: sl@0: test(r == KErrNone); sl@0: } sl@0: delete buf; buf = NULL; sl@0: sl@0: // if (gVerbose) sl@0: test.Printf(_L("Done.\n")); sl@0: sl@0: iF.Close(); sl@0: iOpen = EFalse; sl@0: sl@0: return r; sl@0: } sl@0: sl@0: TInt RFileOps::Write() sl@0: /// If there is a free buffer available, start a write. sl@0: { sl@0: if (!iOpen) sl@0: return 0; sl@0: sl@0: while (iNum < iOps && iStatus[iNum%KMaxLag] != KRequestPending) sl@0: { sl@0: TInt status = iStatus[iNum%KMaxLag].Int(); sl@0: test (status == KErrNone); sl@0: iNum++; sl@0: } sl@0: sl@0: if (iOps < KMaxLag || iStatus[iPtr] != KRequestPending) sl@0: { sl@0: TInt pos = iOps%iMax * iBufSize; sl@0: sl@0: iF.Write(pos, *iBufPtr[iPtr], iStatus[iPtr]); sl@0: sl@0: TInt status = iStatus[iPtr].Int(); sl@0: sl@0: if (gVerbose) sl@0: { sl@0: test.Printf(_L("Writing buf #%d to drive %c at pos %d, status = %d\n"), sl@0: iPtr, (TUint)iDrvCh, pos, status); sl@0: } sl@0: test (status == KErrNone || status == KRequestPending); sl@0: sl@0: iOps++; sl@0: iPtr++; sl@0: iPtr %= KMaxLag; sl@0: return 1; sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: TInt RFileOps::Read() sl@0: /// If there is a free buffer available, start a read. sl@0: { sl@0: if (!iOpen) sl@0: return 0; sl@0: sl@0: while (iNum < iOps && iStatus[iNum%KMaxLag] != KRequestPending) sl@0: { sl@0: TInt status = iStatus[iNum%KMaxLag].Int(); sl@0: if (status != KErrNone) sl@0: test.Printf(_L("drive %c, iNum = %d, iOps=%d, Status = %d\n"), (TUint)iDrvCh, iNum, iOps, status); sl@0: test (status == KErrNone); sl@0: sl@0: iNum++; sl@0: } sl@0: if (iOps < KMaxLag || iStatus[iPtr] != KRequestPending) sl@0: { sl@0: TInt pos = iOps%iMax * iBufSize; sl@0: sl@0: iBufPtr[iPtr]->SetLength(0); sl@0: sl@0: iF.Read(pos, *iBufPtr[iPtr], iStatus[iPtr]); sl@0: sl@0: TInt len = iBufPtr[iPtr]->Length(); sl@0: TInt status = iStatus[iPtr].Int(); sl@0: sl@0: TInt err = KErrNone; sl@0: sl@0: if (status == KErrNone) sl@0: { sl@0: iFileSyncAccesses++; sl@0: if (len < iBufPtr[iPtr]->MaxLength()) sl@0: err = KErrUnderflow; sl@0: } sl@0: else if (status == KRequestPending) sl@0: { sl@0: iFileAsyncAccesses++; sl@0: } sl@0: else sl@0: { sl@0: err = status; sl@0: } sl@0: sl@0: if (gVerbose || err != KErrNone) sl@0: { sl@0: test.Printf(_L("Reading buf #%d, drive %c, pos %d, status %d, len %d, iNum %d, iOps %d, iMax %d\n"), sl@0: iPtr, (TUint)iDrvCh, pos, status, len, iNum, iOps, iMax); sl@0: } sl@0: sl@0: test (err == KErrNone); sl@0: sl@0: iOps++; sl@0: iPtr++; sl@0: iPtr %= KMaxLag; sl@0: sl@0: // have we wrapped to postion zero ? sl@0: if (iOps % iMax == 0) sl@0: iFileWraps++; sl@0: sl@0: return 1; sl@0: } sl@0: return 0; sl@0: } sl@0: sl@0: sl@0: TInt RFileOps::End() sl@0: /// Wait until all outstanding operations have ended, then return the number. sl@0: { sl@0: if (!iOpen) sl@0: return 0; sl@0: sl@0: if (gVerbose) sl@0: test.Printf(_L("Waiting for reads/writes to %c to complete, iNum=%d, iOps=%d...\n"), (TUint)iDrvCh, iNum, iOps); sl@0: sl@0: while (iNum < iOps) sl@0: { sl@0: if (iStatus[iNum%KMaxLag] == KRequestPending) sl@0: { sl@0: User::WaitForRequest(iStatus[iNum%KMaxLag]); sl@0: } sl@0: else sl@0: { sl@0: TInt status = iStatus[iNum%KMaxLag].Int(); sl@0: if (gVerbose || (status != KErrNone && status != KRequestPending)) sl@0: test.Printf(_L("Buf#%d: Status = %d\n"), iNum, status); sl@0: test (status == KErrNone || status == KRequestPending); sl@0: iNum++; sl@0: } sl@0: } sl@0: sl@0: return iNum; sl@0: } sl@0: sl@0: LOCAL_C TInt testAsyncAccess( sl@0: TInt aDrive1, sl@0: TInt aDrive2, sl@0: TInt aBufSize1, sl@0: TInt aBufSize2, sl@0: TBool aSync1, sl@0: TBool aSync2, sl@0: TInt& aThroughput1, sl@0: TInt& aThroughput2) sl@0: // sl@0: // Test one drive against the other. sl@0: // sl@0: { sl@0: TInt r; sl@0: sl@0: RFileOps f1; sl@0: RFileOps f2; sl@0: sl@0: TChar dc1; sl@0: TChar dc2; sl@0: sl@0: TInt op1 = 0; sl@0: TInt op2 = 0; sl@0: RTimer timer; sl@0: TRequestStatus tstat; sl@0: TTime startTime; sl@0: TTime endTime; sl@0: TTimeIntervalMicroSeconds timeTaken(0); sl@0: TInt64 dtime; sl@0: sl@0: aThroughput1 = aThroughput2 = 0; sl@0: sl@0: if (aBufSize1 == 0 && aBufSize2 == 0) sl@0: return KErrNone; sl@0: sl@0: timer.CreateLocal(); sl@0: sl@0: sl@0: r = TheFs.DriveToChar(aDrive1, dc1); sl@0: test(r == KErrNone); sl@0: r = TheFs.DriveToChar(aDrive2, dc2); sl@0: test(r == KErrNone); sl@0: sl@0: // allocate buffers sl@0: r = f1.Init(dc1, aBufSize1); sl@0: test(r == KErrNone); sl@0: r = f2.Init(dc2, aBufSize2); sl@0: test(r == KErrNone); sl@0: sl@0: sl@0: _LIT(KSync, " sync"); sl@0: _LIT(KAsync, "async"); sl@0: if (gVerbose) sl@0: test.Printf(_L("%c: (%S) %d, %c: (%S) %d\n"), sl@0: (TUint)dc1, sl@0: aSync1?&KSync:&KAsync, sl@0: aBufSize1, sl@0: (TUint)dc2, sl@0: aSync2?&KSync:&KAsync, sl@0: aBufSize2); sl@0: sl@0: RemountFileSystem(aDrive1, aSync1); sl@0: RemountFileSystem(aDrive2, aSync2); sl@0: sl@0: if (gReadTests) sl@0: { sl@0: //******************************************************************** sl@0: // read test sl@0: //******************************************************************** sl@0: sl@0: if (aBufSize1 > 0) sl@0: { sl@0: r = f1.CreateReadFile(); sl@0: test(r == KErrNone); sl@0: } sl@0: if (aBufSize2 > 0) sl@0: { sl@0: r = f2.CreateReadFile(); sl@0: test(r == KErrNone); sl@0: } sl@0: sl@0: if (aBufSize1 > 0) sl@0: r = f1.Open(RFileOps::ERead); sl@0: test(r == KErrNone); sl@0: sl@0: if (aBufSize2 > 0) sl@0: r = f2.Open(RFileOps::ERead); sl@0: test(r == KErrNone); sl@0: sl@0: sl@0: timer.After(tstat, KTimeBM * KSecond); sl@0: sl@0: startTime.HomeTime(); sl@0: sl@0: while (tstat == KRequestPending) sl@0: { sl@0: TInt num = 0; sl@0: if (aBufSize1 > 0) sl@0: num = f1.Read(); sl@0: if (aBufSize2 > 0) sl@0: num += f2.Read(); sl@0: if (num == 0) sl@0: User::WaitForAnyRequest(); sl@0: } sl@0: timer.Cancel(); sl@0: sl@0: if (aBufSize1 > 0) sl@0: op1 = f1.End(); sl@0: if (aBufSize2 > 0) sl@0: op2 = f2.End(); sl@0: sl@0: endTime.HomeTime(); sl@0: timeTaken=endTime.MicroSecondsFrom(startTime); sl@0: sl@0: //******************************************************************** sl@0: // Read test end sl@0: //******************************************************************** sl@0: } // if (gReadTests) sl@0: sl@0: if (gWriteTests) sl@0: { sl@0: //******************************************************************** sl@0: // write test sl@0: //******************************************************************** sl@0: if (aBufSize1 > 0) sl@0: { sl@0: r = f1.Open(RFileOps::EWrite); sl@0: test(r == KErrNone); sl@0: } sl@0: sl@0: if (aBufSize2 > 0) sl@0: { sl@0: r = f2.Open(RFileOps::EWrite); sl@0: test(r == KErrNone); sl@0: } sl@0: sl@0: timer.After(tstat, KTimeBM * KSecond); sl@0: sl@0: startTime.HomeTime(); sl@0: sl@0: while (tstat == KRequestPending) sl@0: { sl@0: TInt num = 0; sl@0: if (aBufSize1 > 0) sl@0: num = f1.Write(); sl@0: if (aBufSize2 > 0) sl@0: num += f2.Write(); sl@0: if (num == 0) sl@0: User::WaitForAnyRequest(); sl@0: } sl@0: timer.Cancel(); sl@0: sl@0: if (aBufSize1 > 0) sl@0: op1 = f1.End(); sl@0: if (aBufSize2 > 0) sl@0: op2 = f2.End(); sl@0: sl@0: sl@0: endTime.HomeTime(); sl@0: timeTaken=endTime.MicroSecondsFrom(startTime); sl@0: sl@0: //******************************************************************** sl@0: // Write test end sl@0: //******************************************************************** sl@0: sl@0: } // if gWriteTests sl@0: sl@0: dtime = timeTaken.Int64(); sl@0: sl@0: aThroughput1 = GetSpeed(op1, aBufSize1, dtime); sl@0: aThroughput2 = GetSpeed(op2, aBufSize2, dtime); sl@0: sl@0: test.Printf(_L("%c:,%c:,%10d,%10d,%10d,%10d\n"), sl@0: (TUint)dc1, (TUint)dc2, sl@0: aBufSize1,aBufSize2, sl@0: aThroughput1, sl@0: aThroughput2 sl@0: ); sl@0: sl@0: sl@0: if (gVerbose) sl@0: { sl@0: test.Printf(_L("%c: %d async reads, %d sync reads, wraps = %d\n"), sl@0: (TUint)dc1, f1.iFileAsyncAccesses, f1.iFileSyncAccesses, f1.iFileWraps); sl@0: test.Printf(_L("%c: %d async reads, %d sync reads, wraps = %d\n"), sl@0: (TUint)dc2, f2.iFileAsyncAccesses, f2.iFileSyncAccesses, f2.iFileWraps); sl@0: } sl@0: sl@0: sl@0: f1.Close(); sl@0: f2.Close(); sl@0: sl@0: sl@0: timer.Close(); sl@0: sl@0: f1.DeInit(); sl@0: f2.DeInit(); sl@0: sl@0: return KErrNone; sl@0: } sl@0: sl@0: LOCAL_C TInt parseCmd(TChar& aDrvCh1, TChar& aDrvCh2) sl@0: /// Get parameters from the comand line; if there aren't enough then sl@0: /// prompt the user for them and return KErrAbort if ^C is pressed. sl@0: { sl@0: while (aDrvCh1 < 'A' || aDrvCh1 > 'Z') sl@0: { sl@0: test.Printf(_L("Enter drive letter: ")); sl@0: while (aDrvCh1 < 'A' || aDrvCh1 > 'Z') sl@0: { sl@0: if (aDrvCh1 == 0x03) sl@0: return KErrAbort; sl@0: aDrvCh1 = User::UpperCase(test.Getch()); sl@0: } sl@0: if (!DriveIsOK(aDrvCh1)) sl@0: { sl@0: test.Printf(_L("%c: is not a valid drive\n"), (TUint)aDrvCh1); sl@0: aDrvCh1 = 0; sl@0: } sl@0: else sl@0: { sl@0: TInt drv; sl@0: TheFs.CharToDrive(aDrvCh1, drv); sl@0: TheFs.FileSystemName(gFsName1, drv); sl@0: test.Printf(_L("%c: (%S)\n"), (TUint)aDrvCh1, &gFsName1); sl@0: } sl@0: } sl@0: sl@0: while (aDrvCh2 < 'A' || aDrvCh2 > 'Z') sl@0: { sl@0: test.Printf(_L("Enter drive letter: ")); sl@0: while (aDrvCh2 < 'A' || aDrvCh2 > 'Z') sl@0: { sl@0: if (aDrvCh2 == 0x03) sl@0: return KErrAbort; sl@0: aDrvCh2 = User::UpperCase(test.Getch()); sl@0: } sl@0: if (!DriveIsOK(aDrvCh2)) sl@0: { sl@0: test.Printf(_L("%c: is not a valid drive\n"), (TUint)aDrvCh2); sl@0: aDrvCh2 = 0; sl@0: } sl@0: else sl@0: { sl@0: TInt drv; sl@0: TheFs.CharToDrive(aDrvCh2, drv); sl@0: TheFs.FileSystemName(gFsName2, drv); sl@0: test.Printf(_L("%c: (%S)\n"), (TUint)aDrvCh2, &gFsName2); sl@0: } sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: typedef TInt RESULTS[KMaxIter][KMaxIter]; sl@0: LOCAL_C void PrintResults(RESULTS& aResults, TChar aDrvCh, TChar aDrvCh2) sl@0: { sl@0: TInt bufSize2; sl@0: TInt drive1Index, drive2Index; sl@0: sl@0: test.Printf(_L("*** Throughput for drive %c ***\n"), (TUint)aDrvCh); sl@0: sl@0: test.Printf(_L(" BufferSize (%C:)....\n"), (TUint)aDrvCh2); sl@0: gResults.Zero(); sl@0: for (bufSize2 = drive2Index = 0; bufSize2 <= KMaxBufferSize; bufSize2 = bufSize2 << 1, drive2Index++) sl@0: { sl@0: gResults.AppendFormat(_L("%10d,"), bufSize2); sl@0: if (bufSize2 == 0) sl@0: bufSize2 = KMinBufferSize >> 1; sl@0: } sl@0: test.Printf(_L("%S\n"), &gResults); sl@0: sl@0: for (drive1Index = 0; drive1Index < KMaxIter; drive1Index++) sl@0: { sl@0: gResults.Zero(); sl@0: for (drive2Index = 0; drive2Index < KMaxIter; drive2Index++) sl@0: { sl@0: gResults.AppendFormat(_L("%10d,"), aResults[drive1Index][drive2Index]); sl@0: } sl@0: test.Printf(_L("%S\n"), &gResults); sl@0: } sl@0: sl@0: } sl@0: sl@0: sl@0: // sl@0: // Do all tests sl@0: // sl@0: GLDEF_C void CallTestsL() sl@0: { sl@0: TInt r = TTest::Init(); sl@0: test(r == KErrNone); sl@0: sl@0: TChar drvch1 = 0; sl@0: TChar drvch2 = 0; sl@0: TInt drive1; sl@0: TInt drive2; sl@0: sl@0: const TInt KMaxArgs = 5; sl@0: TPtrC argv[KMaxArgs]; sl@0: TInt argc = TTest::ParseCommandArguments(argv, KMaxArgs); sl@0: if (argc > 1) sl@0: drvch1 = User::UpperCase(argv[1][0]); sl@0: if (argc > 2) sl@0: drvch2 = User::UpperCase(argv[2][0]); sl@0: sl@0: TBool testFs = EFalse; sl@0: sl@0: for (TInt n=3; n 3) sl@0: { sl@0: if (argv[n].Compare(_L("verbose")) == 0) sl@0: gVerbose = ETrue; sl@0: if (argv[n].Compare(_L("read")) == 0) sl@0: gReadTests = ETrue; sl@0: if (argv[n].Compare(_L("write")) == 0) sl@0: gWriteTests = ETrue; sl@0: sl@0: if (argv[n].Compare(_L("async")) == 0) sl@0: gAsyncTests = ETrue; sl@0: if (argv[n].Compare(_L("sync")) == 0) sl@0: gSyncTests = ETrue; sl@0: sl@0: if (argv[n].Compare(_L("testfs")) == 0) sl@0: testFs = ETrue; sl@0: } sl@0: } sl@0: sl@0: if ((!gReadTests && !gWriteTests) || sl@0: (!gAsyncTests && !gSyncTests)) sl@0: { sl@0: test.Printf(_L("T_CFSPERFORM - tests read/write throughput on two drives simultaneously\n")); sl@0: test.Printf(_L("Syntax : t_cfsperform [verbose] [testfs] read|write sync|async\n")); sl@0: test.Printf(_L("Where : async = concurrent access, sync = non-concurrent access\n")); sl@0: test.Printf(_L("E.g. : t_cfsperform c d read async\n")); sl@0: test.Printf(_L("Press any key")); sl@0: test.Getch(); sl@0: test.Printf(_L("\n")); sl@0: return; sl@0: } sl@0: sl@0: sl@0: r = parseCmd(drvch1, drvch2); sl@0: if (r != KErrNone) sl@0: { sl@0: User::Panic(_L("USER ABORT"), 0); sl@0: } sl@0: sl@0: r = TheFs.CharToDrive(drvch1, drive1); sl@0: test(r == KErrNone); sl@0: r = TheFs.CharToDrive(drvch2, drive2); sl@0: test(r == KErrNone); sl@0: sl@0: r = TheFs.FileSystemName(gFsName1, drive1); sl@0: test(r == KErrNone || r == KErrNotFound); sl@0: r = TheFs.FileSystemName(gFsName2, drive2); sl@0: test(r == KErrNone || r == KErrNotFound); sl@0: sl@0: if (testFs) sl@0: { sl@0: MountTestFileSystem(drive1); sl@0: MountTestFileSystem(drive2); sl@0: } sl@0: sl@0: sl@0: TInt bufSize1; sl@0: TInt bufSize2; sl@0: sl@0: // delete temp files before starting sl@0: RFileOps f; sl@0: f.Init(drvch1, 256); sl@0: f.Delete(); sl@0: f.DeInit(); sl@0: f.Init(drvch2, 256); sl@0: f.Delete(); sl@0: f.DeInit(); sl@0: sl@0: sl@0: TInt resultsDrive1[KMaxIter][KMaxIter]; sl@0: TInt resultsDrive2[KMaxIter][KMaxIter]; sl@0: TInt drive1Index; sl@0: TInt drive2Index; sl@0: sl@0: test.Printf(_L(" BufSize(%c) BufSize(%c) ThruPut(%c) ThruPut(%c) \n"), sl@0: (TUint)drvch1, (TUint)drvch2, (TUint)drvch1, (TUint)drvch2); sl@0: sl@0: for (bufSize1 = drive1Index = 0; bufSize1 <= KMaxBufferSize; bufSize1 = bufSize1 << 1, drive1Index++) sl@0: { sl@0: for (bufSize2 = drive2Index = 0; bufSize2 <= KMaxBufferSize; bufSize2 = bufSize2 << 1, drive2Index++) sl@0: { sl@0: sl@0: // // !!! Disable platform security tests until we get the new APIs sl@0: // if (User::Capability() & KCapabilityRoot) sl@0: // { sl@0: // CheckMountLFFS(TheFs, drvch1); sl@0: // CheckMountLFFS(TheFs, drvch2); sl@0: // } sl@0: sl@0: if (gVerbose) sl@0: test.Printf(_L("Using drives %c: (%S) and %c: (%S)\n"), sl@0: (TUint)drvch1, &gFsName1, (TUint)drvch2, &gFsName2); sl@0: sl@0: TInt throughputDrive1; sl@0: TInt throughputDrive2; sl@0: TBool sync = EFalse; sl@0: if (gSyncTests) sl@0: sync = ETrue; sl@0: sl@0: testAsyncAccess( sl@0: drive1, drive2, sl@0: bufSize1, bufSize2, sl@0: sync, sync, sl@0: throughputDrive1, throughputDrive2); sl@0: sl@0: resultsDrive1[drive1Index][drive2Index] = throughputDrive1; sl@0: resultsDrive2[drive1Index][drive2Index] = throughputDrive2; sl@0: sl@0: // buffer size sequence is 0,16,32,64,128, ... sl@0: if (bufSize2 == 0) sl@0: bufSize2 = KMinBufferSize >> 1; sl@0: } sl@0: // buffer size sequence is 0,16,32,64,128, ... sl@0: if (bufSize1 == 0) sl@0: bufSize1 = KMinBufferSize >> 1; sl@0: } sl@0: sl@0: sl@0: sl@0: PrintResults(resultsDrive1, drvch1, drvch2); sl@0: PrintResults(resultsDrive2, drvch2, drvch2); sl@0: sl@0: sl@0: if (testFs) sl@0: { sl@0: UnmountFileSystem(drive1); sl@0: UnmountFileSystem(drive2); sl@0: } sl@0: test(r == 0); sl@0: } sl@0: sl@0: sl@0: GLDEF_C TInt E32Main() sl@0: // sl@0: // Main entry point sl@0: // sl@0: { sl@0: TInt r; sl@0: CTrapCleanup* cleanup; sl@0: cleanup=CTrapCleanup::New(); sl@0: __UHEAP_MARK; sl@0: sl@0: test.Title(); sl@0: test.Start(_L("Starting tests...")); sl@0: sl@0: r=TheFs.Connect(); sl@0: test(r==KErrNone); sl@0: sl@0: // TheFs.SetAllocFailure(gAllocFailOn); sl@0: TTime timerC; sl@0: timerC.HomeTime(); sl@0: // Do the tests sl@0: TRAP(r,CallTestsL()); sl@0: sl@0: // reset the debug register sl@0: TheFs.SetDebugRegister(0); sl@0: sl@0: TTime endTimeC; sl@0: endTimeC.HomeTime(); sl@0: TTimeIntervalSeconds timeTakenC; sl@0: r=endTimeC.SecondsFrom(timerC,timeTakenC); sl@0: test(r==KErrNone); sl@0: test.Printf(_L("Time taken for test = %d seconds\n"),timeTakenC.Int()); sl@0: // TheFs.SetAllocFailure(gAllocFailOff); sl@0: TheFs.Close(); sl@0: test.End(); sl@0: test.Close(); sl@0: __UHEAP_MARKEND; sl@0: delete cleanup; sl@0: return(KErrNone); sl@0: }