|
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 // Performs some benchmarking of the LFFS media driver |
|
15 // |
|
16 // |
|
17 |
|
18 /** |
|
19 @file bf_raw.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 "bf_raw.h" |
|
29 #include "user_config.h" |
|
30 |
|
31 const TInt KAverageOverInSeconds=10; ///< Number of seconds to run tests for |
|
32 |
|
33 //TInt64 Count; ///< Global variable used to count number of operations completed |
|
34 TUint32 Count; |
|
35 |
|
36 RTest test(_L("BF_RAW")); |
|
37 |
|
38 |
|
39 TTestInfo TestInfo; ///< Data passed to exector thread |
|
40 |
|
41 TBusLocalDrive drive; |
|
42 TLocalDriveCapsV2Buf driveInfo; |
|
43 |
|
44 GLDEF_D HBufC8* writeBuffer; ///< Buffer for transferring data |
|
45 GLDEF_D HBufC8* readBuffer; ///< Buffer for transferring data |
|
46 |
|
47 GLDEF_D TBool StopTest; ///< set to ETrue to stop the test |
|
48 |
|
49 |
|
50 GLREF_C TInt BmWrite(TAny*); |
|
51 GLREF_C TInt BmWriteThread(TAny*); |
|
52 GLREF_C TInt BmRead(TAny*); |
|
53 GLREF_C TInt BmReadThread(TAny*); |
|
54 |
|
55 GLDEF_D TInt mainThreadHandle; |
|
56 |
|
57 TUint32 runTest(TThreadFunction aFunction) |
|
58 /** |
|
59 * Function which actually runs the test. |
|
60 * |
|
61 * It creates a new thread to exeute the operations and then waits |
|
62 * for a pre-determined time. The executor thread increments a counter |
|
63 * each time it completes one operation. After the time period expires |
|
64 * the counter is averaged to get an "operations per second". This is |
|
65 * then multiplied by the data size to obtain tranfer rate |
|
66 */ |
|
67 { |
|
68 |
|
69 RThread thread; |
|
70 TInt r=thread.Create(_L("TESTER"),aFunction,KDefaultStackSize,&User::Heap(),NULL); |
|
71 if(r!=KErrNone) |
|
72 { |
|
73 test.Printf(_L("Failed to create thread with error %d\n"),r); |
|
74 return(r); |
|
75 } |
|
76 StopTest = EFalse; // allow the test to run |
|
77 TRequestStatus deadStat; |
|
78 thread.Logon( deadStat ); |
|
79 |
|
80 RThread().SetPriority( EPriorityMuchMore ); |
|
81 |
|
82 thread.Resume(); |
|
83 User::After(1000000); |
|
84 Count=0; |
|
85 User::After(KAverageOverInSeconds*1000000); |
|
86 TUint32 result=Count; |
|
87 |
|
88 // tell test to stop and wait for thread to exit. |
|
89 StopTest = ETrue; |
|
90 User::WaitForRequest( deadStat ); |
|
91 |
|
92 CLOSE_AND_WAIT(thread); |
|
93 return(result); |
|
94 } |
|
95 |
|
96 void PrintResult( TUint32 aCount, const TDesC& aTitle ) |
|
97 /** |
|
98 * Prints result of test |
|
99 */ |
|
100 { |
|
101 TInt64 count(static_cast<TUint>(aCount)); |
|
102 TInt64 transferRate = (count * TestInfo.iLength) / KAverageOverInSeconds; |
|
103 |
|
104 test.Printf(_L("%S: %d bytes/second\n"), |
|
105 &aTitle, |
|
106 I64LOW(transferRate) ); |
|
107 } |
|
108 |
|
109 |
|
110 LOCAL_C TInt EraseSegment( TInt aSegmentNumber ) |
|
111 /** |
|
112 * Erases a segment on Flash |
|
113 * |
|
114 * @param aSegmentNumber index of segment to erase |
|
115 * @return KErrNone or error code |
|
116 */ |
|
117 { |
|
118 TInt offset = aSegmentNumber * driveInfo().iEraseBlockSize; |
|
119 |
|
120 TInt r = drive.Format( offset, driveInfo().iEraseBlockSize ); |
|
121 return r; |
|
122 } |
|
123 |
|
124 |
|
125 /** |
|
126 * Structure defining tests |
|
127 */ |
|
128 class TTestData |
|
129 { |
|
130 public: |
|
131 TThreadFunction iFunction; ///< function to execute, NULL for end of list |
|
132 TInt iLength; ///< data length |
|
133 TInt iOffset; ///< Flash offset |
|
134 const TDesC* iDescription; ///< descriptive text |
|
135 }; |
|
136 |
|
137 |
|
138 _LIT( KErasingSegment0, "Erasing segment 0" ); |
|
139 |
|
140 _LIT( KWrite1Start, "Write, 1 byte, 32-byte boundary, current thread" ); |
|
141 _LIT( KWrite24Start, "Write, 24 bytes, 32-byte boundary, current thread" ); |
|
142 _LIT( KWrite64Start, "Write, 64 bytes, 32-byte boundary, current thread" ); |
|
143 _LIT( KWrite512Start, "Write, 512 bytes, 32-byte boundary, current thread" ); |
|
144 |
|
145 _LIT( KRead1Start, "Read, 1 byte, 32-byte boundary, current thread" ); |
|
146 _LIT( KRead24Start, "Read, 24 bytes, 32-byte boundary, current thread" ); |
|
147 _LIT( KRead64Start, "Read, 64 bytes, 32-byte boundary, current thread" ); |
|
148 _LIT( KRead512Start, "Read, 512 bytes, 32-byte boundary, current thread" ); |
|
149 |
|
150 const TThreadFunction KEraseSegment = (TThreadFunction)0x000000F1; |
|
151 |
|
152 const TTestData testData[] = ///< the test data |
|
153 { |
|
154 { KEraseSegment, 0, 0, &KErasingSegment0 }, |
|
155 |
|
156 { BmWrite, 1, 0, &KWrite1Start }, |
|
157 { BmWrite, 24, 32, &KWrite24Start }, |
|
158 { BmWrite, 64, 64, &KWrite64Start }, |
|
159 { BmWrite, 512, 128, &KWrite512Start }, |
|
160 |
|
161 { BmRead, 1, 0, &KRead1Start }, |
|
162 { BmRead, 24, 0, &KRead24Start }, |
|
163 { BmRead, 64, 0, &KRead64Start }, |
|
164 { BmRead, 512, 0, &KRead512Start }, |
|
165 |
|
166 { NULL, 0, 0, NULL } |
|
167 }; |
|
168 |
|
169 |
|
170 |
|
171 void Initialize() |
|
172 /** |
|
173 * Open channel to media driver |
|
174 */ |
|
175 { |
|
176 // |
|
177 // Load the media driver |
|
178 // |
|
179 #ifndef SKIP_PDD_LOAD |
|
180 test.Printf( _L("Loading %S\n"), &KLfsDriverName ); |
|
181 TInt r = User::LoadPhysicalDevice( KLfsDriverName ); |
|
182 test( KErrNone == r || KErrAlreadyExists == r ); |
|
183 #endif |
|
184 |
|
185 #ifdef UNMOUNT_DRIVE |
|
186 RFs fs; |
|
187 test( KErrNone == fs.Connect() ); |
|
188 #if 0 |
|
189 // XXX - not EKA2 |
|
190 test( KErrNone == fs.SetDefaultPath( _L("Z:\\") ) ); |
|
191 #endif |
|
192 TFullName name; |
|
193 fs.FileSystemName( name, KLffsLogicalDriveNumber ); |
|
194 if( name.Length() > 0 ) |
|
195 { |
|
196 test.Printf( _L("Unmounting drive") ); |
|
197 test( KErrNone == fs.DismountFileSystem( _L("Lffs"), KLffsLogicalDriveNumber) ); |
|
198 User::After( 2000000 ); |
|
199 test.Printf( _L("Drive unmounted") ); |
|
200 } |
|
201 fs.Close(); |
|
202 #endif |
|
203 |
|
204 // |
|
205 // Open a TBusLogicalDevice to it |
|
206 // |
|
207 test.Printf( _L("Opening media channel\n") ); |
|
208 TBool changedFlag = EFalse; |
|
209 test( KErrNone == drive.Connect( KDriveNumber, changedFlag ) ); |
|
210 |
|
211 // |
|
212 // Get size of Flash drive, block size, block count |
|
213 // |
|
214 drive.Caps(driveInfo); |
|
215 |
|
216 // |
|
217 // Create data buffer |
|
218 // |
|
219 writeBuffer = HBufC8::New( 1024 ); |
|
220 test( NULL != writeBuffer ); |
|
221 writeBuffer->Des().FillZ(1024); |
|
222 |
|
223 readBuffer = HBufC8::New( 1024 ); |
|
224 test( NULL != readBuffer ); |
|
225 readBuffer->Des().FillZ(1024); |
|
226 |
|
227 mainThreadHandle = RThread().Handle(); |
|
228 } |
|
229 |
|
230 |
|
231 |
|
232 TInt E32Main() |
|
233 { |
|
234 |
|
235 test.Title(); |
|
236 test.Start(_L("Benchmarks for media driver")); |
|
237 |
|
238 Initialize(); |
|
239 |
|
240 const TTestData* pTest = &testData[0]; |
|
241 while( pTest->iFunction ) |
|
242 { |
|
243 if( KEraseSegment == pTest->iFunction ) |
|
244 { |
|
245 test.Printf( *pTest->iDescription ); |
|
246 TInt r = EraseSegment( pTest->iOffset ); |
|
247 test( KErrNone == r ); |
|
248 test.Printf( _L("Segment erased") ); |
|
249 } |
|
250 else |
|
251 { |
|
252 TestInfo.iLength = pTest->iLength; |
|
253 TestInfo.iOffset = pTest->iOffset; |
|
254 PrintResult( runTest( pTest->iFunction ), *pTest->iDescription ); |
|
255 } |
|
256 ++pTest; |
|
257 } |
|
258 |
|
259 drive.Disconnect(); |
|
260 test.End(); |
|
261 return(KErrNone); |
|
262 } |
|
263 |