tracesrv/tracecore/btrace_handler/src/TraceCoreMediaSWriter.cpp
changeset 56 aa2539c91954
equal deleted inserted replaced
54:a151135b0cf9 56:aa2539c91954
       
     1 // Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Trace Core
       
    15 //
       
    16 
       
    17 #include <kernel/kernel.h>
       
    18 
       
    19 #include "TraceCoreMediaSWriter.h"
       
    20 #include "TraceCoreMediaIf.h"
       
    21 #include "TraceCoreConstants.h"
       
    22 #include "TraceCore.h"
       
    23 #include "TraceCoreSendReceive.h"
       
    24 #include "TraceCoreDebug.h"
       
    25 
       
    26 
       
    27 //- Internal definitions ----------------------------------------------------
       
    28 #ifdef MEDIA_WRITER_STATISTICS
       
    29 
       
    30 /**
       
    31  * Collects statistics about the media writer
       
    32  */
       
    33 class TMediaSWriterStatistics
       
    34     {
       
    35 public:
       
    36     TUint32 iTraces;                // Number of traces received
       
    37     TUint32 iSent;                  // Number of traces sent
       
    38     TUint32 iFailed;                // Number of traces failed to send
       
    39     TUint32 iMissed;                // Number of traces missed due to not enough buffers
       
    40     TUint32 iSleepCount;            // Number of times the threads have slept waiting for buffers
       
    41     TUint32 iCannotSleepCount;      // Number of times a thread could not be slept when it should
       
    42     TUint32 iBlockCount;            // Number of times a thread has been blocked waiting for buffers
       
    43     TUint32 iCannotBlockCount;      // Number of times a thread could not be blocked when it should
       
    44     TUint32 iWaitDidNotHelp;        // Number of waits that did not help
       
    45     TUint32 iMinFreeBuffers;        // Minimum number of free buffers since boot
       
    46     TUint32 iInvalidContextTrace;   // Number of IRQ / IDFC traces ignored
       
    47     TUint32 iIdlePings;             // Statistics are written after some idle time
       
    48     TBool iStatisticsChanged;       // Flags indicating change in statistics
       
    49     };
       
    50 
       
    51 /**
       
    52  * Macro to wrap statistics-related code
       
    53  */
       
    54 #define STATS( x ) x
       
    55 
       
    56 /**
       
    57  * Initializes the statistics structure
       
    58  */
       
    59 TBool DTraceCoreMediaSWriter::InitStatistics()
       
    60     {
       
    61     iStatistics = new TMediaSWriterStatistics();
       
    62     return iStatistics != NULL;
       
    63     }
       
    64 
       
    65 #else
       
    66 
       
    67 /**
       
    68  * Empty class for statistics if flag is not set
       
    69  */
       
    70 class TMediaSWriterStatistics {};
       
    71 
       
    72 #define STATS( x )
       
    73 
       
    74 #endif
       
    75 
       
    76 
       
    77 /**
       
    78  * Max length of one trace
       
    79  */
       
    80 const TUint32 KMaxBufLength = 256;
       
    81 
       
    82 /**
       
    83  * Number of traces that can be buffered
       
    84  */
       
    85 const TUint32 KBufCount = 1;
       
    86 
       
    87 /**
       
    88  * Constructor
       
    89  */
       
    90 EXPORT_C DTraceCoreMediaSWriter::DTraceCoreMediaSWriter()
       
    91 : DTraceCoreWriter( EWriterTypeUSBPhonet )
       
    92 , iSendDfc( DTraceCoreMediaSWriter::SendDfc, this, DTraceCore::GetActivationQ(), KDefaultDfcPriority )
       
    93 , iSendTimerActive( EFalse )
       
    94 , iFirstFreeBuffer( NULL )
       
    95 , iFirstReadyBuffer( NULL )
       
    96 , iLastReadyBuffer( NULL )
       
    97 , iTraceBuffers( NULL )
       
    98 , iFreeBuffers( KBufCount )
       
    99 , iSenderThread( NULL )
       
   100 , iLastTraceSent( 0 )
       
   101 , iStatistics( NULL )
       
   102     {
       
   103     // No implementation in constructor
       
   104     }
       
   105 
       
   106 
       
   107 /**
       
   108  * Destructor
       
   109  */
       
   110 EXPORT_C DTraceCoreMediaSWriter::~DTraceCoreMediaSWriter()
       
   111     {
       
   112     // Delete all trace buffers
       
   113     for ( TUint i = 0; i < KBufCount; i++ )
       
   114         {
       
   115         delete[] iTraceBuffers[ i ].iBuffer;
       
   116         }
       
   117 
       
   118     delete[] iTraceBuffers;
       
   119     delete iStatistics;
       
   120     }
       
   121 
       
   122 
       
   123 /**
       
   124  * Registers this writer to TraceCore
       
   125  *
       
   126  * @return KErrNone if successful
       
   127  */
       
   128 EXPORT_C TInt DTraceCoreMediaSWriter::Register()
       
   129     {
       
   130     // Media writer uses the media interface from SendReceive
       
   131     TInt retval( KErrGeneral );
       
   132 
       
   133     // Get TraceCore
       
   134     DTraceCore* traceCore = DTraceCore::GetInstance();
       
   135     if ( traceCore != NULL )
       
   136         {
       
   137 
       
   138         // Get MediaWriter interface
       
   139         DTraceCoreMediaIf* writerIf = traceCore->GetSendReceive().GetMediaWriterIf();
       
   140         if ( writerIf != NULL )
       
   141             {
       
   142             // Allocates memory for the trace buffers
       
   143             TBool memOK = ETrue;
       
   144             STATS( memOK = InitStatistics() );
       
   145             if(memOK)
       
   146                 {
       
   147                 iTraceBuffers = new TTraceBuffer[ KBufCount ];
       
   148                 }
       
   149             if (iTraceBuffers == NULL)
       
   150                 {
       
   151                 memOK=EFalse;
       
   152                 }
       
   153             if ( memOK )
       
   154                 {
       
   155                 for ( TUint i = 0; i < KBufCount && memOK; i++ )
       
   156                     {
       
   157                     iTraceBuffers[ i ].iBuffer = new TUint8[ KMaxBufLength ];
       
   158                     if (iTraceBuffers[ i ].iBuffer == NULL )
       
   159                         {
       
   160                         memOK = EFalse;
       
   161                         }
       
   162                     if ( memOK )
       
   163                         {
       
   164                         // Initially all buffers are linked to iFirstFreeBuffer
       
   165                         // Casting needed to work around armv5 "pointless comparison of unsigned integer with zero" warning
       
   166                         if ( (TInt) i < (TInt) ( KBufCount - 1 ) )
       
   167                             {
       
   168                             iTraceBuffers[ i ].iNext = &( iTraceBuffers[ i + 1 ] );
       
   169                             }
       
   170                         }
       
   171                     else
       
   172                         {
       
   173                         memOK = EFalse;
       
   174                         }
       
   175                     }
       
   176                 }
       
   177             else
       
   178                 {
       
   179                 memOK = EFalse;
       
   180                 }
       
   181 
       
   182             // Memory was allocated succesfully
       
   183             if ( memOK )
       
   184                 {
       
   185                 iFastCounterBetweenTraces = NKern::FastCounterFrequency() / GetTraceFrequency();
       
   186                 iFirstFreeBuffer = iTraceBuffers;
       
   187 
       
   188                 // Register to the TraceCore
       
   189                 retval = DTraceCoreWriter::Register();
       
   190                 if ( retval == KErrNone )
       
   191                     {
       
   192                     iMediaIf = writerIf;
       
   193                     }
       
   194                 }
       
   195             else
       
   196                 {
       
   197                 retval = KErrNoMemory;
       
   198                 }
       
   199             }
       
   200         }
       
   201     TC_TRACE( ETraceLevelFlow, Kern::Printf("<DTraceCoreMediaSWriter::Register - %d", retval) );
       
   202     return retval;
       
   203     }
       
   204 
       
   205 
       
   206 /**
       
   207  * Starts an entry
       
   208  *
       
   209  * @param aType the type of the trace entry
       
   210  * @return the entry ID that is passed to other Write-functions
       
   211  */
       
   212 EXPORT_C TUint32 DTraceCoreMediaSWriter::WriteStart( TWriterEntryType aType )
       
   213     {
       
   214 
       
   215     // Detaches the first free buffer from the free buffers list
       
   216     TInt context( NKern::CurrentContext() );
       
   217     TTraceBuffer* freeBuf = NULL;
       
   218 
       
   219     if ( context == NKern::EThread || context == NKern::EIDFC )
       
   220         {
       
   221 #ifndef __SMP__
       
   222         // In non SMP env the __SPIN_LOCK macro is empty. We need Kern::Lock.
       
   223 		NKern::Lock(); // Unlocked in WriteEnd
       
   224 #else
       
   225 		//already locked by BTrace spin lock
       
   226 #endif
       
   227 
       
   228 		freeBuf = iFirstFreeBuffer;
       
   229 
       
   230         if ( freeBuf != NULL )
       
   231             {
       
   232             StartBuffer( aType, *freeBuf );
       
   233             }
       
   234         }
       
   235     else
       
   236         {
       
   237         freeBuf = NULL;
       
   238         }
       
   239 
       
   240     return ( TUint32 )freeBuf;
       
   241     }
       
   242 
       
   243 
       
   244 /**
       
   245  * Ends an entry
       
   246  *
       
   247  * @param aEntryId the entry ID returned by WriteStart
       
   248  * @param aWriteEndingZero If ETrue, write ending zero.
       
   249  */
       
   250 EXPORT_C void DTraceCoreMediaSWriter::WriteEnd( TUint32 aEntryId  )
       
   251     {
       
   252 
       
   253     if ( aEntryId != 0 )
       
   254         {
       
   255         TTraceBuffer* buf = ( TTraceBuffer* )aEntryId;
       
   256         TBool drop = EndBuffer( *buf );
       
   257 
       
   258         if( !drop ) //trace isn't dropped
       
   259             {
       
   260             iSendDfc.RawAdd();
       
   261             }
       
   262 
       
   263         // Locked in WriteStart
       
   264 #ifndef __SMP__
       
   265         // In non SMP the __SPIN_LOCK macro is empty. We need Kern::Unlock.
       
   266 		NKern::Unlock(); // Locked in WriteStart
       
   267 #else
       
   268 		//BTrace lock is used from outside of this method.
       
   269 #endif
       
   270         }
       
   271     }
       
   272 
       
   273 
       
   274 /**
       
   275  * Writes 8-bit data to given entry
       
   276  *
       
   277  * @param aEntryId the entry ID returned by WriteStart
       
   278  * @param aData the trace data
       
   279  */
       
   280 EXPORT_C void DTraceCoreMediaSWriter::WriteData( TUint32 aEntryId, TUint8 aData )
       
   281     {
       
   282     if ( aEntryId != 0 )
       
   283         {
       
   284         TTraceBuffer* buf = ( TTraceBuffer* )aEntryId;
       
   285         if ( buf->iLength < KMaxBufLength )
       
   286             {
       
   287             *( buf->iBuffer + buf->iLength ) = aData;
       
   288             buf->iLength++;
       
   289             }
       
   290         }
       
   291     }
       
   292 
       
   293 
       
   294 /**
       
   295  * Writes 16-bit data to given entry
       
   296  *
       
   297  * @param aEntryId the entry ID returned by WriteStart
       
   298  * @param aData the trace data
       
   299  */
       
   300 EXPORT_C void DTraceCoreMediaSWriter::WriteData( TUint32 aEntryId, TUint16 aData )
       
   301     {
       
   302     if ( aEntryId != 0 )
       
   303         {
       
   304         TTraceBuffer* buf = ( TTraceBuffer* )aEntryId;
       
   305         if ( buf->iLength + sizeof ( TUint16 ) <= KMaxBufLength )
       
   306             {
       
   307             *( ( TUint16* )( buf->iBuffer + buf->iLength ) ) = aData;
       
   308             buf->iLength += sizeof ( TUint16 );
       
   309             }
       
   310         }
       
   311     }
       
   312 
       
   313 
       
   314 /**
       
   315  * Writes 32-bit data to given entry
       
   316  *
       
   317  * @param aEntryId the entry ID returned by WriteStart
       
   318  * @param aData the trace data
       
   319  */
       
   320 EXPORT_C void DTraceCoreMediaSWriter::WriteData( TUint32 aEntryId, TUint32 aData )
       
   321     {
       
   322     if ( aEntryId != 0 )
       
   323         {
       
   324         TTraceBuffer* buf = ( TTraceBuffer* )aEntryId;
       
   325         if ( buf->iLength + sizeof ( TUint32 ) <= KMaxBufLength )
       
   326             {
       
   327             *( ( TUint32* )( buf->iBuffer + buf->iLength ) ) = SWAP_DATA( aData );
       
   328             buf->iLength += sizeof ( TUint32 );
       
   329             }
       
   330         }
       
   331     }
       
   332 
       
   333 
       
   334 /**
       
   335  * DFC for sending data
       
   336  *
       
   337  * @param aMediaWriter the media writer
       
   338  */
       
   339 void DTraceCoreMediaSWriter::SendDfc( TAny* aMediaWriter )
       
   340     {
       
   341     DTraceCoreMediaSWriter* writer = static_cast< DTraceCoreMediaSWriter* >( aMediaWriter );
       
   342     writer->SendDfc();
       
   343     }
       
   344 
       
   345 
       
   346 /**
       
   347  * Called from static DFC function to send a buffer
       
   348  */
       
   349 void DTraceCoreMediaSWriter::SendDfc()
       
   350     {
       
   351     // Create and send note random values
       
   352     TBuf8<64> note; // CodForChk_Dis_Magic
       
   353     note.Append(0xAE); // Dont care, CodForChk_Dis_Magic
       
   354     note.Append(0xAE); // Dont care, CodForChk_Dis_Magic
       
   355     note.Append(0x00); // Lentght MSB, CodForChk_Dis_Magic
       
   356     note.Append(0x02); // Length LSB, CodForChk_Dis_Magic
       
   357     note.Append(0xED); // Dont care, CodForChk_Dis_Magic
       
   358     note.Append(0xED); // Dont care, CodForChk_Dis_Magic
       
   359 
       
   360     iMediaIf->SendTrace( note );
       
   361     }
       
   362 
       
   363 // End of File