kerneltest/e32test/lffs/bf_cpu.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1996-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 // Very simple test of CPU overhead
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file bf_cpu.cpp
       
    20 */
       
    21 
       
    22 #include <e32std.h>
       
    23 #include <e32std_private.h>
       
    24 #include <e32base.h>
       
    25 #include <e32base_private.h>
       
    26 #include <e32test.h>
       
    27 #include <e32svr.h>
       
    28 #include "user_config.h"
       
    29 
       
    30 
       
    31 #define TEST_WRITE_OVERHEAD
       
    32 #define NON_WRITING_LOOPS
       
    33 
       
    34 const TInt KAverageOverInSeconds=10;	///< Number of seconds to run tests for
       
    35 
       
    36 TInt64 Count;				///< Global variable used to count number of operations completed
       
    37 RSemaphore CountSem;		///< control access to Count;
       
    38 
       
    39 
       
    40 RTest test(_L("BF_CPU"));
       
    41 
       
    42 
       
    43 
       
    44 TBusLocalDrive	drive;
       
    45 TLocalDriveCapsV2Buf driveInfo;
       
    46 
       
    47 LOCAL_D TBool StopTest;		///< set to ETrue to stop the test
       
    48 
       
    49 
       
    50 #ifdef TEST_WRITE_OVERHEAD
       
    51 LOCAL_D TBool StopZeroTest;
       
    52 
       
    53 LOCAL_C TInt WriteZeroThread(TAny*)
       
    54 	/**
       
    55 	 * Performs writes of zero length continuously
       
    56 	 */
       
    57 	{
       
    58 #if 0
       
    59 	_LIT( KPanicCat, "ZERWRTH" );
       
    60 #endif
       
    61 	
       
    62 	TBuf8<513> buf;
       
    63 	buf.SetLength(513);
       
    64 	
       
    65 	while( !StopZeroTest )
       
    66 		{
       
    67 		// Return values are bogus when doing overhead testing
       
    68 		drive.Write( 513, buf );
       
    69 		}
       
    70 	return KErrNone;
       
    71 	}
       
    72 #endif
       
    73 
       
    74 
       
    75 LOCAL_C TInt WriteThread(TAny*)
       
    76 	/**
       
    77 	 * Performs writes continuously
       
    78 	 */
       
    79 	{
       
    80 	_LIT( KPanicCat, "WRTHRD" );
       
    81 	
       
    82 	TBuf8<512> buf;
       
    83 	buf.SetLength(512);
       
    84 	buf.Fill(0xFF);		// all 0xFF so we can repeatedly overwrite
       
    85 	
       
    86 	while( !StopTest )
       
    87 		{
       
    88 		TInt r = drive.Write( 0, buf );
       
    89 		if( KErrNone != r )
       
    90 			{
       
    91 			User::Panic( KPanicCat, r );
       
    92 			}
       
    93 		}
       
    94 	return KErrNone;
       
    95 	}
       
    96 
       
    97 
       
    98 
       
    99 LOCAL_C TInt CpuThread(TAny*)
       
   100 	/**
       
   101 	 * Just increments the counter
       
   102 	 */
       
   103 	{
       
   104 	while( !StopTest )
       
   105 		{
       
   106 		CountSem.Wait();
       
   107 #ifdef NON_WRITING_LOOPS
       
   108 		for( volatile TInt i = 5000; i > 0; i-- );
       
   109 #endif
       
   110 		++Count;
       
   111 		CountSem.Signal();
       
   112 		}
       
   113 	return KErrNone;
       
   114 	}
       
   115 
       
   116 
       
   117 void runTest()
       
   118 	{
       
   119     RThread writeThread;
       
   120 	TInt r=writeThread.Create(_L("WRITER"),WriteThread,KDefaultStackSize,&User::Heap(),NULL);
       
   121 	test(r==KErrNone);
       
   122 
       
   123 	RThread cpuThread;
       
   124 	r=cpuThread.Create(_L("CPU-ER"),CpuThread,KDefaultStackSize,&User::Heap(),NULL);
       
   125 	test(r==KErrNone);
       
   126 
       
   127 #ifdef TEST_WRITE_OVERHEAD
       
   128     RThread writeZeroThread;
       
   129 	r=writeZeroThread.Create(_L("WRITERZERO"),WriteZeroThread,KDefaultStackSize,&User::Heap(),NULL);
       
   130 	test(r==KErrNone);
       
   131 #endif
       
   132 
       
   133 	r = CountSem.CreateLocal(1);
       
   134 	test(r==KErrNone);
       
   135 
       
   136 
       
   137 	StopTest = EFalse;	// allow the test to run
       
   138 
       
   139     TRequestStatus deadStatWrite;
       
   140     TRequestStatus deadStatCpu;
       
   141 	writeThread.Logon( deadStatWrite );
       
   142 	cpuThread.Logon( deadStatCpu );
       
   143 	
       
   144 	// make writer thread have priority over CPU usage thread
       
   145 	writeThread.SetPriority( EPriorityMore );
       
   146 
       
   147 	// make this thread highest priority
       
   148 	RThread().SetPriority( EPriorityMuchMore );
       
   149 	
       
   150 	
       
   151     cpuThread.Resume();
       
   152 	
       
   153 #ifdef TEST_WRITE_OVERHEAD
       
   154     TRequestStatus deadStatWriteZero;
       
   155 	writeZeroThread.Logon( deadStatWriteZero );
       
   156 	// make writer thread have priority over CPU usage thread
       
   157 	writeZeroThread.SetPriority( EPriorityMore );
       
   158 	StopZeroTest = EFalse;
       
   159 	writeZeroThread.Resume();
       
   160 #endif
       
   161 	
       
   162 	// wait for thread to initialise
       
   163 	User::After(1000000);
       
   164 
       
   165 	CountSem.Wait();
       
   166 	Count=0;
       
   167 	CountSem.Signal();
       
   168 
       
   169     User::After(KAverageOverInSeconds*1000000);
       
   170     
       
   171 	CountSem.Wait();
       
   172 	TInt64 noWriteCount( Count );	// number of counts when not writing
       
   173 	CountSem.Signal();
       
   174 
       
   175 	
       
   176 #ifdef TEST_WRITE_OVERHEAD
       
   177 	// kill the zero writer
       
   178 	StopZeroTest = ETrue;
       
   179 	User::WaitForRequest( deadStatWriteZero );
       
   180 	CLOSE_AND_WAIT(writeZeroThread);
       
   181 #endif
       
   182     
       
   183 	test.Printf( _L("Loops without writing = %ld"), noWriteCount );
       
   184 	
       
   185 	// start write thread
       
   186 	writeThread.Resume();
       
   187 	User::After(1000000);
       
   188     
       
   189 	CountSem.Wait();
       
   190 	Count=0;
       
   191 	CountSem.Signal();
       
   192 
       
   193     User::After(KAverageOverInSeconds*1000000);
       
   194     
       
   195 	CountSem.Wait();
       
   196 	TInt64 withWriteCount( Count );	// number of counts when writing
       
   197 	CountSem.Signal();
       
   198 
       
   199 	test.Printf( _L("Loops while writing = %ld"), withWriteCount );
       
   200 	
       
   201 	// tell test to stop and wait for thread to exit.
       
   202 	cpuThread.Kill(KErrNone);
       
   203 	StopTest = ETrue;
       
   204 	User::WaitForRequest( deadStatWrite );
       
   205 	
       
   206 	CLOSE_AND_WAIT(writeThread);
       
   207 	CLOSE_AND_WAIT(cpuThread);
       
   208     
       
   209 
       
   210 
       
   211 	TInt64 calc( withWriteCount );
       
   212 	calc = calc * 100;
       
   213 	calc = calc / noWriteCount;
       
   214 		
       
   215 	test.Printf( _L("%% CPU used = %d"), 100 - I64LOW(calc) );
       
   216     }
       
   217 
       
   218 
       
   219 
       
   220 LOCAL_C TInt EraseSegment( TInt aSegmentNumber )
       
   221 	/**
       
   222 	 * Erases a segment on Flash
       
   223 	 *
       
   224 	 * @param aSegmentNumber index of segment to erase
       
   225 	 * @return KErrNone or error code
       
   226 	 */
       
   227 	{
       
   228 	TInt offset = aSegmentNumber * driveInfo().iEraseBlockSize;
       
   229 	
       
   230 	TInt r = drive.Format( offset, driveInfo().iEraseBlockSize );
       
   231 	test.Printf( _L("erase returns %d"), r );
       
   232 	return  r;
       
   233 	}
       
   234 
       
   235 
       
   236 
       
   237 
       
   238 void Initialize()
       
   239 	/**
       
   240 	 * Open channel to media driver
       
   241 	 */
       
   242 	{
       
   243 	//
       
   244 	// Load the media driver
       
   245 	//
       
   246 #ifndef SKIP_PDD_LOAD
       
   247 	test.Printf( _L("Loading %S\n"), &KLfsDriverName );
       
   248 	TInt r = User::LoadPhysicalDevice( KLfsDriverName );
       
   249 	test( KErrNone == r || KErrAlreadyExists == r );
       
   250 #endif
       
   251 
       
   252 #ifdef UNMOUNT_DRIVE
       
   253 	RFs fs;
       
   254 	test( KErrNone == fs.Connect() );
       
   255 #if 0
       
   256 	// XXX not EKA2
       
   257 	test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) );
       
   258 #endif
       
   259 	TFullName name;
       
   260 	fs.FileSystemName( name, KLffsLogicalDriveNumber );
       
   261 	if( name.Length() > 0 )
       
   262 		{
       
   263 		test.Printf( _L("Unmounting drive") );
       
   264 		test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) );
       
   265 		User::After( 2000000 );
       
   266 		test.Printf( _L("Drive unmounted") );
       
   267 		}
       
   268 	fs.Close();
       
   269 #endif
       
   270 
       
   271 	//
       
   272 	// Open a TBusLogicalDevice to it
       
   273 	//
       
   274 	test.Printf( _L("Opening media channel\n") );
       
   275 	TBool changedFlag = EFalse;
       
   276 	test( KErrNone == drive.Connect( KDriveNumber, changedFlag ) );
       
   277 	
       
   278 	//
       
   279 	// Get size of Flash drive, block size, block count
       
   280 	//
       
   281     drive.Caps(driveInfo);
       
   282 	}
       
   283 
       
   284 
       
   285 
       
   286 TInt E32Main()
       
   287     {
       
   288 
       
   289     test.Title();
       
   290     test.Start(_L("Testing CPU overhead"));
       
   291 
       
   292 	Initialize();
       
   293 
       
   294 	test.Printf( _L("Erasing first segment") );
       
   295 	TInt r = EraseSegment( 0 );
       
   296 	test( KErrNone == r );
       
   297 	test.Printf( _L("Segment erased") );
       
   298 
       
   299 	runTest();
       
   300 
       
   301 	drive.Disconnect();
       
   302     test.End();
       
   303 	return(KErrNone);
       
   304     }
       
   305