|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // Include Files |
|
20 |
|
21 #include "DebOutWriterPlugin.h" |
|
22 #include <e32base.h> |
|
23 #include <piprofiler/EngineUIDs.h> |
|
24 #include <piprofiler/ProfilerTraces.h> |
|
25 #ifdef OST_TRACE_COMPILER_IN_USE |
|
26 #include <OpenSystemTrace.h> |
|
27 #include "DebOutWriterPluginTraces.h" |
|
28 #endif |
|
29 |
|
30 // engine properties |
|
31 const TUid KEngineStatusPropertyCat={0x2001E5AD}; |
|
32 enum TEnginePropertyKeys |
|
33 { |
|
34 EProfilerEngineStatus = 8, |
|
35 EProfilerErrorStatus |
|
36 }; |
|
37 // Member Functions |
|
38 /* |
|
39 * |
|
40 * Class CDebOutWriterPlugin implementation |
|
41 * |
|
42 */ |
|
43 |
|
44 CDebOutWriterPlugin* CDebOutWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/) |
|
45 { |
|
46 LOGTEXT(_L("CDebOutWriterPlugin::NewL() - entry")); |
|
47 CDebOutWriterPlugin* self = new (ELeave) CDebOutWriterPlugin(KDebOutWriterPluginUid); |
|
48 CleanupStack::PushL( self ); |
|
49 self->ConstructL(); |
|
50 CleanupStack::Pop(); |
|
51 LOGTEXT(_L("CDebOutWriterPlugin::NewL() - exit")); |
|
52 return self; |
|
53 } |
|
54 |
|
55 CDebOutWriterPlugin::CDebOutWriterPlugin(const TUid aImplementationUid) : |
|
56 iWriterType(aImplementationUid.iUid) |
|
57 { |
|
58 LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - entry")); |
|
59 isEnabled = EFalse; |
|
60 iWriterId = Id().iUid; |
|
61 LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - exit")); |
|
62 } |
|
63 |
|
64 CDebOutWriterPlugin::~CDebOutWriterPlugin() |
|
65 { |
|
66 LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - entry")); |
|
67 |
|
68 iErrorStatus.Close(); |
|
69 |
|
70 if(iWriterHandler) |
|
71 { |
|
72 iWriterHandler->Cancel(); |
|
73 delete iWriterHandler; |
|
74 } |
|
75 LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - exit")); |
|
76 } |
|
77 |
|
78 void CDebOutWriterPlugin::ConstructL() |
|
79 { |
|
80 // second phase constructor, anything that may leave must be constructed here |
|
81 |
|
82 LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - entry")); |
|
83 iWriterHandler = CDebOutWriterHandler::NewL(this); |
|
84 User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus)); |
|
85 LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - exit")); |
|
86 } |
|
87 |
|
88 TInt CDebOutWriterPlugin::Start() |
|
89 { |
|
90 LOGTEXT(_L("CDebOutWriterPlugin::Start() - entry")); |
|
91 // if(isEnabled) |
|
92 // { |
|
93 // TRAPD(err,iWriterHandler->StartL()); |
|
94 // if( err != KErrNone ) |
|
95 // { |
|
96 // LOGTEXT(_L("Could not start writer plugin")); |
|
97 // return err; |
|
98 // } |
|
99 // } |
|
100 LOGTEXT(_L("CDebOutWriterPlugin::Start() - exit")); |
|
101 return KErrNone; |
|
102 } |
|
103 |
|
104 void CDebOutWriterPlugin::Stop() |
|
105 { |
|
106 LOGTEXT(_L("CDebOutWriterPlugin::Stop() - entry")); |
|
107 iWriterHandler->Stop(); |
|
108 LOGTEXT(_L("CDebOutWriterPlugin::Stop() - exit")); |
|
109 } |
|
110 |
|
111 void CDebOutWriterPlugin::GetCaption( TDes& aCaption ) const |
|
112 { |
|
113 aCaption.Copy(KDebOutShortName); |
|
114 aCaption.TrimRight(); |
|
115 LOGSTRING2("CDebOutWriterPlugin::GetCaptionL() - Plugin name: %S", &aCaption); |
|
116 } |
|
117 |
|
118 TUid CDebOutWriterPlugin::Id() const |
|
119 { |
|
120 LOGSTRING2("CDebOutWriterPlugin::Id(): 0x%X", KDebOutWriterPluginUid.iUid ); |
|
121 return KDebOutWriterPluginUid; |
|
122 //return iDtor_ID_Key; |
|
123 } |
|
124 |
|
125 TBool CDebOutWriterPlugin::GetEnabled() |
|
126 { |
|
127 return isEnabled; |
|
128 } |
|
129 |
|
130 void CDebOutWriterPlugin::SetValue( const TWriterPluginValueKeys aKey, |
|
131 TDes& aValue ) |
|
132 { |
|
133 TRAP_IGNORE( SetValueL( aKey, aValue ) ); |
|
134 } |
|
135 |
|
136 |
|
137 void CDebOutWriterPlugin::GetValue( const TWriterPluginValueKeys aKey, |
|
138 TDes& aValue ) |
|
139 { |
|
140 TRAP_IGNORE( GetValueL( aKey, aValue ) ); |
|
141 } |
|
142 |
|
143 |
|
144 |
|
145 void CDebOutWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& /*aValue*/ ) |
|
146 { |
|
147 LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - entry")); |
|
148 |
|
149 switch( aKey ) |
|
150 { |
|
151 case EWriterPluginEnabled: |
|
152 isEnabled = ETrue; |
|
153 LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled")); |
|
154 break; |
|
155 case EWriterPluginDisabled: |
|
156 isEnabled = EFalse; |
|
157 LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled")); |
|
158 break; |
|
159 case EWriterPluginSettings: |
|
160 //result = StringLoader::LoadL(PROFILER_KERNEL_MODE_SAMPLER); |
|
161 LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - setting plugin settings")); |
|
162 break; |
|
163 default: |
|
164 break; |
|
165 } |
|
166 LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - exit")); |
|
167 |
|
168 } |
|
169 |
|
170 TUint32 CDebOutWriterPlugin::GetWriterType() |
|
171 { |
|
172 return iWriterType; |
|
173 } |
|
174 |
|
175 |
|
176 void CDebOutWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue ) |
|
177 { |
|
178 switch( aKey ) |
|
179 { |
|
180 case EWriterPluginVersion: |
|
181 |
|
182 GetWriterVersion(&aValue); |
|
183 break; |
|
184 case EWriterPluginType: |
|
185 break; |
|
186 default: |
|
187 break; |
|
188 } |
|
189 } |
|
190 |
|
191 void CDebOutWriterPlugin::GetWriterVersion(TDes* aDes) |
|
192 { |
|
193 _LIT(KDebugOutputWriterVersion, "1.0.0"); |
|
194 aDes->Append(KDebugOutputWriterVersion); |
|
195 } |
|
196 |
|
197 void CDebOutWriterPlugin::DoCancel() |
|
198 { |
|
199 LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry")); |
|
200 } |
|
201 |
|
202 void CDebOutWriterPlugin::WriteData() |
|
203 { |
|
204 // Activate handler to write data from buffer to output |
|
205 LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry")); |
|
206 iWriterHandler->StartL(); |
|
207 LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit")); |
|
208 } |
|
209 |
|
210 void CDebOutWriterPlugin::HandleError(TInt aError) |
|
211 { |
|
212 TInt err(KErrNone); |
|
213 err = iErrorStatus.Set(aError); |
|
214 if(err != KErrNone) |
|
215 { |
|
216 RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error: %d"), err); |
|
217 } |
|
218 } |
|
219 |
|
220 void CDebOutWriterPlugin::PrintDescriptorAsBase64( TDesC8& aDes, |
|
221 TRequestStatus* aStatus, |
|
222 TUint32 sampleTime, |
|
223 TBool aEmptying) |
|
224 { |
|
225 LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - entry")); |
|
226 TUint len = aDes.Length(); |
|
227 |
|
228 // we must wait for the sample tick to be printed, in case |
|
229 // prints are performed at user side, otherwise the kernel |
|
230 // prints will corrupt the data |
|
231 if(sampleTime != 0xffffffff) |
|
232 { |
|
233 TUint32 remains = sampleTime%1000; |
|
234 |
|
235 if(remains > 800) |
|
236 { |
|
237 TTimeIntervalMicroSeconds32 timeToWait = ((1050-remains)*1000); |
|
238 User::After(timeToWait); |
|
239 } |
|
240 } |
|
241 |
|
242 TBuf16<75> buf; |
|
243 |
|
244 // Header |
|
245 #ifdef OST_TRACE_COMPILER_IN_USE |
|
246 // OstTrace0( TRACE_PERFORMANCE, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START, |
|
247 // "<PIPROF>=================================================================" ); |
|
248 #else |
|
249 RDebug::Print(_L("<PIPROF>=================================================================")); |
|
250 #endif |
|
251 buf.Zero(); |
|
252 |
|
253 // base64 encoding table |
|
254 const char uu_base64[64] = |
|
255 { |
|
256 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', |
|
257 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', |
|
258 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', |
|
259 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', |
|
260 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', |
|
261 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', |
|
262 'w', 'x', 'y', 'z', '0', '1', '2', '3', |
|
263 '4', '5', '6', '7', '8', '9', '+', '/' |
|
264 }; |
|
265 |
|
266 TChar byte1, byte2, byte3, byte4; |
|
267 TUint8 count = 0x30; |
|
268 // base64 encoding |
|
269 for(TUint i = 0, j = 0; i < len; i += 3, j = (j + 1) % 18) |
|
270 { |
|
271 // byte 1 |
|
272 byte1 = uu_base64[(aDes[i] >> 2) & 0x3F]; |
|
273 |
|
274 // byte 2 |
|
275 if(i+1 < len) |
|
276 byte2 = uu_base64[(aDes[i] << 4) & 0x3f | (aDes[i+1] >> 4)]; |
|
277 else |
|
278 byte2 = uu_base64[(aDes[i] << 4) & 0x3f]; |
|
279 |
|
280 // byte 3 |
|
281 if(i+1 < len && i+2 < len) |
|
282 byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f | (aDes[i+2] >> 6)]; |
|
283 else if(i+1 < len) |
|
284 byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f]; |
|
285 else |
|
286 byte3 = '='; |
|
287 |
|
288 // byte 4 |
|
289 if(i+2 < len) |
|
290 byte4 = uu_base64[aDes[i+2] & 0x3f]; |
|
291 else |
|
292 byte4 = '='; |
|
293 |
|
294 // append to buffer |
|
295 buf.Append(byte1); |
|
296 buf.Append(byte2); |
|
297 buf.Append(byte3); |
|
298 buf.Append(byte4); |
|
299 |
|
300 // output 72 chars / line |
|
301 if(j == 17) |
|
302 { |
|
303 // add check number at the end of line |
|
304 buf.Append(count); |
|
305 #ifdef OST_TRACE_COMPILER_IN_USE |
|
306 // OstTraceExt1( TRACE_PERFORMANCE, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE, "<PIPROF>%S", &buf ); |
|
307 #else |
|
308 RDebug::Print(_L("<PIPROF>%S"),&buf); |
|
309 #endif |
|
310 count++; |
|
311 if(count > 0x39) |
|
312 count = 0x30; |
|
313 buf.Zero(); |
|
314 } |
|
315 } |
|
316 |
|
317 #ifdef OST_TRACE_COMPILER_IN_USE |
|
318 // OstTraceExt1( TRACE_PERFORMANCE, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN, "<PIPROF>%S", &buf ); |
|
319 #else |
|
320 RDebug::Print(_L("<PIPROF>%S"),&buf); |
|
321 #endif |
|
322 buf.Zero(); |
|
323 |
|
324 // footer |
|
325 #ifdef OST_TRACE_COMPILER_IN_USE |
|
326 // OstTrace0( TRACE_PERFORMANCE, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END, |
|
327 // "<PIPROF>=================================================================" ); |
|
328 #else |
|
329 RDebug::Print(_L("<PIPROF>=================================================================")); |
|
330 #endif |
|
331 |
|
332 if(!aEmptying) |
|
333 { |
|
334 if(aStatus != 0) |
|
335 User::RequestComplete(aStatus,0); |
|
336 } |
|
337 |
|
338 LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - exit")); |
|
339 } |
|
340 |
|
341 |
|
342 |
|
343 /* |
|
344 * |
|
345 * Implementation of class CDebOutWriterHandler |
|
346 * |
|
347 */ |
|
348 CDebOutWriterHandler::CDebOutWriterHandler(CDebOutWriterPlugin* aWriter) : |
|
349 CActive(EPriorityStandard) |
|
350 { |
|
351 LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - entry")); |
|
352 iWriter = aWriter; |
|
353 |
|
354 // set initial mode to non-stopping |
|
355 iStopping = EFalse; |
|
356 |
|
357 // add the handler to the active scheduler |
|
358 CActiveScheduler::Add(this); |
|
359 LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - exit")); |
|
360 } |
|
361 |
|
362 CDebOutWriterHandler* CDebOutWriterHandler::NewL(CDebOutWriterPlugin* aWriter) |
|
363 { |
|
364 LOGTEXT(_L("CDebOutWriterHandler::NewL() - entry")); |
|
365 CDebOutWriterHandler* self = new (ELeave) CDebOutWriterHandler(aWriter); |
|
366 CleanupStack::PushL( self ); |
|
367 self->ConstructL(); |
|
368 CleanupStack::Pop(); |
|
369 LOGTEXT(_L("CDebOutWriterHandler::NewL() - exit")); |
|
370 return self; |
|
371 } |
|
372 |
|
373 CDebOutWriterHandler::~CDebOutWriterHandler() |
|
374 { |
|
375 LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - entry")); |
|
376 |
|
377 LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - exit")); |
|
378 } |
|
379 |
|
380 void CDebOutWriterHandler::ConstructL() |
|
381 { |
|
382 |
|
383 } |
|
384 |
|
385 void CDebOutWriterHandler::StartL() |
|
386 { |
|
387 LOGTEXT(_L("CDebOutWriterHandler::StartL - entry")); |
|
388 if(!IsActive()) |
|
389 { |
|
390 LOGTEXT(_L("CDiskWriterHandler::StartL - is not active")); |
|
391 |
|
392 TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer(); |
|
393 LOGSTRING2(_L("CDiskWriterHandler::StartL - got next filled 0x%x"),nextBuf); |
|
394 |
|
395 if(nextBuf != 0) |
|
396 { |
|
397 LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file")); |
|
398 WriteBufferToOutput(nextBuf); |
|
399 } |
|
400 } |
|
401 LOGTEXT(_L("CDebOutWriterHandler::StartL - entry")); |
|
402 } |
|
403 |
|
404 void CDebOutWriterHandler::Stop() |
|
405 { |
|
406 LOGTEXT(_L("CDebOutWriterHandler::Stop - entry")); |
|
407 |
|
408 // do write once more to write the logged data to output |
|
409 // set to stopping mode, needed for emptying the remaining full buffers |
|
410 iStopping = ETrue; |
|
411 |
|
412 // stop the timer |
|
413 Reset(); |
|
414 |
|
415 // set mode back to non-stopping |
|
416 iStopping = EFalse; |
|
417 LOGTEXT(_L("CDebOutWriterHandler::Stop - exit")); |
|
418 } |
|
419 |
|
420 void CDebOutWriterHandler::Reset() |
|
421 { |
|
422 |
|
423 // start writing new buffer if there is one available |
|
424 TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer(); |
|
425 |
|
426 // empty the rest of the buffers synchronously |
|
427 while(nextBuf != 0) |
|
428 { |
|
429 if(nextBuf->iDataSize != 0) |
|
430 { |
|
431 LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file")); |
|
432 iWriter->PrintDescriptorAsBase64(*(nextBuf->iBufDes),&iStatus,0xffffffff, iStopping); |
|
433 } |
|
434 |
|
435 // empty buffers when profiling stopped |
|
436 iWriter->iStream->AddToFreeBuffers(nextBuf); |
|
437 |
|
438 LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer")); |
|
439 // start writing new buffer if there is one available |
|
440 nextBuf = iWriter->iStream->GetNextFilledBuffer(); |
|
441 LOGSTRING2(_L("CDiskWriterHandler::Reset - got next filled 0x%x"),nextBuf); |
|
442 } |
|
443 } |
|
444 |
|
445 void CDebOutWriterHandler::HandleFullBuffers() |
|
446 { |
|
447 LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry")); |
|
448 // previous write operation has finished |
|
449 // release the previous buffer |
|
450 iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten); |
|
451 |
|
452 LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer")); |
|
453 // start writing new buffer if there is one available |
|
454 TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer(); |
|
455 |
|
456 if(nextBuf != 0) |
|
457 { |
|
458 LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file")); |
|
459 if(nextBuf->iDataSize != 0) |
|
460 { |
|
461 WriteBufferToOutput(nextBuf); |
|
462 } |
|
463 } |
|
464 LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit")); |
|
465 } |
|
466 |
|
467 void CDebOutWriterHandler::RunL() |
|
468 { |
|
469 // call function to complete full buffer handling |
|
470 HandleFullBuffers(); |
|
471 } |
|
472 |
|
473 void CDebOutWriterHandler::DoCancel() |
|
474 { |
|
475 |
|
476 } |
|
477 |
|
478 void CDebOutWriterHandler::WriteBufferToOutput(TBapBuf* aBuf) |
|
479 { |
|
480 LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - entry")); |
|
481 iBufferBeingWritten = aBuf; |
|
482 |
|
483 // set the data length just to be sure |
|
484 iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize); |
|
485 |
|
486 LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file")); |
|
487 // PrintBufferToOutput(iBufferBeingWritten, iStatus); |
|
488 iWriter->PrintDescriptorAsBase64(*(iBufferBeingWritten->iBufDes),&iStatus,0xffffffff, iStopping); |
|
489 // set AO back to active, until filled buffers are emptied |
|
490 SetActive(); |
|
491 |
|
492 LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - exit")); |
|
493 } |
|
494 |
|
495 // private |
|
496 void CDebOutWriterHandler::PrintBufferToOutput(TBapBuf* aBuffer, TRequestStatus& aStatus) |
|
497 { |
|
498 LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput() - debug out writer tick activated")); |
|
499 |
|
500 TPtrC8& aDes = (TPtrC8&)*(aBuffer->iBufDes); |
|
501 #ifdef BAPPEA_SAMPLE_MARKS |
|
502 TUint32 time = iSampler->GetSampleTime(); |
|
503 #else |
|
504 TUint32 time = 0xffffffff; |
|
505 #endif |
|
506 iWriter->PrintDescriptorAsBase64(aDes,&aStatus,time, iStopping); |
|
507 } |
|
508 |