69 * |
71 * |
70 * @param TUint32 Sample number |
72 * @param TUint32 Sample number |
71 * |
73 * |
72 */ |
74 */ |
73 TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum) |
75 TBool IttSamplerImpl::SampleNeeded(TUint32 sampleNum) |
74 { |
|
75 #ifdef ITT_EVENT_HANDLER |
|
76 iCount++; |
|
77 if (iCount <= iIttSamplingPeriod && ((iCount % iIttSamplingPeriod) == 0 || (iCount % iIttSamplingPeriodDiv2) == 0)) |
|
78 { |
76 { |
79 LOGSTRING2("IttSamplerImpl::SampleNeeded - time: %d", iCount); |
77 iCount = sampleNum; |
80 iTimeToSample = true; |
78 LOGSTRING2("IttSamplerImpl::SampleNeeded - time: %d", iCount); |
81 #else |
79 |
82 // no need to do anything, always a good time to sample. |
80 if ((iCount % iIttSamplingPeriod) == 0) |
83 // Sample time filtering is done in IttSamplerImpl:SampleImpl() function |
81 { |
84 #endif |
|
85 return true; |
82 return true; |
86 #ifdef ITT_EVENT_HANDLER |
83 } |
|
84 return false; |
87 } |
85 } |
88 else |
|
89 { |
|
90 return false; |
|
91 } |
|
92 #endif |
|
93 } |
|
94 |
86 |
95 /* |
87 /* |
96 * IttSamplerImpl::SampleImpl(TUint32 pc, TUint32 sampleNum) |
88 * IttSamplerImpl::SampleImpl(TUint32 pc, TUint32 sampleNum) |
97 * |
89 * |
98 * @param TUint32 program counter |
90 * @param TUint32 program counter |
99 * @param TUint32 sample number |
91 * @param TUint32 sample number |
100 */ |
92 */ |
101 TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum) |
93 TInt IttSamplerImpl::SampleImpl(TUint32 pc,TUint32 sampleNum) |
102 { |
94 { |
|
95 //LOGSTRING3("IttSamplerImpl::SampleImpl pc %d samplenum %d",pc, sampleNum); |
103 // in order to avoid overloading the interrupt |
96 // in order to avoid overloading the interrupt |
104 // only one dynamic file in each 50ms is added to the stream |
97 // only one dynamic file in each 50ms is added to the stream |
105 // with the application of the tool in mind, this is |
98 // with the application of the tool in mind, this is |
106 // a reasonable measure |
99 // a reasonable measure |
107 |
100 TInt ret(0); |
108 // encode a process binary |
101 // encode a process binary |
109 sampleDescriptor.Zero(); |
102 |
110 // original |
103 //sampleDescriptor.Zero(); |
111 if((sampleNum % 20) != 0) return 0; |
104 if(iTimeToSample) |
112 if((sampleNum % 40) == 0) |
105 { |
113 { |
|
114 // encode a library binary |
106 // encode a library binary |
115 sampleDescriptor.Zero(); |
107 //sampleDescriptor.Zero(); |
116 DObjectCon* libs = Kern::Containers()[ELibrary]; |
108 if(iInitState == KIttHandlingLibs) |
117 TInt libCount = libs->Count(); |
109 { |
118 |
110 if(iLibsCount < 20) |
119 // go 20 binaries through at a time |
111 { |
120 for(TInt i=0;i<20;i++) |
112 ret = HandleLibs(sampleNum); |
121 { |
113 iLibsCount++; |
122 if(currentLibCount >= libCount) |
114 while(ret == KErrAlreadyExists) |
123 { |
115 { |
124 currentLibCount = 0; |
116 ret = HandleLibs(sampleNum); |
125 } |
117 iLibsCount++; |
126 |
118 } |
127 DLibrary* lib = (DLibrary*)(*libs)[currentLibCount]; |
119 } |
128 currentLibCount++; |
120 else |
129 |
121 { |
130 DCodeSeg* seg = lib->iCodeSeg; |
122 iLibsCount = 0; |
131 if(seg != 0) |
123 return 0; |
132 { |
124 } |
133 if( (seg->iMark & 0x80) == 0) |
125 } |
134 { |
126 //LOGSTRING2("IttSamplerImpl::SampleImpl HandledLibs %d", ret); |
135 this->sample[0] = seg->iFileName->Length(); |
127 // one library has been read to sample, needs to be written to file |
136 sampleDescriptor.Append(*(seg->iFileName)); |
128 |
137 sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4); |
129 else if(iInitState == KIttHandlingCodeSegs) |
138 sampleDescriptor.Append((TUint8*)&(seg->iSize),4); |
130 { |
|
131 if(iCodeSegsCount < 20) |
|
132 { |
|
133 ret = HandleSegs(sampleNum); |
|
134 iCodeSegsCount++; |
|
135 while(ret == KErrAlreadyExists) |
|
136 { |
|
137 ret = HandleSegs(sampleNum); |
|
138 iCodeSegsCount++; |
|
139 } |
|
140 } |
|
141 |
|
142 else |
|
143 { |
|
144 iCodeSegsCount = 0; |
|
145 return 0; |
|
146 } |
|
147 } |
|
148 |
|
149 //LOGSTRING2("IttSamplerImpl::SampleImpl HandledSegs %d", ret); |
|
150 else |
|
151 { |
|
152 // nothing to do |
|
153 Kern::Printf("IttSamplerImpl::SampleImpl - should not be here"); |
|
154 return 0; |
|
155 } |
|
156 } |
|
157 else |
|
158 { |
|
159 LOGSTRING("IttSamplerImpl::SampleImpl Not time to sample"); |
|
160 } |
|
161 |
|
162 return ret; |
|
163 } |
|
164 |
|
165 /* |
|
166 * IttSamplerImpl::Reset() |
|
167 */ |
|
168 void IttSamplerImpl::Reset() |
|
169 { |
|
170 iTimeToSample = ETrue; |
139 #ifdef ITT_EVENT_HANDLER |
171 #ifdef ITT_EVENT_HANDLER |
140 sampleDescriptor.Append((TUint8*)&(sampleNum),4); |
172 iInitialLibsTaken= EFalse; |
141 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
173 iInitialSegsTaken= EFalse; |
142 this->iFirstSampleTaken = ETrue; |
|
143 #else |
|
144 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
145 #endif |
174 #endif |
146 seg->iMark = (seg->iMark | 0x80); |
175 iCurrentLibCount = 0; |
147 |
176 iLibsCount = 0; |
148 this->sample[0] = sampleDescriptor.Size(); |
177 iCodeSegsCount = 0; |
149 return sampleDescriptor.Size()+1; |
178 iLatestCodeseg = NULL; |
150 } |
|
151 } |
|
152 } |
|
153 } else |
|
154 { |
|
155 SDblQue* codeSegList = Kern::CodeSegList(); |
|
156 //Kern::Printf("PI"); |
|
157 //TUint c = 0; |
|
158 // the global list |
|
159 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
|
160 { |
|
161 DCodeSeg* seg = _LOFF(codeseg, DCodeSeg, iLink); |
|
162 if(seg != 0) |
|
163 { |
|
164 if( (seg->iMark & 0x80) == 0) |
|
165 { |
|
166 this->sample[0] = seg->iFileName->Length(); |
|
167 sampleDescriptor.Append(*(seg->iFileName)); |
|
168 sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4); |
|
169 sampleDescriptor.Append((TUint8*)&(seg->iSize),4); |
|
170 #ifdef ITT_EVENT_HANDLER |
|
171 sampleDescriptor.Append((TUint8*)&(sampleNum),4); |
|
172 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
173 this->iFirstSampleTaken = ETrue; |
|
174 #else |
|
175 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
176 #endif |
|
177 seg->iMark = (seg->iMark | 0x80); |
|
178 |
|
179 this->sample[0] = sampleDescriptor.Size(); |
|
180 return sampleDescriptor.Size()+1; |
|
181 } |
|
182 } |
|
183 } |
|
184 } |
|
185 return 0; |
|
186 } |
|
187 |
|
188 /* |
|
189 * IttSamplerImpl::Reset() |
|
190 */ |
|
191 void IttSamplerImpl::Reset() |
|
192 { |
|
193 iTimeToSample = EFalse; |
|
194 #ifdef ITT_EVENT_HANDLER |
|
195 iFirstSampleTaken = EFalse; |
|
196 #endif |
|
197 this->currentLibCount = 0; |
|
198 this->itt_sample = (TUint8*)&(this->sample[0]); |
179 this->itt_sample = (TUint8*)&(this->sample[0]); |
199 sampleDescriptor.Zero(); |
180 sampleDescriptor.Zero(); |
200 |
181 |
201 // #ifdef ITT_TEST |
182 // #ifdef ITT_TEST |
202 SDblQue* codeSegList = Kern::CodeSegList(); |
183 SDblQue* codeSegList = Kern::CodeSegList(); |
203 // the global list |
184 // the global list |
204 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
185 for (SDblQueLink* codeseg= codeSegList->First(); codeseg!=(SDblQueLink*) codeSegList; codeseg=codeseg->iNext) |
205 { |
186 { |
206 DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink); |
187 DCodeSeg* seg = _LOFF(codeseg,DCodeSeg, iLink); |
207 //if(seg != 0) |
188 //if(seg != 0) |
208 { |
189 { |
209 if( (seg->iMark & 0x80) > 0) |
190 if( (seg->iMark & 0x80) > 0) |
210 { |
191 { |
211 seg->iMark = (seg->iMark & ~0x80); |
192 seg->iMark = (seg->iMark & ~0x80); |
212 } |
193 } |
213 } |
194 } |
214 } |
195 } |
215 // the garbage list |
196 // the garbage list |
|
197 |
|
198 NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex |
216 DObjectCon* libs = Kern::Containers()[ELibrary]; |
199 DObjectCon* libs = Kern::Containers()[ELibrary]; |
|
200 libs->Wait(); |
217 TInt libCount = libs->Count(); |
201 TInt libCount = libs->Count(); |
218 for(TInt i=0;i<libCount;i++) |
202 for(TInt i=0;i<libCount;i++) |
219 { |
203 { |
220 DLibrary* lib = (DLibrary*)(*libs)[i]; |
204 DLibrary* lib = (DLibrary*)(*libs)[i]; |
221 DCodeSeg* seg = lib->iCodeSeg; |
205 DCodeSeg* seg = lib->iCodeSeg; |
222 if( (seg->iMark & 0x80) > 0) |
206 if( (seg->iMark & 0x80) > 0) |
223 { |
207 { |
224 seg->iMark = (seg->iMark & ~0x80); |
208 seg->iMark = (seg->iMark & ~0x80); |
225 } |
209 } |
226 } |
210 } |
227 |
211 libs->Signal(); |
228 DObjectCon* procs = Kern::Containers()[EProcess]; |
212 NKern::ThreadLeaveCS(); |
229 TInt procCount = procs->Count(); |
|
230 for(TInt i=0;i<procCount;i++) |
|
231 { |
|
232 DProcess* pro = (DProcess*)(*procs)[i]; |
|
233 DCodeSeg* seg = pro->iCodeSeg; |
|
234 if(seg != 0) |
|
235 { |
|
236 if( (seg->iMark & 0x80) > 0) |
|
237 { |
|
238 seg->iMark = (seg->iMark & ~0x80); |
|
239 } |
|
240 } |
|
241 } |
|
242 //#endif //ITT_TEST |
213 //#endif //ITT_TEST |
243 } |
214 } |
|
215 /* |
|
216 * |
|
217 */ |
|
218 TInt IttSamplerImpl::HandleLibs(TUint32 sampleNum) |
|
219 { |
|
220 NKern::ThreadEnterCS(); // Prevent us from dying or suspending whilst holding a DMutex |
|
221 DObjectCon* libs = Kern::Containers()[ELibrary]; |
|
222 libs->Wait(); |
|
223 TInt libCount(libs->Count()); |
|
224 sampleDescriptor.Zero(); |
|
225 |
|
226 // go 20 binaries through at a time |
|
227 //for(TInt i=0;i<libCount;i++) |
|
228 if (iCurrentLibCount < libCount) |
|
229 { |
|
230 // get libs from |
|
231 DLibrary* lib = (DLibrary*)(*libs)[iCurrentLibCount]; |
|
232 libs->Signal(); |
|
233 NKern::ThreadLeaveCS(); |
|
234 iCurrentLibCount++; |
|
235 |
|
236 DCodeSeg* seg = lib->iCodeSeg; |
|
237 if(seg != 0) |
|
238 { |
|
239 if( (seg->iMark & 0x80) == 0) |
|
240 { |
|
241 this->sample[0] = seg->iFileName->Length(); |
|
242 sampleDescriptor.Append(*(seg->iFileName)); |
|
243 sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4); |
|
244 sampleDescriptor.Append((TUint8*)&(seg->iSize),4); |
|
245 |
|
246 #ifdef ITT_EVENT_HANDLER |
|
247 sampleDescriptor.Append((TUint8*)&(sampleNum),4); |
|
248 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
249 //this->iFirstSampleTaken = ETrue; |
|
250 #else |
|
251 //Kern::Printf("DLL: NM %S : RA:0x%x SZ:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize); |
|
252 #endif |
|
253 seg->iMark = (seg->iMark | 0x80); |
|
254 this->sample[0] = sampleDescriptor.Size(); |
|
255 return sampleDescriptor.Size()+1; |
|
256 } |
|
257 else |
|
258 { |
|
259 //Kern::Printf("Already met DLL: NM %S : RA:0x%x SZ:0x%x, SN:0x%x",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
260 return KErrAlreadyExists; |
|
261 } |
|
262 } |
|
263 } |
|
264 else |
|
265 { |
|
266 // check if list gone through |
|
267 iInitState = KIttHandlingCodeSegs; |
|
268 iInitialLibsTaken = ETrue; |
|
269 } |
|
270 libs->Signal(); |
|
271 NKern::ThreadLeaveCS(); |
|
272 return 0; |
|
273 } |
|
274 /* |
|
275 * |
|
276 */ |
|
277 TInt IttSamplerImpl::HandleSegs(TUint32 sampleNum) |
|
278 { |
|
279 SDblQue* codeSegList = Kern::CodeSegList(); |
|
280 //Kern::Printf("PI"); |
|
281 TUint count(0); |
|
282 sampleDescriptor.Zero(); |
|
283 if(iLatestCodeseg == NULL) |
|
284 { |
|
285 iLatestCodeseg = codeSegList->First(); |
|
286 } |
|
287 else |
|
288 { |
|
289 iLatestCodeseg = iLatestCodeseg->iNext; |
|
290 } |
|
291 |
|
292 // search the global code segment list |
|
293 //for (; iLatestCodeseg!=(SDblQueLink*) codeSegList; iLatestCodeseg=iLatestCodeseg->iNext) |
|
294 if (iLatestCodeseg != (SDblQueLink*) codeSegList) |
|
295 { |
|
296 DCodeSeg* seg = _LOFF(iLatestCodeseg, DCodeSeg, iLink); |
|
297 if(seg != 0) |
|
298 { |
|
299 if( (seg->iMark & 0x80) == 0) |
|
300 { |
|
301 this->sample[0] = seg->iFileName->Length(); |
|
302 sampleDescriptor.Append(*(seg->iFileName)); |
|
303 sampleDescriptor.Append((TUint8*)&(seg->iRunAddress),4); |
|
304 sampleDescriptor.Append((TUint8*)&(seg->iSize),4); |
|
305 #ifdef ITT_EVENT_HANDLER |
|
306 sampleDescriptor.Append((TUint8*)&(sampleNum),4); |
|
307 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
308 #else |
|
309 //Kern::Printf("EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
310 #endif |
|
311 seg->iMark = (seg->iMark | 0x80); |
|
312 count++; |
|
313 this->sample[0] = sampleDescriptor.Size(); |
|
314 return sampleDescriptor.Size()+1; |
|
315 } |
|
316 else |
|
317 { |
|
318 //Kern::Printf("Already met EXE2: NM %S : RA:0x%x SZ:0x%x, time: %d",seg->iFileName,seg->iRunAddress,seg->iSize, sampleNum); |
|
319 return KErrAlreadyExists; |
|
320 } |
|
321 } |
|
322 } |
|
323 // check if list gone through |
|
324 else //if (count == 0) |
|
325 { |
|
326 iInitialSegsTaken = ETrue; |
|
327 iTimeToSample = false; |
|
328 LOGSTRING("ITT sampler - all initial samples generated!"); |
|
329 } |
|
330 return 0; |
|
331 } |
|
332 |
244 // end of file |
333 // end of file |