piprofiler/plugins/GeneralsPlugin/src/GeneralsPlugin.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 25 May 2010 14:22:58 +0300
branchRCL_3
changeset 19 da2cedce4920
child 49 7fdc9a71d314
permissions -rw-r--r--
Revision: 201019 Kit: 2010121

/*
* 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 "GeneralsPlugin.h"	
//#include <piprofiler/EngineUIDs.h>
#include <piprofiler/ProfilerTraces.h>

const TInt KMaxSamplerAmount = 20;

// LITERALS
_LIT8(KSamplingPeriod, "sampling_period_ms");

// CONSTANTS
// GeneralsPlugin UID:
const TUid KSamplerGeneralsPluginUid = { 0x2001E5B2 };

// Gpp sub-sampler UID:
const TUid KSamplerGppPluginUid = { 0x2001E570 };

// Gfc sub-sampler UID:
const TUid KSamplerGfcPluginUid = { 0x2001E571 };

// Itt sub-sampler UID:
const TUid KSamplerIttPluginUid = { 0x2001E572 };

// Mem sub-sampler UID:
const TUid KSamplerMemPluginUid = { 0x2001E573 };

// Pri sub-sampler UID:
const TUid KSamplerPriPluginUid = { 0x2001E574 };

/*
 *	
 *	class CGeneralsPlugin implementation
 * 
 */
 
CGeneralsPlugin* CGeneralsPlugin::NewL(const TUid aImplementationUid, TAny* /*aInitParams*/)
    {
	LOGTEXT(_L("CGeneralsPlugin::NewL() - entry"));
    CGeneralsPlugin* self = new (ELeave) CGeneralsPlugin();
    CleanupStack::PushL( self );
    self->ConstructL();
    CleanupStack::Pop();
	LOGTEXT(_L("CGeneralsPlugin::NewL() - exit"));
    return self;
    }

CGeneralsPlugin::CGeneralsPlugin() :
	iVersionDescriptor(&(this->iVersion[1]),0,19)
	{
	iSamplerType = PROFILER_KERNEL_MODE_SAMPLER;
	iSamplerId = PROFILER_GENERALS_SAMPLER_ID;
	iBufferHandler = NULL;
    iEnabled = EFalse;
	LOGTEXT(_L("CGeneralsPlugin::CGeneralsPlugin() - constructor"));
	}

void CGeneralsPlugin::ConstructL() 
    {
	LOGTEXT(_L("CGeneralsPlugin::ConstructL() - entry"));
	
	// create attribute array
	iSamplerAttributes = new(ELeave) CArrayFixFlat<TSamplerAttributes>(KSubSamplerCount);
	
	TInt err = InitiateSamplerL();
	if( err != KErrNone )
		{
			LOGTEXT(_L("CGeneralsPlugin::ConstructL - LEAVING, failed to load open sampler device"));
			User::Leave(err);
		}
	
	// initiate sampler attributes, i.e. settings for modification
	InitiateSamplerAttributesL();
	
	LOGTEXT(_L("CGeneralsPlugin::ConstructL() - exit"));
    }


CGeneralsPlugin::~CGeneralsPlugin()
	{
	// clean all the members
	CleanSampler();	// clean the created sampler
	}

TInt CGeneralsPlugin::InitiateSamplerL()
	{
	RThread me;
	
	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #1"));

	me.SetPriority(EPriorityRealTime);

	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #2"));
	
	// create 
	User::FreeLogicalDevice(KPluginSamplerName);
	TInt err(KErrGeneral);
	
	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #3"));

    err = User::LoadLogicalDevice(KPluginSamplerName);
    if(err != KErrNone)
        {
        User::Leave(err);
        }

	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #4"));
	
	err = KErrGeneral;

    err = iGeneralsSampler.Open();
    if(err != KErrNone)
        {
        LOGSTRING2("CGeneralsPlugin::InitiateSamplerL - Could not open sampler device - waiting and trying again: %d", err);
        User::Leave(err);
        }

	LOGTEXT(_L("CGeneralsPlugin::InitiateSamplerL - #5"));

	return err;
	}

/* 
 * 
 * Default sampler attributes
 * 
 */
void CGeneralsPlugin::InitiateSamplerAttributesL()
    {

    // 
    for(TInt i(0);i<KMaxSamplerAmount;i++)
        {
        switch(i)
            {
// Usage:
//            TSamplerAttributes(TUint32 aUid,
//                    const TDesC8& aShortName,
//                    const TDesC& aName,
//                    const TDesC& aDescription,
//                    TInt aSampleRate,
//                    TBool aEnabled,
//                    TBool aHidden,
//                    TUint32 aItemCount);
            case PROFILER_GPP_SAMPLER_ID:
                {
                TSamplerAttributes attr(KSamplerGppPluginUid.iUid,
                        KGPPShortName(),
                        KGPPLongName(),
                        KGPPDescription(),
                        1,
                        ETrue,
                        ETrue,
                        0);
                iSamplerAttributes->AppendL(attr);
                break;
                }
            case PROFILER_GFC_SAMPLER_ID:
                {
                TSamplerAttributes attr2(KSamplerGfcPluginUid.iUid,
                        KGFCShortName(),
                        KGFCLongName(),
                        KGFCDescription(),
                        -1,
                        EFalse,
                        EFalse,
                        0);
                this->iSamplerAttributes->AppendL(attr2);
                break;
                }
            case PROFILER_ITT_SAMPLER_ID:
                {
                TSamplerAttributes attr3(KSamplerIttPluginUid.iUid,
                        KITTShortName(),
                        KITTLongName(),
                        KITTDescription(),
                        -1,
                        ETrue,
                        EFalse,
                        0);
                this->iSamplerAttributes->AppendL(attr3);
                break;
                }
            case PROFILER_MEM_SAMPLER_ID:
                {
                TSamplerAttributes attr4(KSamplerMemPluginUid.iUid,
                        KMEMShortName(),
                        KMEMLongName(),
                        KMEMDescription(),
                        -1,
                        EFalse,
                        EFalse,
                        0);
//                // select event or sampling based
//                attr4.iSettingItem1.iSettingDescription.Copy(KMEM1Desc);
//                attr4.iSettingItem1.iType = TSettingItem::ESettingItemTypeBool;
//                attr4.iSettingItem1.iValue.AppendNum(0, EDecimal);
//                attr4.iSettingItem1.iUIText.Copy(KMEM1UIText);
//                attr4.iSettingItem1.iSettingText.Copy(KMemCounter1);
                
                this->iSamplerAttributes->AppendL(attr4);
                break;
                }
            case PROFILER_PRI_SAMPLER_ID:
                {
                TSamplerAttributes attr5(KSamplerPriPluginUid.iUid,
                        KPRIShortName(),
                        KPRILongName(),
                        KPRIDescription(),
                        3000,
                        EFalse,
                        EFalse,
                        0);
                this->iSamplerAttributes->AppendL(attr5);
                break;
                }
            }
        }
    }

TInt CGeneralsPlugin::CleanSampler()
	{
    LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - deleting buffer handler"));
    // release the buffer handler
    if(iBufferHandler)
        {
        iBufferHandler->Cancel();
        delete iBufferHandler;
        iBufferHandler = NULL;
        }
    
    LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - closing sampler"));
	iGeneralsSampler.Close();
	
	LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - Freeing sampler device"));
	User::FreeLogicalDevice(KPluginSamplerName);
	
	// release attribute array
	if(iSamplerAttributes)
	    {
	    iSamplerAttributes->Reset();
	    }
    delete iSamplerAttributes;
    iSamplerAttributes = NULL;

	LOGTEXT(_L("CGeneralsPlugin::CleanSampler() - exit"));

	return KErrNone;
	}

// returns setting array
void CGeneralsPlugin::GetAttributesL(CArrayFixFlat<TSamplerAttributes>* aAttributes)
    {
    TInt count(iSamplerAttributes->Count());
    // append all sampler attributes to aAttributes array
    for(TInt i(0);i<count;i++)
        {
        aAttributes->AppendL(iSamplerAttributes->At(i));
        }
    }

TInt CGeneralsPlugin::SetAttributesL(TSamplerAttributes aAttributes)
    {
    TSamplerAttributes attr;

    TInt count(iSamplerAttributes->Count());
    // loop the sub sampler attributes (by UID)
    for(TInt i(0);i<count;i++)
        {
        attr = iSamplerAttributes->At(i);
        // if UIDs match replace the old 
        if(attr.iUid == aAttributes.iUid)
            {
            // replace the old attribute container
            iSamplerAttributes->Delete(i);
            iSamplerAttributes->InsertL(i, aAttributes);
            return KErrNone;
            }
        }
    return KErrNotFound;
    }

/* 
 * Method for parsing and transforming text array settings into TSamplerAttributes (per each sub sampler),
 * called by CSamplerController class
 * 
 * @param array of raw text setting lines, e.g. [gpp]\nenabled=true\nsampling_period_ms=1\n
 */
TInt CGeneralsPlugin::ConvertRawSettingsToAttributes(CDesC8ArrayFlat* aAllSettingsArray)
    {
    // local literals
    _LIT8(KGPPShort, "gpp");
    _LIT8(KGFCShort, "gfc");
    _LIT8(KITTShort, "itt");
    _LIT8(KMEMShort, "mem");
    _LIT8(KPRIShort, "pri");

    TInt err(KErrNone);
    
    TBuf8<16> samplerSearchName;
    
    // loop previous settings, update value if changed
    for(TInt i(0);i<KSubSamplerCount;i++)
        {
        // go through all the sub samplers
        switch (i)
            {
            case 0:
                samplerSearchName.Copy(KGPPShort);
                break;
            case 1:
                samplerSearchName.Copy(KGFCShort);
                break;
            case 2:
                samplerSearchName.Copy(KITTShort);
                break;
            case 3:
                samplerSearchName.Copy(KMEMShort);
                break;
            case 4:
                samplerSearchName.Copy(KPRIShort);
                break;
            }

        // get sampler specific settings  
        err = DoSetSamplerSettings(aAllSettingsArray, samplerSearchName, i);
        }
    
    // returns KErrNone if settings found, otherwise KErrNotFound
    return err;
    }

/**
 * Method for searching sampler specific settings among all settings (raw setting lines read from settings file)
 * 
 * @param aAllSettings array of all settings from settings file
 * @param aSamplerName short name of sampler to be searched among the settings
 * @param aIndex index number of sampler specific sampler attributes (TSamplerAttributes)
 * @return KErrNone if settings found ok else KErrNotFound
 */
TInt CGeneralsPlugin::DoSetSamplerSettings(CDesC8ArrayFlat* aAllSettings, TDesC8& aSamplerName, TInt aIndex)
    {
    // sampler name to be searched among the all settings
    TBuf8<16> samplerSearch;
    samplerSearch.Copy(KBracketOpen);
    samplerSearch.Append(aSamplerName);
    samplerSearch.Append(KBracketClose);
    
    // read a line from ALL settings array
    for (TInt i(0); i<aAllSettings->MdcaCount(); i++)
        {
        // check if this line has a setting block start, i.e. contains [xxx] in it
        if (aAllSettings->MdcaPoint(i).CompareF(samplerSearch) == 0)
            {
            // right settings block found, now loop until the next block is found
            for(TInt j(i+1);j<aAllSettings->MdcaCount();j++)
                {
                // check if the next settings block was found
                if(aAllSettings->MdcaPoint(j).Left(1).CompareF(KBracketOpen) != 0)
                    {
                    // save found setting value directly to its owners attributes
                    SaveSettingToAttributes(aAllSettings->MdcaPoint(j), aIndex);
                    }
                else
                    {
                    // next block found, return KErrNone
                    return KErrNone;
                    }
                }
            }
        }
    // no settings found for specific sampler
    return KErrNotFound;
    }

/**
 * Method for setting a specific descriptor (from settings file) to attribute structure
 * 
 * @param aSetting  
 * @param aName  
 */
void CGeneralsPlugin::SaveSettingToAttributes(const TDesC8& aSetting, TInt aIndex)
    {
    // local literals
    _LIT8(KSettingItemSeparator, "=");
    
    // find the equal mark from the setting line
    TInt sepPos = aSetting.Find(KSettingItemSeparator);
    // check that '=' is found
    if (sepPos > 0)
        {
        // check that the element matches
        if (aSetting.Left(sepPos).CompareF(KEnabled) == 0)
            {
            TBool en;
            CSamplerPluginInterface::Str2Bool(aSetting.Right(aSetting.Length()-sepPos-1), en);
            if(en != iSamplerAttributes->At(aIndex).iEnabled)
                {
                iSamplerAttributes->At(aIndex).iEnabled = en;
                }
            }
        else if (aSetting.Left(sepPos).CompareF(KSamplingPeriod) == 0)
            {
            TInt sr;
            CSamplerPluginInterface::Str2Int(aSetting.Right(aSetting.Length()-sepPos-1), sr);
            if(sr != iSamplerAttributes->At(aIndex).iSampleRate)
                {
                iSamplerAttributes->At(aIndex).iSampleRate = sr;
                }
            }
        }
    }


TUid CGeneralsPlugin::Id(TInt aSubId) const
	{
		if(aSubId == PROFILER_GPP_SAMPLER_ID)		
			return KSamplerGppPluginUid;
		else if (aSubId == PROFILER_GFC_SAMPLER_ID)		
			return KSamplerGfcPluginUid;
		else if (aSubId == PROFILER_ITT_SAMPLER_ID)		
			return KSamplerIttPluginUid;
		else if (aSubId == PROFILER_MEM_SAMPLER_ID)		
			return KSamplerMemPluginUid;
		else if (aSubId == PROFILER_PRI_SAMPLER_ID)		
			return KSamplerPriPluginUid;
		else
			return KSamplerGeneralsPluginUid;
	}

TInt CGeneralsPlugin::SubId(TUid aId) const
	{
/* definitions from ProfilerConfig.h:
 * 	#define		PROFILER_GPP_SAMPLER_ID			1
	#define		PROFILER_GFC_SAMPLER_ID			2
	#define		PROFILER_ITT_SAMPLER_ID			3
	#define		PROFILER_MEM_SAMPLER_ID			4
	#define		PROFILER_PRI_SAMPLER_ID			5
 */
	
		if(aId == KSamplerGppPluginUid)		
			return PROFILER_GPP_SAMPLER_ID;
		else if (aId == KSamplerGfcPluginUid)		
			return PROFILER_GFC_SAMPLER_ID;
		else if (aId == KSamplerIttPluginUid)		
			return PROFILER_ITT_SAMPLER_ID;
		else if (aId == KSamplerMemPluginUid)		
			return PROFILER_MEM_SAMPLER_ID;
		else if (aId == KSamplerPriPluginUid)		
			return PROFILER_PRI_SAMPLER_ID;
		else
			return KErrNotFound;
	}

TInt CGeneralsPlugin::GetSamplerType()
	{
	return iSamplerType;
	}


void CGeneralsPlugin::InstallStreamForActiveTraces(RGeneralsSampler& sampler, CProfilerSampleStream& aStream)
	{
	// output mode for this trace is stream
	if(!iBufferHandler)
		{
		// stream object has not been created yet
		LOGTEXT(_L("CGeneralsPlugin::InstallStreamForActiveTraces - creating stream for trace"));	
		
		// use a 32KB buffer to transfer data from sampler to client
		// commonStream = new RProfilerSampleStream(sampler,totalPrefix,32768);
		TRAPD(err, iBufferHandler = CProfilerBufferHandler::NewL(aStream, sampler));
		if(err != KErrNone)
		    {
		    LOGTEXT(_L("CGeneralsPlugin::InstallStreamForActiveTraces() - No memory"));
		    return;
		    }
		}

	// initiate receiving of data from the sampler device driver
	if(iBufferHandler)
		{
		iBufferHandler->StartReceivingData();
		}
}

void CGeneralsPlugin::SetSettingsToSamplers()
    {
    TSamplerAttributes attr;
    
    // loop through the setting attributes
    for(TInt i(0);i<iSamplerAttributes->Count();i++)
        {
        // get the attribute container
        attr = iSamplerAttributes->At(i);
        
        // make changes according to right sampler, NOTE! The old IDs of sub samplers (i+1)!
        if(attr.iEnabled)
            {
            iGeneralsSampler.MarkTraceActive(i+1);
            
            // set enabled
            iEnabled = ETrue;
            }
        else
            {
            iGeneralsSampler.MarkTraceInactive(i+1);
            }
        // set sampling period if available
        if(attr.iSampleRate != KErrNotFound)
            {
            iGeneralsSampler.SetSamplingPeriod(i+1, attr.iSampleRate);
            }
        }
    }

TInt CGeneralsPlugin::ResetAndActivateL(CProfilerSampleStream& aStream) 
    {
	// the sampler starting functionality
	LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - entry"));

    // now before starting the latest settings must be set to samplers itself
	SetSettingsToSamplers();

	if(Enabled())
	    {
        LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - starting sampling..."));
        // start sampling process of enabled sub samplers
        iGeneralsSampler.StartSampling();		
        LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - installing stream for an active trace..."));
    
        // install the trace for enabled samplers
        InstallStreamForActiveTraces(iGeneralsSampler, aStream);
        LOGSTRING2("CGeneralsPlugin::ResetAndActivate() - stream installed: 0x%x", aStream);
	    }
	
	LOGTEXT(_L("CGeneralsPlugin::ResetAndActivate() - exit"));
	return KErrNone;
    }
	
TInt CGeneralsPlugin::StopSampling() 
    {
    // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Stopping sampler LDD"));
	iGeneralsSampler.StopSampling();
	// RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Sampler LDD stopped"));
	
	// check if bufferhandler has died
	if(iBufferHandler)
		{
		// RDebug::Print(_L("CGeneralsPlugin::StopSampling() - Canceling the buffer handler"));
		iBufferHandler->Cancel();
		delete iBufferHandler;
		iBufferHandler = NULL;
		}	
	// set enabled
    iEnabled = EFalse;
    // RDebug::Print(_L("CGeneralsPlugin::StopSampling() - exit"));
	return KErrNone;
    }