diff -r 000000000000 -r a41df078684a kerneltest/e32test/lffs/bf_raw.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/e32test/lffs/bf_raw.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,263 @@ +// Copyright (c) 1996-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: +// Performs some benchmarking of the LFFS media driver +// +// + +/** + @file bf_raw.cpp +*/ + +#include +#include +#include +#include +#include +#include +#include "bf_raw.h" +#include "user_config.h" + +const TInt KAverageOverInSeconds=10; ///< Number of seconds to run tests for + +//TInt64 Count; ///< Global variable used to count number of operations completed +TUint32 Count; + +RTest test(_L("BF_RAW")); + + +TTestInfo TestInfo; ///< Data passed to exector thread + +TBusLocalDrive drive; +TLocalDriveCapsV2Buf driveInfo; + +GLDEF_D HBufC8* writeBuffer; ///< Buffer for transferring data +GLDEF_D HBufC8* readBuffer; ///< Buffer for transferring data + +GLDEF_D TBool StopTest; ///< set to ETrue to stop the test + + +GLREF_C TInt BmWrite(TAny*); +GLREF_C TInt BmWriteThread(TAny*); +GLREF_C TInt BmRead(TAny*); +GLREF_C TInt BmReadThread(TAny*); + +GLDEF_D TInt mainThreadHandle; + +TUint32 runTest(TThreadFunction aFunction) + /** + * Function which actually runs the test. + * + * It creates a new thread to exeute the operations and then waits + * for a pre-determined time. The executor thread increments a counter + * each time it completes one operation. After the time period expires + * the counter is averaged to get an "operations per second". This is + * then multiplied by the data size to obtain tranfer rate + */ + { + + RThread thread; + TInt r=thread.Create(_L("TESTER"),aFunction,KDefaultStackSize,&User::Heap(),NULL); + if(r!=KErrNone) + { + test.Printf(_L("Failed to create thread with error %d\n"),r); + return(r); + } + StopTest = EFalse; // allow the test to run + TRequestStatus deadStat; + thread.Logon( deadStat ); + + RThread().SetPriority( EPriorityMuchMore ); + + thread.Resume(); + User::After(1000000); + Count=0; + User::After(KAverageOverInSeconds*1000000); + TUint32 result=Count; + + // tell test to stop and wait for thread to exit. + StopTest = ETrue; + User::WaitForRequest( deadStat ); + + CLOSE_AND_WAIT(thread); + return(result); + } + +void PrintResult( TUint32 aCount, const TDesC& aTitle ) + /** + * Prints result of test + */ + { + TInt64 count(static_cast(aCount)); + TInt64 transferRate = (count * TestInfo.iLength) / KAverageOverInSeconds; + + test.Printf(_L("%S: %d bytes/second\n"), + &aTitle, + I64LOW(transferRate) ); + } + + +LOCAL_C TInt EraseSegment( TInt aSegmentNumber ) + /** + * Erases a segment on Flash + * + * @param aSegmentNumber index of segment to erase + * @return KErrNone or error code + */ + { + TInt offset = aSegmentNumber * driveInfo().iEraseBlockSize; + + TInt r = drive.Format( offset, driveInfo().iEraseBlockSize ); + return r; + } + + +/** + * Structure defining tests + */ +class TTestData + { + public: + TThreadFunction iFunction; ///< function to execute, NULL for end of list + TInt iLength; ///< data length + TInt iOffset; ///< Flash offset + const TDesC* iDescription; ///< descriptive text + }; + + +_LIT( KErasingSegment0, "Erasing segment 0" ); + +_LIT( KWrite1Start, "Write, 1 byte, 32-byte boundary, current thread" ); +_LIT( KWrite24Start, "Write, 24 bytes, 32-byte boundary, current thread" ); +_LIT( KWrite64Start, "Write, 64 bytes, 32-byte boundary, current thread" ); +_LIT( KWrite512Start, "Write, 512 bytes, 32-byte boundary, current thread" ); + +_LIT( KRead1Start, "Read, 1 byte, 32-byte boundary, current thread" ); +_LIT( KRead24Start, "Read, 24 bytes, 32-byte boundary, current thread" ); +_LIT( KRead64Start, "Read, 64 bytes, 32-byte boundary, current thread" ); +_LIT( KRead512Start, "Read, 512 bytes, 32-byte boundary, current thread" ); + +const TThreadFunction KEraseSegment = (TThreadFunction)0x000000F1; + +const TTestData testData[] = ///< the test data + { + { KEraseSegment, 0, 0, &KErasingSegment0 }, + + { BmWrite, 1, 0, &KWrite1Start }, + { BmWrite, 24, 32, &KWrite24Start }, + { BmWrite, 64, 64, &KWrite64Start }, + { BmWrite, 512, 128, &KWrite512Start }, + + { BmRead, 1, 0, &KRead1Start }, + { BmRead, 24, 0, &KRead24Start }, + { BmRead, 64, 0, &KRead64Start }, + { BmRead, 512, 0, &KRead512Start }, + + { NULL, 0, 0, NULL } + }; + + + +void Initialize() + /** + * Open channel to media driver + */ + { + // + // Load the media driver + // +#ifndef SKIP_PDD_LOAD + test.Printf( _L("Loading %S\n"), &KLfsDriverName ); + TInt r = User::LoadPhysicalDevice( KLfsDriverName ); + test( KErrNone == r || KErrAlreadyExists == r ); +#endif + +#ifdef UNMOUNT_DRIVE + RFs fs; + test( KErrNone == fs.Connect() ); +#if 0 + // XXX - not EKA2 + test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) ); +#endif + TFullName name; + fs.FileSystemName( name, KLffsLogicalDriveNumber ); + if( name.Length() > 0 ) + { + test.Printf( _L("Unmounting drive") ); + test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) ); + User::After( 2000000 ); + test.Printf( _L("Drive unmounted") ); + } + fs.Close(); +#endif + + // + // Open a TBusLogicalDevice to it + // + test.Printf( _L("Opening media channel\n") ); + TBool changedFlag = EFalse; + test( KErrNone == drive.Connect( KDriveNumber, changedFlag ) ); + + // + // Get size of Flash drive, block size, block count + // + drive.Caps(driveInfo); + + // + // Create data buffer + // + writeBuffer = HBufC8::New( 1024 ); + test( NULL != writeBuffer ); + writeBuffer->Des().FillZ(1024); + + readBuffer = HBufC8::New( 1024 ); + test( NULL != readBuffer ); + readBuffer->Des().FillZ(1024); + + mainThreadHandle = RThread().Handle(); + } + + + +TInt E32Main() + { + + test.Title(); + test.Start(_L("Benchmarks for media driver")); + + Initialize(); + + const TTestData* pTest = &testData[0]; + while( pTest->iFunction ) + { + if( KEraseSegment == pTest->iFunction ) + { + test.Printf( *pTest->iDescription ); + TInt r = EraseSegment( pTest->iOffset ); + test( KErrNone == r ); + test.Printf( _L("Segment erased") ); + } + else + { + TestInfo.iLength = pTest->iLength; + TestInfo.iOffset = pTest->iOffset; + PrintResult( runTest( pTest->iFunction ), *pTest->iDescription ); + } + ++pTest; + } + + drive.Disconnect(); + test.End(); + return(KErrNone); + } +