|
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 <piprofiler/ProfilerVersion.h> |
|
20 |
|
21 #include <kern_priv.h> |
|
22 #include <plat_priv.h> |
|
23 |
|
24 #include "IttSamplerImpl.h" |
|
25 |
|
26 /* |
|
27 * |
|
28 * ITT sampler definition |
|
29 * |
|
30 */ |
|
31 |
|
32 IttSamplerImpl::IttSamplerImpl() |
|
33 { |
|
34 this->ptrToData = new TPtr8(((TUint8*)&(this->internalData[1])),255); |
|
35 this->currentLibCount = 0; |
|
36 this->currentProcCount = 0; |
|
37 this->iSampleProcesses = false; |
|
38 |
|
39 this->Reset(); |
|
40 } |
|
41 |
|
42 IttSamplerImpl::~IttSamplerImpl() |
|
43 { |
|
44 delete(this->ptrToData); |
|
45 } |
|
46 |
|
47 TInt IttSamplerImpl::CreateFirstSample() |
|
48 { |
|
49 this->iVersionData.Zero(); |
|
50 this->iVersionData.Append(_L8("Bappea_ITT_V")); |
|
51 this->iVersionData.Append(PROFILER_ITT_SAMPLER_VERSION); |
|
52 this->itt_sample = (TUint8*)iVersionData.Ptr(); |
|
53 return iVersionData.Length(); |
|
54 } |
|
55 |
|
56 TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum) |
|
57 { |
|
58 return true; |
|
59 } |
|
60 |
|
61 TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum) |
|
62 { |
|
63 // in order to avoid overloading the interrupt |
|
64 // only one dynamic file in each 50ms is added to the stream |
|
65 // with the application of the tool in mind, this is |
|
66 // a reasonable measure |
|
67 |
|
68 // #ifdef ITT_TEST |
|
69 //if(iSampleProcesses) |
|
70 { |
|
71 // encode a process binary |
|
72 ptrToData->Zero(); |
|
73 |
|
74 //static RPointerArray<DCodeSeg> array = DCodeSeg::CodeSegsByName; |
|
75 //TInt arrayCount = array.Count(); |
|
76 |
|
77 /* mietintää... |
|
78 |
|
79 DCodeSeg* pSeg = Kern::CodeSegFromAddress( (TLinAddr)aPtr, TheCurrentThread->iOwningProcess ); |
|
80 if (!pSeg) |
|
81 { |
|
82 return KErrNotFound; |
|
83 } |
|
84 Kern::KUDesPut(aModuleName, *pSeg->iFileName); |
|
85 |
|
86 // lisää pohdintaa |
|
87 |
|
88 TInt n=0; |
|
89 TInt i; |
|
90 TInt c=iDynamicCode.Count(); // DProcess.iDynamicCode, type = RArray<SCodeSegEntry>, SCodeSegEntry->iSeg/iLib |
|
91 for (i=-1; i<c; ++i) |
|
92 { |
|
93 DCodeSeg* pS=(i<0)?iCodeSeg:iDynamicCode[i].iSeg; |
|
94 if (pS && pS!=aExclude) |
|
95 { |
|
96 if ((aFlags & ETraverseFlagRestrict) && i>=0) |
|
97 { |
|
98 DLibrary* pL=iDynamicCode[i].iLib; |
|
99 if (pL && pL->iState!=DLibrary::EAttached) |
|
100 continue; |
|
101 } |
|
102 if (aFlags & ETraverseFlagAdd) |
|
103 n+=pS->ListDeps(aQ,aMark); |
|
104 else |
|
105 n+=pS->UnListDeps(aMark); |
|
106 } |
|
107 } |
|
108 |
|
109 |
|
110 */ |
|
111 |
|
112 /* |
|
113 // testi... |
|
114 // encode a process binary |
|
115 //Kern::Printf("Get Processes from container..."); |
|
116 DObjectCon* proc = Kern::Containers()[EProcess]; |
|
117 TInt procCount = proc->Count(); |
|
118 |
|
119 //Kern::Printf("Got count of processes: %d", procCount); |
|
120 |
|
121 // go 20 executables through at a time |
|
122 for(TInt i=0;i<procCount;i++) |
|
123 { |
|
124 DProcess* pro = (DProcess*)(*proc)[i]; |
|
125 |
|
126 //Kern::Printf("Inspecting DProcess array..."); |
|
127 |
|
128 TInt c=pro->iDynamicCode.Count(); // DProcess.iDynamicCode, type = RArray<SCodeSegEntry>, SCodeSegEntry->iSeg/iLib |
|
129 |
|
130 //Kern::Printf("DProcess: count of segments %d", c); |
|
131 for (TInt i=-1; i<c; ++i) |
|
132 { |
|
133 DCodeSeg* seg=(i<0)?pro->iCodeSeg:pro->iDynamicCode[i].iSeg; |
|
134 if(seg != 0) |
|
135 { |
|
136 if( (seg->iMark & 0x80) == 0) |
|
137 { |
|
138 this->internalData[0] = seg->iFileName->Length(); |
|
139 ptrToData->Append(*(seg->iFileName)); |
|
140 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
141 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
142 //Kern::Printf("EXE1: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
143 seg->iMark = (seg->iMark | 0x80); |
|
144 |
|
145 this->internalData[0] = ptrToData->Size(); |
|
146 return ptrToData->Size()+1; |
|
147 } |
|
148 } |
|
149 } |
|
150 } |
|
151 */ |
|
152 /* |
|
153 |
|
154 DObjectCon* libs = Kern::Containers()[ELibrary]; |
|
155 TInt libCount = libs->Count(); |
|
156 |
|
157 //Kern::Printf("Got count of processes: %d", procCount); |
|
158 |
|
159 // go 20 executables through at a time |
|
160 for(TInt i=0;i<libCount;i++) |
|
161 { |
|
162 //Kern::Printf("Inspecting DLibrary array..."); |
|
163 |
|
164 DLibrary* lib = (DLibrary*)(*libs)[i]; |
|
165 |
|
166 DCodeSeg* seg = lib->iCodeSeg; |
|
167 if(seg != 0) |
|
168 { |
|
169 if( (seg->iMark & 0x80) == 0) |
|
170 { |
|
171 this->internalData[0] = seg->iFileName->Length(); |
|
172 ptrToData->Append(*(seg->iFileName)); |
|
173 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
174 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
175 Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
176 seg->iMark = (seg->iMark | 0x80); |
|
177 |
|
178 this->internalData[0] = ptrToData->Size(); |
|
179 return ptrToData->Size()+1; |
|
180 } |
|
181 } |
|
182 } |
|
183 */ |
|
184 // original |
|
185 if((sampleNum % 20) != 0) return 0; |
|
186 if((sampleNum % 40) == 0) |
|
187 { |
|
188 /* |
|
189 if((sampleNum % 60) == 0) |
|
190 { |
|
191 // encode a process binary |
|
192 ptrToData->Zero(); |
|
193 DObjectCon* proc = Kern::Containers()[EProcess]; |
|
194 TInt procCount = proc->Count(); |
|
195 |
|
196 // go 20 executables through at a time |
|
197 for(TInt i=0;i<20;i++) |
|
198 { |
|
199 if(currentProcCount >= procCount) |
|
200 { |
|
201 currentProcCount = 0; |
|
202 } |
|
203 |
|
204 DProcess* pro = (DProcess*)(*proc)[currentProcCount]; |
|
205 currentProcCount++; |
|
206 |
|
207 DCodeSeg* seg = pro->iCodeSeg; |
|
208 if(seg != 0) |
|
209 { |
|
210 if( (seg->iMark & 0x80) == 0) |
|
211 { |
|
212 this->internalData[0] = seg->iFileName->Length(); |
|
213 ptrToData->Append(*(seg->iFileName)); |
|
214 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
215 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
216 //Kern::Printf("EXE: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
217 seg->iMark = (seg->iMark | 0x80); |
|
218 |
|
219 this->internalData[0] = ptrToData->Size(); |
|
220 return ptrToData->Size()+1; |
|
221 } |
|
222 } |
|
223 } |
|
224 } else |
|
225 { */ |
|
226 // encode a library binary |
|
227 ptrToData->Zero(); |
|
228 DObjectCon* libs = Kern::Containers()[ELibrary]; |
|
229 TInt libCount = libs->Count(); |
|
230 |
|
231 // go 20 binaries through at a time |
|
232 for(TInt i=0;i<20;i++) |
|
233 { |
|
234 if(currentLibCount >= libCount) |
|
235 { |
|
236 currentLibCount = 0; |
|
237 } |
|
238 |
|
239 DLibrary* lib = (DLibrary*)(*libs)[currentLibCount]; |
|
240 currentLibCount++; |
|
241 |
|
242 DCodeSeg* seg = lib->iCodeSeg; |
|
243 if(seg != 0) |
|
244 { |
|
245 if( (seg->iMark & 0x80) == 0) |
|
246 { |
|
247 this->internalData[0] = seg->iFileName->Length(); |
|
248 ptrToData->Append(*(seg->iFileName)); |
|
249 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
250 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
251 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
252 seg->iMark = (seg->iMark | 0x80); |
|
253 |
|
254 this->internalData[0] = ptrToData->Size(); |
|
255 return ptrToData->Size()+1; |
|
256 } |
|
257 } |
|
258 } |
|
259 } else |
|
260 { |
|
261 SDblQue* codeSegList = Kern::CodeSegList(); |
|
262 //Kern::Printf("PI"); |
|
263 //TUint c = 0; |
|
264 // the global list |
|
265 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
|
266 { |
|
267 DCodeSeg* seg = _LOFF(codeseg, DCodeSeg, iLink); |
|
268 if(seg != 0) |
|
269 { |
|
270 if( (seg->iMark & 0x80) == 0) |
|
271 { |
|
272 this->internalData[0] = seg->iFileName->Length(); |
|
273 ptrToData->Append(*(seg->iFileName)); |
|
274 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
275 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
276 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
277 seg->iMark = (seg->iMark | 0x80); |
|
278 |
|
279 this->internalData[0] = ptrToData->Size(); |
|
280 return ptrToData->Size()+1; |
|
281 } |
|
282 } |
|
283 } |
|
284 } |
|
285 |
|
286 /* |
|
287 // the garbage list |
|
288 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
|
289 { |
|
290 DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iGbgLink); |
|
291 if(seg != 0) |
|
292 { |
|
293 if( (seg->iMark & 0x80) == 0) |
|
294 { |
|
295 this->internalData[0] = seg->iFileName->Length(); |
|
296 ptrToData->Append(*(seg->iFileName)); |
|
297 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
298 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
299 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
300 seg->iMark = (seg->iMark | 0x80); |
|
301 |
|
302 this->internalData[0] = ptrToData->Size(); |
|
303 return ptrToData->Size()+1; |
|
304 } |
|
305 } |
|
306 } |
|
307 */ |
|
308 |
|
309 // Another try |
|
310 // Kern::AccessCode(); |
|
311 |
|
312 //Collect all non-XIP segments that are not already marked. |
|
313 /* |
|
314 SDblQue* p = Kern::CodeSegList(); |
|
315 SDblQueLink* anchor=&p->iA; |
|
316 SDblQueLink* a=anchor->iNext; |
|
317 for (; a!=anchor; a=a->iNext) |
|
318 { |
|
319 DEpocCodeSeg* pSeg = (DEpocCodeSeg*) _LOFF(a, DCodeSeg, iLink); |
|
320 if (pSeg != 0) |
|
321 { |
|
322 if (pSeg->iXIP || pSeg->iMark&DCodeSeg::EMarkProfilerTAG) |
|
323 { |
|
324 //continue; |
|
325 //if (current > (max-KMaxCreateCodeSegRecordSize)) |
|
326 // break;//No more space. Finish now and wait for another GetSegments request. |
|
327 |
|
328 pSeg->iMark |= DCodeSeg::EMarkProfilerTAG; //Mark this segment |
|
329 this->internalData[0] = pSeg->iFileName->Length(); |
|
330 ptrToData->Append(*(pSeg->iFileName)); |
|
331 ptrToData->Append((TUint8*)&(pSeg->iRunAddress),4); |
|
332 ptrToData->Append((TUint8*)&(pSeg->iSize),4); |
|
333 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
334 |
|
335 this->internalData[0] = ptrToData->Size(); |
|
336 return ptrToData->Size()+1; |
|
337 } |
|
338 } |
|
339 } |
|
340 */ |
|
341 |
|
342 // Kern::EndAccessCode(); |
|
343 |
|
344 //Kern::Printf("PO"); |
|
345 |
|
346 /* |
|
347 for(TInt i=0;i<arrayCount;i++) |
|
348 { |
|
349 currentProcCount++; |
|
350 DCodeSeg* seg = (DCodeSeg*)array[i]; |
|
351 if(seg != 0) |
|
352 { |
|
353 if( (seg->iMark & 0x80) == 0) |
|
354 { |
|
355 this->internalData[0] = seg->iFileName->Length(); |
|
356 ptrToData->Append(*(seg->iFileName)); |
|
357 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
358 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
359 //Kern::Printf("EXE: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
360 seg->iMark = (seg->iMark | 0x80); |
|
361 |
|
362 this->internalData[0] = ptrToData->Size(); |
|
363 return ptrToData->Size()+1; |
|
364 } |
|
365 } |
|
366 } |
|
367 */ |
|
368 } |
|
369 /* |
|
370 #else |
|
371 if((sampleNum % 50) != 0) return 0; |
|
372 if((sampleNum % 100) == 0) |
|
373 { |
|
374 // encode a process binary |
|
375 ptrToData->Zero(); |
|
376 DObjectCon* proc = Kern::Containers()[EProcess]; |
|
377 TInt procCount = proc->Count(); |
|
378 |
|
379 // go 20 executables through at a time |
|
380 for(TInt i=0;i<20;i++) |
|
381 { |
|
382 if(currentProcCount >= procCount) |
|
383 { |
|
384 currentProcCount = 0; |
|
385 } |
|
386 |
|
387 DProcess* pro = (DProcess*)(*proc)[currentProcCount]; |
|
388 currentProcCount++; |
|
389 |
|
390 DCodeSeg* seg = pro->iCodeSeg; |
|
391 if(seg != 0) |
|
392 { |
|
393 if( (seg->iMark & 0x80) == 0) |
|
394 { |
|
395 this->internalData[0] = seg->iFileName->Length(); |
|
396 ptrToData->Append(*(seg->iFileName)); |
|
397 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
398 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
399 //Kern::Printf("EXE: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
400 seg->iMark = (seg->iMark | 0x80); |
|
401 |
|
402 this->internalData[0] = ptrToData->Size(); |
|
403 return ptrToData->Size()+1; |
|
404 } |
|
405 } |
|
406 } |
|
407 } |
|
408 else |
|
409 { |
|
410 // encode a library binary |
|
411 ptrToData->Zero(); |
|
412 DObjectCon* libs = Kern::Containers()[ELibrary]; |
|
413 TInt libCount = libs->Count(); |
|
414 |
|
415 // go 20 binaries through at a time |
|
416 for(TInt i=0;i<20;i++) |
|
417 { |
|
418 if(currentLibCount >= libCount) |
|
419 { |
|
420 currentLibCount = 0; |
|
421 } |
|
422 |
|
423 DLibrary* lib = (DLibrary*)(*libs)[currentLibCount]; |
|
424 currentLibCount++; |
|
425 |
|
426 DCodeSeg* seg = lib->iCodeSeg; |
|
427 if(seg != 0) |
|
428 { |
|
429 if( (seg->iMark & 0x80) == 0) |
|
430 { |
|
431 this->internalData[0] = seg->iFileName->Length(); |
|
432 ptrToData->Append(*(seg->iFileName)); |
|
433 ptrToData->Append((TUint8*)&(seg->iRunAddress),4); |
|
434 ptrToData->Append((TUint8*)&(seg->iSize),4); |
|
435 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
436 seg->iMark = (seg->iMark | 0x80); |
|
437 |
|
438 this->internalData[0] = ptrToData->Size(); |
|
439 return ptrToData->Size()+1; |
|
440 } |
|
441 } |
|
442 } |
|
443 } |
|
444 #endif |
|
445 */ |
|
446 return 0; |
|
447 |
|
448 } |
|
449 |
|
450 void IttSamplerImpl::Reset() |
|
451 { |
|
452 this->currentLibCount = 0; |
|
453 this->currentProcCount = 0; |
|
454 this->itt_sample = (TUint8*)&(this->internalData[0]); |
|
455 ptrToData->Zero(); |
|
456 |
|
457 // #ifdef ITT_TEST |
|
458 |
|
459 SDblQue* codeSegList = Kern::CodeSegList(); |
|
460 // the global list |
|
461 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
|
462 { |
|
463 DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink); |
|
464 //if(seg != 0) |
|
465 { |
|
466 if( (seg->iMark & 0x80) > 0) |
|
467 { |
|
468 seg->iMark = (seg->iMark & ~0x80); |
|
469 } |
|
470 } |
|
471 } |
|
472 |
|
473 // the garbage list |
|
474 /* |
|
475 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
|
476 { |
|
477 DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iGbgLink); |
|
478 if(seg != 0) |
|
479 { |
|
480 if( (seg->iMark & 0x80) > 0) |
|
481 { |
|
482 seg->iMark = (seg->iMark & ~0x80); |
|
483 } |
|
484 } |
|
485 } |
|
486 */ |
|
487 // another try |
|
488 /* |
|
489 // Kern::AccessCode(); |
|
490 SDblQue* p = Kern::CodeSegList(); |
|
491 SDblQueLink* anchor=&p->iA; |
|
492 SDblQueLink* a=anchor->iNext; |
|
493 for (; a!=anchor; a=a->iNext) |
|
494 { |
|
495 DEpocCodeSeg* pSeg = (DEpocCodeSeg*) _LOFF(a, DCodeSeg, iLink); |
|
496 if (!pSeg->iXIP) |
|
497 pSeg->iMark &= ~DCodeSeg::EMarkProfilerTAG; |
|
498 } |
|
499 |
|
500 // Kern::EndAccessCode(); |
|
501 */ |
|
502 /* |
|
503 DObjectCon* proc = Kern::Containers()[EProcess]; |
|
504 TInt procCount = proc->Count(); |
|
505 |
|
506 // go 20 executables through at a time |
|
507 for(TInt i=0;i<procCount;i++) |
|
508 { |
|
509 DProcess* pro = (DProcess*)(*proc)[i]; |
|
510 |
|
511 //Kern::Printf("Reset: Inspecting DProcess..."); |
|
512 |
|
513 TInt c=pro->iDynamicCode.Count(); // DProcess.iDynamicCode, type = RArray<SCodeSegEntry>, SCodeSegEntry->iSeg/iLib |
|
514 |
|
515 //Kern::Printf("Reset: DProcess: count of segments %d", c); |
|
516 for (TInt i=-1; i<c; ++i) |
|
517 { |
|
518 DCodeSeg* seg=(i<0)?pro->iCodeSeg:pro->iDynamicCode[i].iSeg; |
|
519 if(seg != 0) |
|
520 { |
|
521 if( (seg->iMark & 0x80) > 0) |
|
522 { |
|
523 seg->iMark = (seg->iMark & ~0x80); |
|
524 } |
|
525 } |
|
526 } |
|
527 } |
|
528 |
|
529 //Kern::Printf("Reset: Exiting..."); |
|
530 |
|
531 #else |
|
532 */ |
|
533 DObjectCon* libs = Kern::Containers()[ELibrary]; |
|
534 TInt libCount = libs->Count(); |
|
535 for(TInt i=0;i<libCount;i++) |
|
536 { |
|
537 DLibrary* lib = (DLibrary*)(*libs)[i]; |
|
538 DCodeSeg* seg = lib->iCodeSeg; |
|
539 if( (seg->iMark & 0x80) > 0) |
|
540 { |
|
541 seg->iMark = (seg->iMark & ~0x80); |
|
542 } |
|
543 } |
|
544 |
|
545 DObjectCon* procs = Kern::Containers()[EProcess]; |
|
546 TInt procCount = procs->Count(); |
|
547 for(TInt i=0;i<procCount;i++) |
|
548 { |
|
549 DProcess* pro = (DProcess*)(*procs)[i]; |
|
550 DCodeSeg* seg = pro->iCodeSeg; |
|
551 if(seg != 0) |
|
552 { |
|
553 if( (seg->iMark & 0x80) > 0) |
|
554 { |
|
555 seg->iMark = (seg->iMark & ~0x80); |
|
556 } |
|
557 } |
|
558 } |
|
559 //#endif |
|
560 } |