23 #include <nk_trace.h> |
23 #include <nk_trace.h> |
24 |
24 |
25 #include "MemoryEventHandler.h" |
25 #include "MemoryEventHandler.h" |
26 |
26 |
27 |
27 |
28 DMemoryEventHandler::DMemoryEventHandler(DProfilerSampleBuffer* aSampleBuffer) |
28 DMemoryEventHandler::DMemoryEventHandler(DProfilerSampleBuffer* aSampleBuffer, TProfilerGppSamplerData* aGppSamplerDataIn) |
29 : DKernelEventHandler(EventHandler, this), |
29 : DKernelEventHandler(EventHandler, this), |
30 iSampleBuffer(aSampleBuffer), |
30 iSampleBuffer(aSampleBuffer), |
31 iSampleDescriptor(&(this->iSample[1]),0,256) |
31 iSampleDescriptor(&(this->iSample[1]),0,256), |
32 { |
32 gppSamplerData(aGppSamplerDataIn) |
33 // Kern::Printf("DMemoryEventHandler::DMemoryEventHandler()"); |
33 { |
34 iCount = 0; |
|
35 iPreviousCount = 0; |
34 iPreviousCount = 0; |
|
35 iSampleAvailable = false; |
36 } |
36 } |
37 |
37 |
38 |
38 |
39 TInt DMemoryEventHandler::Create() |
39 TInt DMemoryEventHandler::Create() |
40 { |
40 { |
41 // Kern::Printf("DMemoryEventHandler::Create()"); |
41 TInt err(Kern::MutexCreate(iLock, _L("MemoryEventHandlerLock"), KMutexOrdResourceManager)); |
42 |
|
43 TInt err(Kern::MutexCreate(iLock, _L("MemoryEventHandlerLock"), KMutexOrdGeneral0)); |
|
44 if (err != KErrNone) |
42 if (err != KErrNone) |
45 return err; |
43 return err; |
46 |
44 |
47 return Add(); |
45 return Add(); |
48 } |
46 } |
49 |
47 |
50 |
48 |
51 DMemoryEventHandler::~DMemoryEventHandler() |
49 DMemoryEventHandler::~DMemoryEventHandler() |
52 { |
50 { |
53 // Kern::Printf("DMemoryEventHandler::~DMemoryEventHandler()"); |
|
54 |
|
55 if (iLock) |
51 if (iLock) |
56 iLock->Close(NULL); |
52 iLock->Close(NULL); |
57 |
53 |
58 } |
54 } |
59 |
55 |
60 |
56 |
61 TInt DMemoryEventHandler::Start() |
57 TInt DMemoryEventHandler::Start() |
62 { |
58 { |
63 // Kern::Printf("DMemoryEventHandler::Start()"); |
|
64 |
|
65 iTracking = ETrue; |
59 iTracking = ETrue; |
66 return KErrNone; |
60 return KErrNone; |
67 } |
61 } |
68 |
62 |
69 |
63 |
70 TInt DMemoryEventHandler::Stop() |
64 TInt DMemoryEventHandler::Stop() |
71 { |
65 { |
72 // Kern::Printf("DMemoryEventHandler::Stop()"); |
|
73 |
|
74 iTracking = EFalse; |
66 iTracking = EFalse; |
75 return KErrNone; |
67 return KErrNone; |
76 } |
68 } |
77 |
69 |
78 TBool DMemoryEventHandler::SampleNeeded() |
70 TBool DMemoryEventHandler::SampleNeeded() |
79 { |
71 { |
80 LOGTEXT("DMemoryEventHandler::SampleNeeded()"); |
72 LOGTEXT("DMemoryEventHandler::SampleNeeded()"); |
81 |
73 |
82 // increase the coutner by one on each round |
|
83 iCount++; |
|
84 |
|
85 // check if event handler was not running |
74 // check if event handler was not running |
86 // if(!iTracking) |
75 if(!iTracking) |
87 // return false; // return false |
76 return false; // return false |
88 |
77 // check if a new sample is available |
89 return true; |
78 if(iSampleAvailable) |
|
79 { |
|
80 return true; |
|
81 } |
|
82 else |
|
83 { |
|
84 return false; |
|
85 } |
|
86 } |
|
87 void DMemoryEventHandler::SampleHandled() |
|
88 { |
|
89 iSampleAvailable = false; |
90 } |
90 } |
91 |
91 |
92 |
92 |
93 TUint DMemoryEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis) |
93 TUint DMemoryEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis) |
94 { |
94 { |
98 |
98 |
99 |
99 |
100 TUint DMemoryEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2) |
100 TUint DMemoryEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2) |
101 { |
101 { |
102 // debug |
102 // debug |
103 // Kern::Printf("New kernel event received, %d", aType); |
103 // Kern::Printf("New kernel event received, %d", aType); |
104 |
104 |
105 if (iTracking/* && iCount != iPreviousCount*/) |
105 if (iTracking) |
106 { |
106 { |
107 // iPreviousCount = iCount; |
|
108 iCounters[aType]++; |
107 iCounters[aType]++; |
109 switch (aType) |
108 switch (aType) |
110 { |
109 { |
111 // capture only chunk creation, updates and destroyal |
110 // capture only chunk creation, updates and destroyal |
112 case EEventNewChunk: |
111 case EEventNewChunk: |
206 TInt DMemoryEventHandler::AddHeader() |
200 TInt DMemoryEventHandler::AddHeader() |
207 { |
201 { |
208 TInt err(KErrNone); |
202 TInt err(KErrNone); |
209 |
203 |
210 TUint8 number(4); // mem sampler id |
204 TUint8 number(4); // mem sampler id |
211 |
205 TUint32 sampleNum= this->gppSamplerData->sampleNumber; |
212 // check if iCount bigger than previous, i.e. at least 1 ms has passed from the previous sample |
206 // check if iCount bigger than previous, i.e. at least 1 ms has passed from the previous sample |
213 if(iCount > iPreviousCount) |
207 if(sampleNum > iPreviousCount) |
214 { |
208 { |
215 err = this->iSampleBuffer->AddSample(&number,1); |
209 err = this->iSampleBuffer->AddSample(&number,1); |
216 err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4); |
210 err = this->iSampleBuffer->AddSample((TUint8*)&(sampleNum),4); |
217 |
211 |
218 // add data chunk header |
212 // add data chunk header |
219 TInt length(EncodeUpdateCode()); |
213 TInt length(EncodeUpdateCode()); |
220 err = iSampleBuffer->AddSample(iSample, length); |
214 err = iSampleBuffer->AddSample(iSample, length); |
221 |
215 |
222 // add total memory sample in the beginning of each sample |
216 // add total memory sample in the beginning of each sample |
223 length = EncodeTotalMemory(); |
217 length = EncodeTotalMemory(); |
224 err = iSampleBuffer->AddSample(iSample, length); |
218 err = iSampleBuffer->AddSample(iSample, length); |
225 AddFooter(); // end mark for total memory sample |
219 AddFooter(); // end mark for total memory sample |
226 } |
220 } |
227 iPreviousCount = iCount; |
221 iPreviousCount = sampleNum; |
228 |
222 |
229 // add actual sample |
223 // add actual sample |
230 err = this->iSampleBuffer->AddSample(&number,1); |
224 err = this->iSampleBuffer->AddSample(&number,1); |
231 err = this->iSampleBuffer->AddSample((TUint8*)&(iCount),4); |
225 err = this->iSampleBuffer->AddSample((TUint8*)&(sampleNum),4); |
|
226 LOGSTRING2("handler timestamp : 0x%04x", sampleNum); |
232 |
227 |
233 return err; |
228 return err; |
234 } |
229 } |
235 |
230 |
236 // encode the memory sample header in all memory changes |
231 // encode the memory sample header in all memory changes |
282 } |
277 } |
283 |
278 |
284 // handle chunk activity |
279 // handle chunk activity |
285 TBool DMemoryEventHandler::HandleAddChunk(DChunk* aChunk) |
280 TBool DMemoryEventHandler::HandleAddChunk(DChunk* aChunk) |
286 { |
281 { |
287 // Kern::Printf("New DChunk created: 0x%08x, time: %d", aChunk, iCount); |
|
288 |
|
289 NKern::ThreadEnterCS(); |
282 NKern::ThreadEnterCS(); |
290 Kern::MutexWait(*iLock); |
283 Kern::MutexWait(*iLock); |
291 // add header first |
284 // add header first |
292 TInt err(AddHeader()); |
285 TInt err(AddHeader()); |
293 |
286 |
294 if(err != KErrNone) |
287 if(err != KErrNone) |
295 { |
288 { |
|
289 Kern::MutexSignal(*iLock); |
|
290 NKern::ThreadLeaveCS(); |
296 return EFalse; |
291 return EFalse; |
297 } |
292 } |
298 |
293 |
299 // new chunk, add name of it |
294 // new chunk, add name of it |
300 TInt length(EncodeNameCode()); |
295 TInt length(EncodeNameCode()); |
318 return ETrue; |
313 return ETrue; |
319 } |
314 } |
320 |
315 |
321 TBool DMemoryEventHandler::HandleUpdateChunk(DChunk* aChunk) |
316 TBool DMemoryEventHandler::HandleUpdateChunk(DChunk* aChunk) |
322 { |
317 { |
323 // Kern::Printf("DChunk updated: 0x%08x, time: %d", aChunk, iCount); |
|
324 |
|
325 NKern::ThreadEnterCS(); |
318 NKern::ThreadEnterCS(); |
326 Kern::MutexWait(*iLock); |
319 Kern::MutexWait(*iLock); |
327 // add header first |
320 // add header first |
328 TInt err(AddHeader()); |
321 TInt err(AddHeader()); |
329 |
322 |
330 if(err != KErrNone) |
323 if(err != KErrNone) |
331 { |
324 { |
|
325 Kern::Printf("DChunk update error: %d", err); |
|
326 Kern::MutexSignal(*iLock); |
|
327 NKern::ThreadLeaveCS(); |
332 return EFalse; |
328 return EFalse; |
333 } |
329 } |
334 |
330 |
335 // add new chunk tag |
331 // add new chunk tag |
336 TInt length(EncodeUpdateCode()); |
332 TInt length(EncodeUpdateCode()); |
346 return ETrue; |
342 return ETrue; |
347 } |
343 } |
348 |
344 |
349 TBool DMemoryEventHandler::HandleDeleteChunk(DChunk* aChunk) |
345 TBool DMemoryEventHandler::HandleDeleteChunk(DChunk* aChunk) |
350 { |
346 { |
351 // Kern::Printf("DChunk deleted: 0x%08x, time: %d", aChunk, iCount); |
|
352 NKern::ThreadEnterCS(); |
347 NKern::ThreadEnterCS(); |
353 Kern::MutexWait(*iLock); |
348 Kern::MutexWait(*iLock); |
354 // add header first |
349 // add header first |
355 TInt err(AddHeader()); |
350 TInt err(AddHeader()); |
356 |
351 |
357 if(err != KErrNone) |
352 if(err != KErrNone) |
358 { |
353 { |
|
354 Kern::MutexSignal(*iLock); |
|
355 NKern::ThreadLeaveCS(); |
359 return EFalse; |
356 return EFalse; |
360 } |
357 } |
361 |
358 |
362 // add new chunk tag |
359 // add new chunk tag |
363 TInt length(EncodeRemoveCode()); |
360 TInt length(EncodeRemoveCode()); |
390 } |
387 } |
391 |
388 |
392 // handle thread activity |
389 // handle thread activity |
393 TBool DMemoryEventHandler::HandleAddThread(DThread* aThread) |
390 TBool DMemoryEventHandler::HandleAddThread(DThread* aThread) |
394 { |
391 { |
395 // Kern::Printf("DThread added: 0x%08x, time: %d", aThread->iId, iCount); |
|
396 NKern::ThreadEnterCS(); |
392 NKern::ThreadEnterCS(); |
397 Kern::MutexWait(*iLock); |
393 Kern::MutexWait(*iLock); |
398 // add header first |
394 // add header first |
399 TInt err(AddHeader()); |
395 TInt err(AddHeader()); |
400 |
396 |
401 if(err != KErrNone) |
397 if(err != KErrNone) |
402 { |
398 { |
|
399 Kern::MutexSignal(*iLock); |
|
400 NKern::ThreadLeaveCS(); |
403 return EFalse; |
401 return EFalse; |
404 } |
402 } |
405 |
403 |
406 // new thread, add name of it |
404 // new thread, add name of it |
407 TInt length(EncodeNameCode()); |
405 TInt length(EncodeNameCode()); |
425 return ETrue; |
423 return ETrue; |
426 } |
424 } |
427 |
425 |
428 TBool DMemoryEventHandler::HandleUpdateThread(DThread* aThread) |
426 TBool DMemoryEventHandler::HandleUpdateThread(DThread* aThread) |
429 { |
427 { |
430 // Kern::Printf("DThread updated: 0x%08x, time: %d", aThread->iId, iCount); |
|
431 NKern::ThreadEnterCS(); |
428 NKern::ThreadEnterCS(); |
432 Kern::MutexWait(*iLock); |
429 Kern::MutexWait(*iLock); |
433 // add header first |
430 // add header first |
434 TInt err(AddHeader()); |
431 TInt err(AddHeader()); |
435 |
432 |
436 if(err != KErrNone) |
433 if(err != KErrNone) |
437 { |
434 { |
|
435 Kern::MutexSignal(*iLock); |
|
436 NKern::ThreadLeaveCS(); |
438 return EFalse; |
437 return EFalse; |
439 } |
438 } |
440 |
439 |
441 // add new chunk tag |
440 // add new chunk tag |
442 TInt length(EncodeUpdateCode()); |
441 TInt length(EncodeUpdateCode()); |
452 return ETrue; |
451 return ETrue; |
453 } |
452 } |
454 |
453 |
455 TBool DMemoryEventHandler::HandleDeleteThread(DThread* aThread) |
454 TBool DMemoryEventHandler::HandleDeleteThread(DThread* aThread) |
456 { |
455 { |
457 // Kern::Printf("DThread deleted: 0x%08x, time: %d", aThread->iId, iCount); |
|
458 NKern::ThreadEnterCS(); |
456 NKern::ThreadEnterCS(); |
459 Kern::MutexWait(*iLock); |
457 Kern::MutexWait(*iLock); |
460 // add header first |
458 // add header first |
461 TInt err(AddHeader()); |
459 TInt err(AddHeader()); |
462 |
460 |
463 if(err != KErrNone) |
461 if(err != KErrNone) |
464 { |
462 { |
|
463 Kern::MutexSignal(*iLock); |
|
464 NKern::ThreadLeaveCS(); |
465 return EFalse; |
465 return EFalse; |
466 } |
466 } |
467 |
467 |
468 // add new chunk tag |
468 // add new chunk tag |
469 TInt length(EncodeRemoveCode()); |
469 TInt length(EncodeRemoveCode()); |
480 } |
480 } |
481 |
481 |
482 TBool DMemoryEventHandler::HandleAddLibrary(DLibrary* aLibrary, DThread* aThread) |
482 TBool DMemoryEventHandler::HandleAddLibrary(DLibrary* aLibrary, DThread* aThread) |
483 { |
483 { |
484 LOGTEXT("DMemoryEventHandler::HandleAddLibrary"); |
484 LOGTEXT("DMemoryEventHandler::HandleAddLibrary"); |
485 Kern::Printf("DLibrary added: 0x%08x, time: %d", aLibrary, iCount); |
|
486 // add header first |
485 // add header first |
487 NKern::ThreadEnterCS(); |
486 NKern::ThreadEnterCS(); |
488 Kern::MutexWait(*iLock); |
487 Kern::MutexWait(*iLock); |
489 TInt err(AddHeader()); |
488 TInt err(AddHeader()); |
490 |
489 |
491 if(err != KErrNone) |
490 if(err != KErrNone) |
492 { |
491 { |
|
492 Kern::MutexSignal(*iLock); |
|
493 NKern::ThreadLeaveCS(); |
493 return EFalse; |
494 return EFalse; |
494 } |
495 } |
495 |
496 |
496 // new library, add name of it |
497 // new library, add name of it |
497 TInt length(EncodeNameCode()); |
498 TInt length(EncodeNameCode()); |
515 return ETrue; |
516 return ETrue; |
516 } |
517 } |
517 |
518 |
518 TBool DMemoryEventHandler::HandleDeleteLibrary(DLibrary* aLibrary) |
519 TBool DMemoryEventHandler::HandleDeleteLibrary(DLibrary* aLibrary) |
519 { |
520 { |
520 Kern::Printf("DLibrary deleted: 0x%08x, time: %d", aLibrary, iCount); |
521 LOGTEXT("DMemoryEventHandler::HandleDeleteLibrary"); |
521 NKern::ThreadEnterCS(); |
522 NKern::ThreadEnterCS(); |
522 Kern::MutexWait(*iLock); |
523 Kern::MutexWait(*iLock); |
523 // add header first |
524 // add header first |
524 TInt err(AddHeader()); |
525 TInt err(AddHeader()); |
525 |
526 |
526 if(err != KErrNone) |
527 if(err != KErrNone) |
527 { |
528 { |
|
529 Kern::MutexSignal(*iLock); |
|
530 NKern::ThreadLeaveCS(); |
528 return EFalse; |
531 return EFalse; |
529 } |
532 } |
530 |
533 |
531 // add new chunk tag |
534 // add new chunk tag |
532 TInt length(EncodeRemoveCode()); |
535 TInt length(EncodeRemoveCode()); |
638 |
641 |
639 // append user stack (max) size |
642 // append user stack (max) size |
640 iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt)); |
643 iSampleDescriptor.Append((TUint8*)&(t.iUserStackSize),sizeof(TInt)); |
641 *size += sizeof(TInt); |
644 *size += sizeof(TInt); |
642 |
645 |
643 // Kern::Printf("TData -> %d",*size); |
646 LOGSTRING2("TData -> %d",*size); |
644 return ((TInt)(*size))+1; |
647 return ((TInt)(*size))+1; |
645 } |
648 } |
646 |
649 |
647 // record chunk changes |
650 // record chunk changes |
648 TInt DMemoryEventHandler::EncodeChunkData(DChunk& c) |
651 TInt DMemoryEventHandler::EncodeChunkData(DChunk& c) |
654 *size = 0; |
657 *size = 0; |
655 iSampleDescriptor.Zero(); |
658 iSampleDescriptor.Zero(); |
656 TInt zero(0); |
659 TInt zero(0); |
657 |
660 |
658 TUint32 address((TUint32)&c); |
661 TUint32 address((TUint32)&c); |
659 |
662 LOGSTRING2("DMemoryEventHandler::EncodeChunkDataC - address 0x%x", *&address); |
660 iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32)); |
663 iSampleDescriptor.Append((TUint8*)&address,sizeof(TUint32)); |
661 *size += sizeof(TUint); |
664 *size += sizeof(TUint); |
662 |
665 |
663 // copy the total amount of memory allocated |
666 // copy the total amount of memory allocated |
664 iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt)); |
667 iSampleDescriptor.Append((TUint8*)&(c.iSize),sizeof(TInt)); |
674 |
677 |
675 // append the thread user stack size |
678 // append the thread user stack size |
676 iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); |
679 iSampleDescriptor.Append((TUint8*)&(zero),sizeof(TInt)); |
677 *size += sizeof(TInt); |
680 *size += sizeof(TInt); |
678 |
681 |
679 // Kern::Printf("CData - %d",*size); |
682 LOGSTRING2("CData - %d",*size); |
680 return ((TInt)(*size))+1; |
683 return ((TInt)(*size))+1; |
681 } |
684 } |
682 |
685 |
683 // record loaded libraries changes |
686 // record loaded libraries changes |
684 TInt DMemoryEventHandler::EncodeChunkData(DLibrary& l, DThread& t) |
687 TInt DMemoryEventHandler::EncodeChunkData(DLibrary& l, DThread& t) |