piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPlugin.cpp
branchRCL_3
changeset 19 da2cedce4920
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/piprofiler/plugins/DebugOutputWriterPlugin/src/DebOutWriterPlugin.cpp	Tue May 25 14:22:58 2010 +0300
@@ -0,0 +1,542 @@
+/*
+* Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). 
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description:  
+*
+*/
+
+
+//  Include Files  
+
+#include "DebOutWriterPlugin.h"	
+#include <e32base.h>
+//#include <piprofiler/EngineUIDs.h>
+#include <piprofiler/ProfilerTraces.h>
+#ifdef OST_TRACE_COMPILER_IN_USE
+#include <OpenSystemTrace.h>
+#include "DebOutWriterPluginTraces.h"
+#endif
+
+// engine properties
+const TUid KEngineStatusPropertyCat={0x2001E5AD};
+enum TEnginePropertyKeys
+    {
+    EProfilerEngineStatus = 8,
+    EProfilerErrorStatus
+    };
+
+// CONSTANTS
+// own UID
+const TUid KDebOutWriterPluginUid = { 0x2001E5BA };
+
+//  Member Functions
+/*
+ *
+ *	Class CDebOutWriterPlugin implementation
+ *
+ */
+
+CDebOutWriterPlugin* CDebOutWriterPlugin::NewL(const TUid /*aImplementationUid*/, TAny* /*aInitParams*/)
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::NewL() - entry"));
+	CDebOutWriterPlugin* self = new (ELeave) CDebOutWriterPlugin(KDebOutWriterPluginUid);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CDebOutWriterPlugin::NewL() - exit"));
+    return self;
+}
+
+CDebOutWriterPlugin::CDebOutWriterPlugin(const TUid aImplementationUid) :
+	iWriterType(aImplementationUid.iUid)
+    {
+    LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - entry"));
+    isEnabled = EFalse;
+    iWriterId = Id().iUid;
+    LOGTEXT(_L("CDebOutWriterPlugin::CDebOutWriterPlugin - exit"));
+    }
+
+CDebOutWriterPlugin::~CDebOutWriterPlugin()
+    {
+    LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - entry"));
+
+    iErrorStatus.Close();
+    
+    if(iWriterHandler)
+        {
+        iWriterHandler->Cancel();
+        delete iWriterHandler;
+        }
+    LOGTEXT(_L("CDebOutWriterPlugin::~CDebOutWriterPlugin - exit"));
+    }    
+    
+void CDebOutWriterPlugin::ConstructL()
+	{
+	// second phase constructor, anything that may leave must be constructed here
+
+	LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - entry"));
+	iWriterHandler = CDebOutWriterHandler::NewL(this);
+    User::LeaveIfError(iErrorStatus.Attach(KEngineStatusPropertyCat, EProfilerErrorStatus));
+    
+	LOGTEXT(_L("CDebOutWriterPlugin::ConstructL() - exit"));
+	}
+
+TInt CDebOutWriterPlugin::Start()
+	{
+	LOGTEXT(_L("CDebOutWriterPlugin::Start() - entry"));
+	
+#ifdef OST_TRACE_COMPILER_IN_USE
+    TInt err(KErrNone);
+	// activate traces on TraceCore
+    RTcDriverParameters tcdp_ThreadIdentification;
+    tcdp_ThreadIdentification.iComponentId = KOstTraceComponentID;
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END;
+    err = tcldd.ActivateTrace(tcdp_ThreadIdentification);
+
+    RDebug::Print(_L("Debug output activated"));
+    if(err != KErrNone)
+        RDebug::Print(_L("TraceCore LDD API responded: %d"), err);
+#endif
+
+	LOGTEXT(_L("CDebOutWriterPlugin::Start() - exit"));
+	return KErrNone;
+	}
+
+void CDebOutWriterPlugin::Stop()
+	{
+	LOGTEXT(_L("CDebOutWriterPlugin::Stop() - entry"));
+	iWriterHandler->Stop();
+#ifdef OST_TRACE_COMPILER_IN_USE
+	TInt err(KErrNone);
+    // activate traces on TraceCore
+    RTcDriverParameters tcdp_ThreadIdentification;
+    tcdp_ThreadIdentification.iComponentId = KOstTraceComponentID;
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    tcdp_ThreadIdentification.iGroupId = CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END;
+    err = tcldd.DeactivateTrace(tcdp_ThreadIdentification);
+
+    RDebug::Print(_L("Debug output deactivated"));
+    if(err != KErrNone)
+        RDebug::Print(_L("TraceCore LDD API responded: %d"), err);
+#endif
+	LOGTEXT(_L("CDebOutWriterPlugin::Stop() - exit"));
+	}
+
+TUid CDebOutWriterPlugin::Id() const
+	{
+    LOGSTRING2("CDebOutWriterPlugin::Id(): 0x%X", KDebOutWriterPluginUid.iUid );
+    return KDebOutWriterPluginUid;
+	//return iDtor_ID_Key;
+	}
+
+TBool CDebOutWriterPlugin::GetEnabled()
+	{
+	return isEnabled;
+	}
+
+void CDebOutWriterPlugin::SetValue( const TWriterPluginValueKeys aKey,
+                                    TDes& aValue )
+    {
+    TRAP_IGNORE( SetValueL( aKey, aValue ) );
+    }
+
+
+void CDebOutWriterPlugin::GetValue( const TWriterPluginValueKeys aKey,
+                                    TDes& aValue )
+    {
+    TRAP_IGNORE( GetValueL( aKey, aValue ) );
+    }
+
+
+
+void CDebOutWriterPlugin::SetValueL( const TWriterPluginValueKeys aKey, TDes& /*aValue*/ )
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - entry"));	
+	
+    switch( aKey )
+        {
+        case EWriterPluginEnabled:
+            isEnabled = ETrue;
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin enabled"));
+        	break;
+        case EWriterPluginDisabled:
+            isEnabled = EFalse;
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - plugin disabled"));	
+            break;
+        case EWriterPluginSettings:
+        	//result = StringLoader::LoadL(PROFILER_KERNEL_MODE_SAMPLER);
+        	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - setting plugin settings"));	
+        	break;
+        default:
+        	break;
+        }
+	LOGTEXT(_L("CDebOutWriterPlugin::SetValueL - exit"));	
+
+}
+
+TUint32 CDebOutWriterPlugin::GetWriterType()
+	{
+	return iWriterType;
+	}
+
+
+void CDebOutWriterPlugin::GetValueL( const TWriterPluginValueKeys aKey, TDes& aValue )
+    {
+    switch( aKey )
+        {
+        case EWriterPluginVersion:
+
+        	GetWriterVersion(&aValue);
+        	break;
+        case EWriterPluginType:
+        	break;
+           default:
+                break;
+        }
+    }
+
+void CDebOutWriterPlugin::GetWriterVersion(TDes* aDes)
+	{
+	_LIT(KDebugOutputWriterVersion, "1.0.0");
+	aDes->Append(KDebugOutputWriterVersion);
+	}
+
+void CDebOutWriterPlugin::DoCancel()
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::DoCancel - entry"));
+}
+
+void CDebOutWriterPlugin::WriteData()
+    {
+    // Activate handler to write data from buffer to output
+    LOGTEXT(_L("CDiskWriterPlugin::WriteData() - entry"));
+    TRAP_IGNORE(iWriterHandler->StartL());
+    LOGTEXT(_L("CDiskWriterPlugin::WriteData() - exit"));
+    }
+
+void CDebOutWriterPlugin::HandleError(TInt aError)
+    {
+    TInt err(KErrNone);
+    err = iErrorStatus.Set(aError);
+    if(err != KErrNone)
+        {
+        RDebug::Print(_L("CDiskWriterPlugin::HandleError() - error: %d"), err);
+        }
+    }
+
+void CDebOutWriterPlugin::PrintDescriptorAsBase64(	TDesC8& aDes,
+                                                    TRequestStatus* aStatus,
+													TUint32 sampleTime,
+													TBool aEmptying)
+{
+	LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - entry"));
+	TUint len = aDes.Length();
+
+	// we must wait for the sample tick to be printed, in case
+	// prints are performed at user side, otherwise the kernel
+	// prints will corrupt the data
+	if(sampleTime != 0xffffffff)
+	{
+		TUint32 remains = sampleTime%1000;
+	
+		if(remains > 800) 
+		{
+			TTimeIntervalMicroSeconds32 timeToWait = ((1050-remains)*1000);
+			User::After(timeToWait);
+		}
+	}
+	
+	TBuf16<75> buf;
+
+	// Header
+#ifdef OST_TRACE_COMPILER_IN_USE
+    OstTrace0( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64START, 
+            "<PIPROF>=================================================================" );
+#else
+	RDebug::Print(_L("<PIPROF>================================================================="));
+#endif
+	buf.Zero();
+
+	// base64 encoding table
+	const char uu_base64[64] =
+	{
+		'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H',
+		'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
+		'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
+		'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
+		'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
+		'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
+		'w', 'x', 'y', 'z', '0', '1', '2', '3',
+		'4', '5', '6', '7', '8', '9', '+', '/'
+	};
+
+	TChar byte1, byte2, byte3, byte4;
+	TUint8 count = 0x30;
+	// base64 encoding 
+	for(TUint i = 0, j = 0; i < len; i += 3, j = (j + 1) % 18) 
+	{
+    // byte 1
+		byte1 = uu_base64[(aDes[i] >> 2) & 0x3F];
+		
+		// byte 2
+		if(i+1 < len)
+			byte2 = uu_base64[(aDes[i] << 4) & 0x3f | (aDes[i+1] >> 4)];
+		else
+			byte2 = uu_base64[(aDes[i] << 4) & 0x3f];
+
+		// byte 3
+		if(i+1 < len && i+2 < len)
+			byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f | (aDes[i+2] >> 6)];
+		else if(i+1 < len)
+			byte3 = uu_base64[(aDes[i+1] << 2) & 0x3f];
+		else
+			byte3 = '=';
+
+		// byte 4
+		if(i+2 < len) 
+			byte4 = uu_base64[aDes[i+2] & 0x3f];
+		else
+			byte4 = '=';
+	
+		// append to buffer
+		buf.Append(byte1);
+		buf.Append(byte2);
+		buf.Append(byte3);
+		buf.Append(byte4);
+
+		// output 72 chars / line
+		if(j == 17) 
+		{		
+			// add check number at the end of line
+			buf.Append(count);
+#ifdef OST_TRACE_COMPILER_IN_USE
+			OstTraceExt1( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64LINE, "<PIPROF>%S", &buf );
+#else
+			RDebug::Print(_L("<PIPROF>%S"),&buf);
+#endif
+			count++;
+			if(count > 0x39)
+				count = 0x30;
+			buf.Zero();
+		}
+	}
+	
+#ifdef OST_TRACE_COMPILER_IN_USE
+	OstTraceExt1( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64FIN, "<PIPROF>%S", &buf );
+#else
+	RDebug::Print(_L("<PIPROF>%S"),&buf);
+#endif
+	buf.Zero();
+
+	// footer
+#ifdef OST_TRACE_COMPILER_IN_USE
+	OstTrace0( PIPROFILER_TRACE_OUT, CDEBOUTWRITERPLUGIN_PRINTDESCRIPTORASBASE64END, 
+	        "<PIPROF>=================================================================" );
+#else
+	RDebug::Print(_L("<PIPROF>================================================================="));
+#endif
+
+	if(!aEmptying)
+	    {
+        if(aStatus != 0) 
+            User::RequestComplete(aStatus,0);
+	    }
+	
+	LOGTEXT(_L("CDebOutWriterPlugin::PrintDescriptorAsBase64() - exit"));
+}
+
+
+
+/*
+ * 
+ * Implementation of class CDebOutWriterHandler
+ * 
+ */
+CDebOutWriterHandler::CDebOutWriterHandler(CDebOutWriterPlugin* aWriter) :
+    CActive(EPriorityStandard)
+    {
+    LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - entry"));
+    iWriter = aWriter;
+    
+    // set initial mode to non-stopping
+    iStopping = EFalse;
+    
+    // add the handler to the active scheduler
+    CActiveScheduler::Add(this);
+    LOGTEXT(_L("CDebOutWriterHandler::CDebOutWriterHandler - exit"));
+    }
+
+CDebOutWriterHandler* CDebOutWriterHandler::NewL(CDebOutWriterPlugin* aWriter)
+{
+	LOGTEXT(_L("CDebOutWriterHandler::NewL() - entry"));
+	CDebOutWriterHandler* self = new (ELeave) CDebOutWriterHandler(aWriter);
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    CleanupStack::Pop();
+	LOGTEXT(_L("CDebOutWriterHandler::NewL() - exit"));
+    return self;
+}
+
+CDebOutWriterHandler::~CDebOutWriterHandler()
+    {
+	LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - entry"));
+    
+    LOGTEXT(_L("CDebOutWriterHandler::~CDebOutWriterHandler - exit"));
+    }    
+    
+void CDebOutWriterHandler::ConstructL()
+	{
+
+	}
+
+void CDebOutWriterHandler::StartL()
+	{
+	LOGTEXT(_L("CDebOutWriterHandler::StartL - entry"));
+    if(!IsActive())
+        {
+        LOGTEXT(_L("CDiskWriterHandler::StartL - is not active"));
+    
+        TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+        LOGSTRING2("CDiskWriterHandler::StartL - got next filled 0x%x",nextBuf);
+    
+        if(nextBuf != 0)
+            {
+            LOGTEXT(_L("CDiskWriterHandler::StartL - writing to file"));
+            WriteBufferToOutput(nextBuf);
+            }
+        }
+	LOGTEXT(_L("CDebOutWriterHandler::StartL - entry"));
+	}
+
+void CDebOutWriterHandler::Stop()
+	{
+	LOGTEXT(_L("CDebOutWriterHandler::Stop - entry"));
+   
+	// do write once more to write the logged data to output
+    // set to stopping mode, needed for emptying the remaining full buffers
+    iStopping = ETrue;
+
+    // stop the timer
+    Reset();
+
+    // set mode back to non-stopping
+    iStopping = EFalse;
+	LOGTEXT(_L("CDebOutWriterHandler::Stop - exit"));
+	}
+
+void CDebOutWriterHandler::Reset()
+    {
+  
+    // start writing new buffer if there is one available
+    TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+    
+    // empty the rest of the buffers synchronously
+    while(nextBuf != 0)
+        {
+        if(nextBuf->iDataSize != 0)
+            {
+            LOGTEXT(_L("CDiskWriterHandler::Reset - writing to file"));
+            iWriter->PrintDescriptorAsBase64(*(nextBuf->iBufDes),&iStatus,0xffffffff, iStopping);
+            }
+        
+        // empty buffers when profiling stopped
+        iWriter->iStream->AddToFreeBuffers(nextBuf);
+
+        LOGTEXT(_L("CDiskWriterHandler::Reset - get next full buffer"));
+        // start writing new buffer if there is one available
+        nextBuf = iWriter->iStream->GetNextFilledBuffer();
+        LOGSTRING2("CDiskWriterHandler::Reset - got next filled 0x%x",nextBuf);
+        }
+    }
+
+void CDebOutWriterHandler::HandleFullBuffers()
+    {
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - entry"));
+    // previous write operation has finished
+    // release the previous buffer 
+    iWriter->iStream->AddToFreeBuffers(iBufferBeingWritten);
+
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - get next full buffer"));
+    // start writing new buffer if there is one available
+    TBapBuf* nextBuf = iWriter->iStream->GetNextFilledBuffer();
+
+    if(nextBuf != 0)
+        {
+        LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - writing to file"));
+        if(nextBuf->iDataSize != 0)
+            {
+            WriteBufferToOutput(nextBuf);
+            }
+        } 
+    LOGTEXT(_L("CDiskWriterHandler::HandleFullBuffers - exit"));
+    }
+
+void CDebOutWriterHandler::RunL()
+    {
+    // call function to complete full buffer handling
+    HandleFullBuffers();
+    }
+
+void CDebOutWriterHandler::DoCancel()
+    {
+    
+    }
+
+void CDebOutWriterHandler::WriteBufferToOutput(TBapBuf* aBuf)
+    {
+    LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - entry"));
+    iBufferBeingWritten = aBuf;
+
+    // set the data length just to be sure
+    iBufferBeingWritten->iBufDes->SetLength(aBuf->iDataSize);
+
+    LOGTEXT(_L("CDiskWriterPlugin::WriteBufferToOutput - writing to file"));
+//    PrintBufferToOutput(iBufferBeingWritten, iStatus);
+    iWriter->PrintDescriptorAsBase64(*(iBufferBeingWritten->iBufDes),&iStatus,0xffffffff, iStopping);
+    // set AO back to active, until filled buffers are emptied 
+    SetActive();
+    
+    LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput - exit"));
+    }
+
+// private
+void CDebOutWriterHandler::PrintBufferToOutput(TBapBuf* aBuffer, TRequestStatus& aStatus)
+    {
+    LOGTEXT(_L("CDebOutWriterHandler::WriteBufferToOutput() - debug out writer tick activated"));
+
+    TPtrC8& aDes = (TPtrC8&)*(aBuffer->iBufDes);
+#ifdef BAPPEA_SAMPLE_MARKS
+    TUint32 time = iSampler->GetSampleTime();
+#else
+    TUint32 time = 0xffffffff;
+#endif
+    iWriter->PrintDescriptorAsBase64(aDes,&aStatus,time, iStopping);
+    }
+