os/kernelhwsrv/kerneltest/e32test/lffs/bf_cpu.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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