75 } |
75 } |
76 |
76 |
77 inline TInt DProfilerSampleBuffer::AddSample(TUint8* aSample, TUint32 aLength) |
77 inline TInt DProfilerSampleBuffer::AddSample(TUint8* aSample, TUint32 aLength) |
78 { |
78 { |
79 TUint32 bytesTotal; |
79 TUint32 bytesTotal; |
80 |
80 #ifdef __SMP__ |
|
81 TInt intState(0); |
|
82 #endif |
81 // check whether the buffer status is |
83 // check whether the buffer status is |
82 switch (iBufferStatus) |
84 switch (iBufferStatus) |
83 { |
85 { |
84 case DProfilerSampleBuffer::BufferOk: |
86 case DProfilerSampleBuffer::BufferOk: |
85 // add the data normally to the buffer |
87 // add the data normally to the buffer |
86 bytesTotal = iBytesWritten+aLength; |
88 bytesTotal = iBytesWritten+aLength; |
87 |
89 |
88 if(bytesTotal < iBufferDataSize) |
90 if(bytesTotal < iBufferDataSize) |
89 { |
91 { |
|
92 #ifdef __SMP__ |
|
93 __SPIN_LOCK_IRQ(WriteSpinLock); |
|
94 #endif |
90 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength); |
95 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength); |
|
96 #ifdef __SMP__ |
|
97 __SPIN_UNLOCK_IRQ(WriteSpinLock); |
|
98 #endif |
91 iBytesWritten+=aLength; |
99 iBytesWritten+=aLength; |
92 return 0; |
100 return 0; |
93 } |
101 } |
94 else |
102 else |
95 { |
103 { |
96 |
104 |
97 // the sample does not fit to the buffer |
105 // the sample does not fit to the buffer |
98 // first copy as much data as we can fit to the first buffer |
106 // first copy as much data as we can fit to the first buffer |
99 TUint32 fitsToBuffer = iBufferDataSize-iBytesWritten; |
107 TUint32 fitsToBuffer(iBufferDataSize-iBytesWritten); |
100 TUint32 remaining = aLength-fitsToBuffer; |
108 TUint32 remaining(aLength-fitsToBuffer); |
101 |
109 LOGSTRING2("DProfilerSampleBuffer::AddSample sample does not fit to buffer, cpu %d", NKern::CurrentCpu()); |
|
110 #ifdef __SMP__ |
|
111 __SPIN_LOCK_IRQ(WriteSpinLock); |
|
112 #endif |
102 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,fitsToBuffer); |
113 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,fitsToBuffer); |
|
114 #ifdef __SMP__ |
|
115 __SPIN_UNLOCK_IRQ(WriteSpinLock); |
|
116 #endif |
103 iBytesWritten = iBufferDataSize; |
117 iBytesWritten = iBufferDataSize; |
104 |
118 |
|
119 #ifdef __SMP__ |
|
120 intState = __SPIN_LOCK_IRQSAVE(BufferStateSpinLock); |
|
121 #endif |
105 // ->switch to the double buffer |
122 // ->switch to the double buffer |
106 iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap; |
123 iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap; |
107 |
124 #ifdef __SMP__ |
108 TProfilerSampleBufStruct* tmpPtr = iBufStruct; |
125 __SPIN_UNLOCK_IRQRESTORE(BufferStateSpinLock, intState); |
|
126 #endif |
|
127 TProfilerSampleBufStruct* tmpPtr(iBufStruct); |
109 iBufStruct = iDblBufStruct; |
128 iBufStruct = iDblBufStruct; |
110 iDblBufStruct = tmpPtr; |
129 iDblBufStruct = tmpPtr; |
111 |
130 |
112 iDblBytesWritten = iBytesWritten; |
131 iDblBytesWritten = iBytesWritten; |
113 |
132 |
137 // add the data normally to the buffer |
162 // add the data normally to the buffer |
138 bytesTotal = iBytesWritten+aLength; |
163 bytesTotal = iBytesWritten+aLength; |
139 |
164 |
140 if(bytesTotal < iBufferDataSize) |
165 if(bytesTotal < iBufferDataSize) |
141 { |
166 { |
|
167 LOGSTRING2("DProfilerSampleBuffer::BufferCopyAsap, cpu %d", NKern::CurrentCpu()); |
|
168 #ifdef __SMP__ |
|
169 __SPIN_LOCK_IRQ(WriteSpinLock); |
|
170 #endif |
142 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength); |
171 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength); |
|
172 #ifdef __SMP__ |
|
173 __SPIN_UNLOCK_IRQ(WriteSpinLock); |
|
174 #endif |
143 iBytesWritten+=aLength; |
175 iBytesWritten+=aLength; |
144 return 0; |
176 return 0; |
145 } |
177 } |
146 else |
178 else |
147 { |
179 { |
148 // the double buffer is now also full - there is no |
180 // the double buffer is now also full - there is no |
149 // place to put the data -> we have to waste it! |
181 // place to put the data -> we have to waste it! |
150 // this is an indication of a too small buffer size |
182 // this is an indication of a too small buffer size |
|
183 #ifdef __SMP__ |
|
184 intState = __SPIN_LOCK_IRQSAVE(BufferStateSpinLock); |
|
185 #endif |
151 iBufferStatus = DProfilerSampleBuffer::BufferFull; |
186 iBufferStatus = DProfilerSampleBuffer::BufferFull; |
152 LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full1!!"); |
187 #ifdef __SMP__ |
|
188 __SPIN_UNLOCK_IRQRESTORE(BufferStateSpinLock, intState); |
|
189 #endif |
|
190 Kern::Printf("DProfilerSampleBuffer::AddSample - double buffer full1!! cpu %d", NKern::CurrentCpu()); |
153 return -1; |
191 return -1; |
154 } |
192 } |
155 |
193 |
156 case DProfilerSampleBuffer::BufferBeingCopied: |
194 case DProfilerSampleBuffer::BufferBeingCopied: |
157 |
195 |
158 // no difference to the BufferCopyAsap case |
196 // no difference to the BufferCopyAsap case |
159 bytesTotal = iBytesWritten+aLength; |
197 bytesTotal = iBytesWritten+aLength; |
160 |
198 |
161 if(bytesTotal < iBufferDataSize) |
199 if(bytesTotal < iBufferDataSize) |
162 { |
200 { |
|
201 LOGSTRING2("DProfilerSampleBuffer::BufferBeingCopied iBufferDataSize, cpu %d", NKern::CurrentCpu()); |
|
202 #ifdef __SMP__ |
|
203 __SPIN_LOCK_IRQ(WriteSpinLock); |
|
204 #endif |
163 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength); |
205 memcpy((&(iBufStruct->iDataStart))+iBytesWritten,aSample,aLength); |
|
206 #ifdef __SMP__ |
|
207 __SPIN_UNLOCK_IRQ(WriteSpinLock); |
|
208 #endif |
164 iBytesWritten+=aLength; |
209 iBytesWritten+=aLength; |
165 return 0; |
210 return 0; |
166 } |
211 } |
167 else |
212 else |
168 { |
213 { |
169 // the double buffer is now also full - there is no |
214 // the double buffer is now also full - there is no |
170 // place to put the data -> we have to waste it! |
215 // place to put the data -> we have to waste it! |
171 // this is an indication of a too small buffer size |
216 // this is an indication of a too small buffer size |
172 LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full2!!"); |
217 Kern::Printf("DProfilerSampleBuffer::AddSample - double buffer full2!! cpu %d", NKern::CurrentCpu()); |
173 |
|
174 // don't change the state to CProfilerSampleBuffer::BufferFull, since it is |
218 // don't change the state to CProfilerSampleBuffer::BufferFull, since it is |
175 // already being copied |
219 // already being copied |
176 return -1; |
220 return -1; |
177 } |
221 } |
178 |
222 |
179 case DProfilerSampleBuffer::BufferFull: |
223 case DProfilerSampleBuffer::BufferFull: |
180 // the buffer is still full, there is noting we can do |
224 // the buffer is still full, there is noting we can do |
181 // about it -> return |
225 // about it -> return |
182 LOGSTRING("DProfilerSampleBuffer::AddSample - double buffer full3!!"); |
226 Kern::Printf("DProfilerSampleBuffer::AddSample - double buffer full3!! cpu %d", NKern::CurrentCpu()); |
183 return -1; |
227 return -1; |
184 |
228 |
185 default: |
229 default: |
186 LOGSTRING("DProfilerSampleBuffer::AddSample - wrong switch!!"); |
230 Kern::Printf("DProfilerSampleBuffer::AddSample - wrong switch!!"); |
187 return -1; |
231 return -1; |
188 } |
232 } |
189 } |
233 } |
190 |
234 |
191 inline void DProfilerSampleBuffer::EndSampling() |
235 inline void DProfilerSampleBuffer::EndSampling() |
192 { |
236 { |
|
237 #ifdef __SMP__ |
|
238 TInt intState(0); |
|
239 #endif |
193 LOGSTRING("DProfilerSampleBuffer::EndSampling"); |
240 LOGSTRING("DProfilerSampleBuffer::EndSampling"); |
194 // this will switch to the dbl buffer even though |
241 // this will switch to the dbl buffer even though |
195 // the buffer is not full, so that data can be copied |
242 // the buffer is not full, so that data can be copied |
196 |
243 |
197 // during this operation, no other buffer |
244 // during this operation, no other buffer |
201 // buffer is in normal state ( this procedure is performed only once ) |
248 // buffer is in normal state ( this procedure is performed only once ) |
202 if(iBufferStatus == DProfilerSampleBuffer::BufferOk) |
249 if(iBufferStatus == DProfilerSampleBuffer::BufferOk) |
203 { |
250 { |
204 // ->switch to the double buffer |
251 // ->switch to the double buffer |
205 LOGSTRING("DProfilerSampleBuffer::EndSampling - switching to double buffer"); |
252 LOGSTRING("DProfilerSampleBuffer::EndSampling - switching to double buffer"); |
|
253 #ifdef __SMP__ |
|
254 intState = __SPIN_LOCK_IRQSAVE(BufferStateSpinLock); |
|
255 #endif |
206 iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap; |
256 iBufferStatus = DProfilerSampleBuffer::BufferCopyAsap; |
207 |
257 #ifdef __SMP__ |
208 TProfilerSampleBufStruct* tmpPtr = iBufStruct; |
258 __SPIN_UNLOCK_IRQRESTORE(BufferStateSpinLock, intState); |
|
259 #endif |
|
260 TProfilerSampleBufStruct* tmpPtr(iBufStruct); |
209 iBufStruct = iDblBufStruct; |
261 iBufStruct = iDblBufStruct; |
210 iDblBufStruct = tmpPtr; |
262 iDblBufStruct = tmpPtr; |
211 |
263 |
212 iDblBytesWritten = iBytesWritten; |
264 iDblBytesWritten = iBytesWritten; |
213 |
265 |
242 |
296 |
243 // written the dblBufStruct |
297 // written the dblBufStruct |
244 iBytesWritten = 0; |
298 iBytesWritten = 0; |
245 iDblBytesWritten = 0; |
299 iDblBytesWritten = 0; |
246 iDblBytesRead = 0; |
300 iDblBytesRead = 0; |
247 |
301 #ifdef __SMP__ |
|
302 intState = __SPIN_LOCK_IRQSAVE(BufferStateSpinLock); |
|
303 #endif |
248 iBufferStatus = DProfilerSampleBuffer::BufferOk; |
304 iBufferStatus = DProfilerSampleBuffer::BufferOk; |
|
305 #ifdef __SMP__ |
|
306 __SPIN_UNLOCK_IRQRESTORE(BufferStateSpinLock, intState); |
|
307 #endif |
249 } |
308 } |
250 |
309 |
251 inline void DProfilerSampleBuffer::DataCopied() |
310 inline void DProfilerSampleBuffer::DataCopied() |
252 { |
311 { |
|
312 #ifdef __SMP__ |
|
313 TInt intState(0); |
|
314 #endif |
253 iDblBytesRead = 0; |
315 iDblBytesRead = 0; |
254 iDblBytesWritten = 0; |
316 iDblBytesWritten = 0; |
|
317 #ifdef __SMP__ |
|
318 intState = __SPIN_LOCK_IRQSAVE(BufferStateSpinLock); |
|
319 #endif |
255 iBufferStatus = DProfilerSampleBuffer::BufferOk; |
320 iBufferStatus = DProfilerSampleBuffer::BufferOk; |
|
321 #ifdef __SMP__ |
|
322 __SPIN_UNLOCK_IRQRESTORE(BufferStateSpinLock, intState); |
|
323 #endif |
256 } |
324 } |
257 |
325 |
258 /* |
326 /* |
259 * |
327 * |
260 * Class DProfilerSampleStream implementation |
328 * Class DProfilerSampleStream implementation |
317 LOGSTRING("DProfilerSampleStream::ReleaseIfPending - exit"); |
385 LOGSTRING("DProfilerSampleStream::ReleaseIfPending - exit"); |
318 } |
386 } |
319 |
387 |
320 inline void DProfilerSampleStream::AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId) |
388 inline void DProfilerSampleStream::AddSamples(DProfilerSampleBuffer& aBuffer, TInt aSamplerId) |
321 { |
389 { |
322 LOGSTRING3("DProfilerSampleStream::AddSamples - entry ID: %d, currentbuffer: 0x%x", aSamplerId,iCurrentBuffer); |
390 LOGSTRING4("DProfilerSampleStream::AddSamples - entry ID: %d, currentbuffer: 0x%x, cpu %d", aSamplerId,iCurrentBuffer, NKern::CurrentCpu()); |
323 if(iCurrentBuffer != 0) |
391 if(iCurrentBuffer != 0) |
324 { |
392 { |
325 // the following will perform simple mutual exclusion |
393 // the following will perform simple mutual exclusion |
326 iAddingSamples++; |
394 iAddingSamples++; |
327 if(iAddingSamples > 1) |
395 if(iAddingSamples > 1) |
328 { |
396 { |
329 // there is someone else adding samples to the buffer |
397 // there is someone else adding samples to the buffer |
330 LOGSTRING("DProfilerSampleStream::AddSamples - mutex in use"); |
398 Kern::Printf("DProfilerSampleStream::AddSamples - mutex in use"); |
331 iAddingSamples--; |
399 iAddingSamples--; |
332 return; |
400 return; |
333 } |
401 } |
334 |
402 |
335 LOGSTRING("DProfilerSampleStream::AddSamples - reading TBapBuf"); |
403 LOGSTRING("DProfilerSampleStream::AddSamples - reading TBapBuf"); |
349 realBuf.iBuffer, |
417 realBuf.iBuffer, |
350 realBuf.iBufferSize, |
418 realBuf.iBufferSize, |
351 realBuf.iDataSize); |
419 realBuf.iDataSize); |
352 |
420 |
353 // get the address of the source buffer data |
421 // get the address of the source buffer data |
354 TUint8* src = (TUint8*)&(aBuffer.iDblBufStruct->iDataStart); |
422 TUint8* src((TUint8*)&(aBuffer.iDblBufStruct->iDataStart)); |
355 src += aBuffer.iDblBytesRead; |
423 src += aBuffer.iDblBytesRead; |
356 |
424 |
357 // the amount of data to copy is the 4 header bytes + |
425 // the amount of data to copy is the 4 header bytes + |
358 // the remaining data in the buffer |
426 // the remaining data in the buffer |
359 TInt amount = aBuffer.iDblBytesWritten-aBuffer.iDblBytesRead; |
427 TInt amount(aBuffer.iDblBytesWritten-aBuffer.iDblBytesRead); |
360 |
428 |
361 TUint8* dst = realBuf.iBuffer; |
429 TUint8* dst(realBuf.iBuffer); |
362 |
430 |
363 LOGSTRING4("DProfilerSampleStream::AddSamples - s:0x%x d:0x%x a:%d",src,dst,amount); |
431 LOGSTRING4("DProfilerSampleStream::AddSamples - s:0x%x d:0x%x a:%d",src,dst,amount); |
364 |
432 |
365 if(realBuf.iDataSize == 0) |
433 if(realBuf.iDataSize == 0) |
366 { |
434 { |
456 |
524 |
457 |
525 |
458 inline TInt DProfilerSampleStream::EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId) |
526 inline TInt DProfilerSampleStream::EndSampling(DProfilerSampleBuffer& aBuffer,TInt aSamplerId) |
459 { |
527 { |
460 LOGSTRING2("DProfilerSampleStream::EndSampling, sampler ID: %d",aSamplerId); |
528 LOGSTRING2("DProfilerSampleStream::EndSampling, sampler ID: %d",aSamplerId); |
461 |
529 #ifdef __SMP__ |
|
530 TInt intState(0); |
|
531 #endif |
462 // switch the buffer to double buffer |
532 // switch the buffer to double buffer |
463 // even though it would not be full yet |
533 // even though it would not be full yet |
464 // the switch is done only once / end sampling procedure |
534 // the switch is done only once / end sampling procedure |
465 // (Only with BufferOk status) |
535 // (Only with BufferOk status) |
466 aBuffer.EndSampling(); |
536 aBuffer.EndSampling(); |
486 // buffer status was changed to BufferOk in AddSamples() - |
556 // buffer status was changed to BufferOk in AddSamples() - |
487 // this means all data from it could be copied |
557 // this means all data from it could be copied |
488 // now we have to change the status of the buffer to BufferDataEnd, so |
558 // now we have to change the status of the buffer to BufferDataEnd, so |
489 // we know that the particular buffer has no more data to copy |
559 // we know that the particular buffer has no more data to copy |
490 LOGSTRING("DProfilerSampleStream::EndSampling - switch to BufferDataEnd"); |
560 LOGSTRING("DProfilerSampleStream::EndSampling - switch to BufferDataEnd"); |
|
561 #ifdef __SMP__ |
|
562 intState = __SPIN_LOCK_IRQSAVE(BufferStateSpinLock); |
|
563 #endif |
491 aBuffer.iBufferStatus = DProfilerSampleBuffer::BufferDataEnd; |
564 aBuffer.iBufferStatus = DProfilerSampleBuffer::BufferDataEnd; |
|
565 #ifdef __SMP__ |
|
566 __SPIN_UNLOCK_IRQRESTORE(BufferStateSpinLock, intState); |
|
567 #endif |
492 } |
568 } |
493 } |
569 } |
494 |
570 |
495 // the buffer was completely emptied to the client buffer, or there was no |
571 // the buffer was completely emptied to the client buffer, or there was no |
496 // data to copy to the client side |
572 // data to copy to the client side |
510 ptr.SetLength(4); |
586 ptr.SetLength(4); |
511 |
587 |
512 LOGSTRING2("DProfilerSampleStream::PerformCopy - start header copy HDR = 0x%x",header); |
588 LOGSTRING2("DProfilerSampleStream::PerformCopy - start header copy HDR = 0x%x",header); |
513 |
589 |
514 // write the header |
590 // write the header |
515 Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0); |
591 TInt err(Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0)); |
|
592 if (err != KErrNone) |
|
593 { |
|
594 Kern::Printf(("DProfilerSampleStream::PerformCopy() - thread des write error, %d"), err); |
|
595 } |
516 |
596 |
517 LOGSTRING2("DProfilerSampleStream::PerformCopy - copied header %d bytes",ptr.Size()); |
597 LOGSTRING2("DProfilerSampleStream::PerformCopy - copied header %d bytes",ptr.Size()); |
518 aOffset+=4; |
598 aOffset+=4; |
519 |
599 |
520 LOGSTRING("DProfilerSampleStream::PerformCopy - start copy"); |
600 LOGSTRING("DProfilerSampleStream::PerformCopy - start copy"); |
521 // write the data |
601 // write the data |
522 ptr.Set(aSrc,aAmount,aAmount); |
602 ptr.Set(aSrc,aAmount,aAmount); |
523 ptr.SetLength(aAmount); |
603 ptr.SetLength(aAmount); |
524 |
604 |
525 Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0); |
605 err = Kern::ThreadDesWrite(iClient,(TAny*)aDst,ptr,aOffset,KChunkShiftBy0); |
526 |
606 if (err != KErrNone) |
|
607 { |
|
608 Kern::Printf(("DProfilerSampleStream::PerformCopy() - thread des write error, %d"), err); |
|
609 } |
527 |
610 |
528 LOGSTRING2("DProfilerSampleStream::PerformCopy - copied data %d bytes",ptr.Size()); |
611 LOGSTRING2("DProfilerSampleStream::PerformCopy - copied data %d bytes",ptr.Size()); |
529 |
612 |
530 } |
613 } |