|
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 #ifndef PROFILER_ITT_SAMPLER_H |
|
19 #define PROFILER_ITT_SAMPLER_H |
|
20 |
|
21 #include "GeneralsConfig.h" |
|
22 |
|
23 #include <kern_priv.h> |
|
24 |
|
25 #include <piprofiler/ProfilerGenericClassesKrn.h> |
|
26 #include <piprofiler/ProfilerTraces.h> |
|
27 #include "GppSamplerImpl.h" |
|
28 #include "IttEventHandler.h" |
|
29 |
|
30 // CONSTANTS |
|
31 const TInt KITTSampleBufferSize = 256; |
|
32 |
|
33 // flags |
|
34 #define ITT_EVENT_HANDLER // enable event based ITT sampling |
|
35 |
|
36 /* |
|
37 * |
|
38 * ITT sampler definition |
|
39 * |
|
40 */ |
|
41 class DIttEventHandler; |
|
42 |
|
43 /* |
|
44 * User side ITT sampler |
|
45 */ |
|
46 class IttSamplerImpl |
|
47 { |
|
48 public: |
|
49 IttSamplerImpl(); |
|
50 ~IttSamplerImpl(); |
|
51 |
|
52 TInt SampleImpl(TUint32 pc,TUint32 sampleNum); |
|
53 TBool SampleNeeded(TUint32 sampleNum); |
|
54 TInt CreateFirstSample(); |
|
55 void Reset(); |
|
56 TInt ProcessEvent(); |
|
57 |
|
58 TUint8* itt_sample; |
|
59 TInt iIttSamplingPeriod; |
|
60 TInt iIttSamplingPeriodDiv2; |
|
61 TBool iTimeToSample; |
|
62 #ifdef ITT_EVENT_HANDLER |
|
63 TBool iEventReceived; |
|
64 TBool iFirstSampleTaken; |
|
65 #endif |
|
66 |
|
67 private: |
|
68 #ifdef ITT_EVENT_HANDLER |
|
69 TInt iCount; |
|
70 #endif |
|
71 TInt currentLibCount; |
|
72 TInt currentProcCount; |
|
73 |
|
74 TUint8 sample[KITTSampleBufferSize ]; |
|
75 TPtr8 sampleDescriptor; |
|
76 |
|
77 TBuf8<64> iVersionData; |
|
78 SDblQue* codeSegList; |
|
79 |
|
80 }; |
|
81 |
|
82 /* |
|
83 * ITT sampler kernel part |
|
84 * |
|
85 */ |
|
86 template <int BufferSize> |
|
87 class DProfilerIttSampler : public DProfilerGenericSampler<BufferSize> |
|
88 { |
|
89 public: |
|
90 DProfilerIttSampler(struct TProfilerGppSamplerData* gppSamplerDataIn); |
|
91 ~DProfilerIttSampler(); |
|
92 |
|
93 void Sample(); |
|
94 TInt Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset); |
|
95 TInt PostSample(); |
|
96 TBool PostSampleNeeded(); |
|
97 |
|
98 private: |
|
99 #ifdef ITT_EVENT_HANDLER |
|
100 DIttEventHandler* iEventHandler; |
|
101 #endif |
|
102 IttSamplerImpl ittSamplerImpl; |
|
103 struct TProfilerGppSamplerData* gppSamplerData; |
|
104 TBool sampleInProgress; |
|
105 TBool sampleNeeded; |
|
106 }; |
|
107 |
|
108 /* |
|
109 * ITT sampler implementation |
|
110 * |
|
111 */ |
|
112 template <int BufferSize> |
|
113 DProfilerIttSampler<BufferSize>::DProfilerIttSampler(struct TProfilerGppSamplerData* gppSamplerDataIn) : |
|
114 DProfilerGenericSampler<BufferSize>(PROFILER_ITT_SAMPLER_ID) |
|
115 { |
|
116 this->gppSamplerData = (struct TProfilerGppSamplerData*)gppSamplerDataIn; |
|
117 this->sampleInProgress = false; |
|
118 LOGSTRING2("CProfilerIttSampler<%d>::CProfilerIttSampler",BufferSize); |
|
119 } |
|
120 |
|
121 /* |
|
122 * DProfilerIttSampler::Reset() |
|
123 * |
|
124 * @param DProfilerSampleStream* sample stream |
|
125 * @param TUint32 Offset |
|
126 */ |
|
127 template <int BufferSize> |
|
128 TInt DProfilerIttSampler<BufferSize>::Reset(DProfilerSampleStream* aStream, TUint32 aSyncOffset) |
|
129 { |
|
130 Kern::Printf("DProfilerIttSampler<%d>::Reset - calling superclass reset",BufferSize); |
|
131 DProfilerGenericSampler<BufferSize>::Reset(aStream); |
|
132 |
|
133 // check if reset called in stop (by driver) |
|
134 if(aSyncOffset != 999999) |
|
135 { |
|
136 #ifdef ITT_EVENT_HANDLER |
|
137 // Itt event handler |
|
138 if(iEventHandler) |
|
139 { |
|
140 // stop previous sampling if still running |
|
141 Kern::Printf("Stopping DIttEventHandler"); |
|
142 iEventHandler->Stop(); |
|
143 iEventHandler->Close(); |
|
144 iEventHandler = NULL; |
|
145 } |
|
146 |
|
147 Kern::Printf("Initiating DIttEventHandler"); |
|
148 iEventHandler = new DIttEventHandler(this->iSampleBuffer, this->gppSamplerData); |
|
149 if(iEventHandler) |
|
150 { |
|
151 Kern::Printf("Creating DIttEventHandler"); |
|
152 TInt err(iEventHandler->Create()); |
|
153 if(err != KErrNone) |
|
154 { |
|
155 Kern::Printf("Error in creation of DIttEventHandler, error %d", err); |
|
156 return err; |
|
157 } |
|
158 } |
|
159 else |
|
160 { |
|
161 Kern::Printf("Could not initiate DIttEventHandler"); |
|
162 return KErrGeneral; |
|
163 } |
|
164 |
|
165 // set first sample at the 10 ms, should be enough |
|
166 this->ittSamplerImpl.iIttSamplingPeriod = 10; |
|
167 #else |
|
168 this->ittSamplerImpl.iIttSamplingPeriod = this->iSamplingPeriod; |
|
169 #endif |
|
170 this->ittSamplerImpl.iIttSamplingPeriodDiv2 = (TInt)(this->ittSamplerImpl.iIttSamplingPeriod / 2); |
|
171 LOGSTRING3("CProfilerIttSampler<%d>::Reset - set ITT sampling period to %d", |
|
172 BufferSize,this->ittSamplerImpl.iIttSamplingPeriod); |
|
173 } |
|
174 else |
|
175 { |
|
176 LOGSTRING2("DProfilerIttSampler<%d>::Reset - reset in stop", BufferSize); |
|
177 #ifdef ITT_EVENT_HANDLER |
|
178 // destroy memory event handler |
|
179 if(iEventHandler) |
|
180 { |
|
181 // stop previous sampling if still running |
|
182 iEventHandler->Stop(); |
|
183 iEventHandler->Close(); |
|
184 iEventHandler = NULL; |
|
185 } |
|
186 #endif |
|
187 return KErrNone; // return if reset called in stop |
|
188 } |
|
189 |
|
190 TInt length(ittSamplerImpl.CreateFirstSample()); |
|
191 this->iSampleBuffer->AddSample((TUint8*)&length,1); |
|
192 this->iSampleBuffer->AddSample(ittSamplerImpl.itt_sample, length); |
|
193 this->sampleInProgress = false; |
|
194 this->sampleNeeded = false; |
|
195 //LOGSTRING("DProfilerIttSampler::Reset - exit"); |
|
196 this->ittSamplerImpl.Reset(); |
|
197 return KErrNone; |
|
198 |
|
199 } |
|
200 |
|
201 /* |
|
202 * DProfilerIttSampler::PostSample |
|
203 * |
|
204 * Function for finishing sample |
|
205 */ |
|
206 template <int BufferSize> |
|
207 TInt DProfilerIttSampler<BufferSize>::PostSample() |
|
208 { |
|
209 #ifdef ITT_EVENT_HANDLER |
|
210 if(!ittSamplerImpl.iFirstSampleTaken) // if we haven't read the initial state |
|
211 { |
|
212 #endif |
|
213 if(sampleNeeded) |
|
214 { |
|
215 this->sampleNeeded = false; |
|
216 //LOGSTRING3("CProfilerIttSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus()); |
|
217 //Kern::Printf("DProfilerIttSampler<%d>::PostSample - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus()); |
|
218 |
|
219 TInt length = this->ittSamplerImpl.SampleImpl(this->gppSamplerData->lastPcValue, |
|
220 this->gppSamplerData->sampleNumber); |
|
221 if(length != 0) |
|
222 { |
|
223 LOGSTRING("ITT sampler PostSample - starting to sample"); |
|
224 |
|
225 while(length > 0) |
|
226 { |
|
227 this->iSampleBuffer->AddSample(ittSamplerImpl.itt_sample,length); |
|
228 length = this->ittSamplerImpl.SampleImpl( this->gppSamplerData->lastPcValue, |
|
229 this->gppSamplerData->sampleNumber ); |
|
230 if(length == 0) |
|
231 { |
|
232 LOGSTRING("MEM sampler PostSample - all samples generated!"); |
|
233 } |
|
234 } |
|
235 LOGSTRING("ITT sampler PostSample - finished sampling"); |
|
236 } |
|
237 this->sampleInProgress = false; |
|
238 } |
|
239 #ifdef ITT_EVENT_HANDLER |
|
240 } |
|
241 if(!iEventHandler->Tracking()) |
|
242 { |
|
243 iEventHandler->Start(); |
|
244 Kern::Printf("DProfilerITTSampler<%d>::PostSample - ITT handler started",BufferSize); |
|
245 } |
|
246 |
|
247 #endif |
|
248 |
|
249 LOGSTRING2("ITT sampler PostSample - finished sampling, time: %d", gppSamplerData->sampleNumber); |
|
250 |
|
251 // finally perform superclass postsample |
|
252 TInt i(this->DProfilerGenericSampler<BufferSize>::PostSample()); |
|
253 return i; |
|
254 } |
|
255 |
|
256 /* |
|
257 * DProfilerIttSampler::PostSampleNeeded() |
|
258 * |
|
259 * Function for deciding if sample handling is needed |
|
260 */ |
|
261 template <int BufferSize> |
|
262 TBool DProfilerIttSampler<BufferSize>::PostSampleNeeded() |
|
263 { |
|
264 LOGSTRING3("CProfilerIttSampler<%d>::PostSampleNeeded - state %d",BufferSize,this->iSampleBuffer->GetBufferStatus()); |
|
265 |
|
266 TUint32 status = this->iSampleBuffer->iBufferStatus; |
|
267 |
|
268 if(status == DProfilerSampleBuffer::BufferCopyAsap || status == DProfilerSampleBuffer::BufferFull || this->sampleNeeded == true) |
|
269 { |
|
270 return true; |
|
271 } |
|
272 |
|
273 return false; |
|
274 } |
|
275 |
|
276 /* |
|
277 * DProfilerIttSampler::Sample |
|
278 * |
|
279 * Function for initiating sampling |
|
280 */ |
|
281 template <int BufferSize> |
|
282 void DProfilerIttSampler<BufferSize>::Sample() |
|
283 { |
|
284 LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize); |
|
285 |
|
286 //#ifdef ITT_TEST |
|
287 LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize); |
|
288 |
|
289 if(ittSamplerImpl.SampleNeeded(this->gppSamplerData->sampleNumber) && this->sampleInProgress == false) |
|
290 { |
|
291 this->sampleInProgress = true; |
|
292 this->sampleNeeded = true; |
|
293 |
|
294 LOGSTRING2("CProfilerIttSampler<%d>::Sample - sample needed",BufferSize); |
|
295 } |
|
296 #ifdef ITT_EVENT_HANDLER |
|
297 // call this to increase the time stamp |
|
298 else if(iEventHandler->SampleNeeded()) |
|
299 { |
|
300 // set the flag for post sampling |
|
301 this->sampleNeeded = true; |
|
302 } |
|
303 #endif |
|
304 |
|
305 LOGSTRING2("CProfilerIttSampler<%d>::Sample",BufferSize); |
|
306 return; |
|
307 } |
|
308 |
|
309 /* |
|
310 * Destructor |
|
311 */ |
|
312 template <int BufferSize> |
|
313 DProfilerIttSampler<BufferSize>::~DProfilerIttSampler() |
|
314 { |
|
315 LOGSTRING2("CProfilerIttSampler<%d>::~CProfilerIttSampler",BufferSize); |
|
316 #ifdef ITT_EVENT_HANDLER |
|
317 if(iEventHandler) |
|
318 { |
|
319 // stop previous sampling if still running |
|
320 iEventHandler->Stop(); |
|
321 iEventHandler->Close(); |
|
322 iEventHandler = NULL; |
|
323 } |
|
324 #endif |
|
325 } |
|
326 #endif |
|
327 // end of file |