diff -r 000000000000 -r a41df078684a userlibandfileserver/fileserver/ftrace/d_ftrace.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/userlibandfileserver/fileserver/ftrace/d_ftrace.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,312 @@ +/* +* 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 the License "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: +* +*/ +// D_FTRACE.CPP +// +// +// +#include "plat_priv.h" +#include + +#include "f32trace.h" + +#define __DLOGICAL_CHANNEL_BASE__ + +#ifdef __DLOGICAL_CHANNEL_BASE__ +DMutex* TheTraceMutex = NULL; +_LIT(KLitTraceMutexName, "FTRACE_MUTEX"); +#else +TDynamicDfcQue* gDfcQ; +const TInt KDFTraceThreadPriority = 27; +_LIT(KDFTraceThread,"DFTraceThread"); +#endif + +const TInt KMajorVersionNumber=1; +const TInt KMinorVersionNumber=0; +const TInt KBuildVersionNumber=0; + + +class DLddFactoryFTrace : public DLogicalDevice + { +public: + DLddFactoryFTrace(); + virtual ~DLddFactoryFTrace(); + virtual TInt Install(); + virtual void GetCaps(TDes8 &aDes) const; + virtual TInt Create(DLogicalChannelBase*& aChannel); //overriding pure virtual + }; + +#ifdef __DLOGICAL_CHANNEL_BASE__ +class DLddFTrace : public DLogicalChannelBase +#else +class DLddFTrace : public DLogicalChannel +#endif + { +public: + DLddFTrace(); + ~DLddFTrace(); +protected: + virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer); + +#ifdef __DLOGICAL_CHANNEL_BASE__ + virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2); +#else + virtual void HandleMsg(class TMessageBase *); +#endif + +private: + void DoCancel(TInt aReqNo); + TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1, TAny* a2); + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2); + +private: + DThread* iClient; + }; + +DECLARE_STANDARD_LDD() + { +#ifdef __DLOGICAL_CHANNEL_BASE__ + TInt r = Kern::MutexCreate(TheTraceMutex, KLitTraceMutexName, KMutexOrdNone); + if (r != KErrNone) + return NULL; +#endif + + return new DLddFactoryFTrace; + } + +DLddFactoryFTrace::DLddFactoryFTrace() + { + + iParseMask=KDeviceAllowUnit; // Pass stack number as unit + iUnitsMask=0xffffffff; + iVersion=TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber); + } + +TInt DLddFactoryFTrace::Create(DLogicalChannelBase*& aChannel) + { + aChannel=new DLddFTrace; + return aChannel ? KErrNone : KErrNoMemory; + } + +TInt DLddFactoryFTrace::Install() + { +#ifndef __DLOGICAL_CHANNEL_BASE__ + // Allocate a kernel thread to run the DFC + TInt r = Kern::DynamicDfcQCreate(gDfcQ, KDFTraceThreadPriority, KDFTraceThread); + if (r != KErrNone) + return r; +#endif + + TPtrC name=_L("FTrace"); + return(SetName(&name)); + } + +void DLddFactoryFTrace::GetCaps(TDes8& /*aDes*/) const + { + } + +DLddFactoryFTrace::~DLddFactoryFTrace() + { +#ifndef __DLOGICAL_CHANNEL_BASE__ + if (gDfcQ) + gDfcQ->Destroy(); +#endif + } + +DLddFTrace::DLddFTrace() + { + iClient=&Kern::CurrentThread(); + ((DObject*)iClient)->Open(); // can't fail since thread is running + } + +DLddFTrace::~DLddFTrace() + { + Kern::SafeClose((DObject*&)iClient,NULL); + } + +TInt DLddFTrace::DoCreate(TInt /*aUnit*/, const TDesC8* /*aInfo*/, const TVersion& aVer) + { + + if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber,KMinorVersionNumber,KBuildVersionNumber),aVer)) + return(KErrNotSupported); + +#ifndef __DLOGICAL_CHANNEL_BASE__ + SetDfcQ(gDfcQ); + iMsgQ.Receive(); +#endif + + return(KErrNone); + } + +void DLddFTrace::DoCancel(TInt /*aReqNo*/) + { + } + +#ifdef __DLOGICAL_CHANNEL_BASE__ +TInt DLddFTrace::Request(TInt aReqNo, TAny* a1, TAny* a2) + { + NKern::ThreadEnterCS(); + Kern::MutexWait(*TheTraceMutex); + TInt r = DoControl(aReqNo, a1, a2); + Kern::MutexSignal(*TheTraceMutex); + NKern::ThreadLeaveCS(); + + return r; + } + +#else + +void DLddFTrace::HandleMsg(TMessageBase* aMsg) + { + TThreadMessage& m=*(TThreadMessage*)aMsg; + TInt id=m.iValue; + + if (id==(TInt)ECloseMsg) + { + m.Complete(KErrNone, EFalse); + return; + } + else if (id==KMaxTInt) + { + // DoCancel + m.Complete(KErrNone,ETrue); + return; + } + + if (id<0) + { + // DoRequest + TRequestStatus* pS=(TRequestStatus*)m.Ptr0(); + + // WDP FIXME change this to use the Kern::RequestComplete() API which doesn't take a thread pointer + // when this becomes available + Kern::RequestComplete(iClient, pS, KErrNotSupported); + m.Complete(KErrNotSupported, ETrue); + } + else + { + // DoControl + TInt r=DoControl(id, m.Ptr0(), m.Ptr1()); + m.Complete(r,ETrue); + } + } +#endif // __DLOGICAL_CHANNEL_BASE__ + +const TUint KTraceBufferSize = 4096; +TUint8 gTraceBuffer[KTraceBufferSize]; + + + +#define MIN(a,b) ((a) < (b) ? (a) : (b)) + +TInt DLddFTrace::DoControl(TInt aFunction, TAny* a1, TAny* a2) +// +// Mostly requests (but some kernel server async ones) +// + { + TInt r=KErrNotSupported; + switch (aFunction) + { + case RFTrace::ETraceMultiple: + { + typedef struct { + TClassification iCategory; + TUint8 iPadding1[sizeof(TUint) - sizeof(TClassification)]; + + TFormatId iFormatId; + TUint8 iPadding2[sizeof(TUint) - sizeof(TFormatId)]; + + TUint32 iUid; + TInt iDescriptorCount; + } TraceArgs; + + TraceArgs args={0}; + +#ifdef __DLOGICAL_CHANNEL_BASE__ + XTRAP(r, XT_DEFAULT, kumemget32(&args, a1, sizeof(args))); + if (r != KErrNone) + return r; +#else + r = Kern::ThreadRawRead(iClient, a1, &args, sizeof(args)); + if (r != KErrNone) + return r; +#endif + + + // current descriptor - MUST be either a TPtr8 or a TBuf8<4> + TUint32 desc[2] = {0, 0}; + TUint32& desLength = desc[0]; + + TUint offset = 0; + + *((TUint*) (gTraceBuffer+offset)) = args.iFormatId; + offset+= sizeof(TUint); + + TDesC8* des = (TDesC8*) ((TUint8*) a2); + const TInt desSize = sizeof(TPtrC8); + for (TInt n=0; n< args.iDescriptorCount; n++, des = (TDesC8*) (((TUint8*) des) + desSize) ) + { + +#ifdef __DLOGICAL_CHANNEL_BASE__ + XTRAP(r, XT_DEFAULT, kumemget32(desc, des, sizeof(desc))); +#else + r = Kern::ThreadRawRead(iClient, des, desc, sizeof(desc)); + if (r != KErrNone) + return r; +#endif + TUint32 desType = desLength >> KShiftDesType; + desLength &= (TUint) (KMaskDesLength); + if (desType == EPtrC) + { + *((TUint*) (gTraceBuffer+offset)) = desLength; + desLength = (desLength+3)&~3; + offset+= sizeof(TUint); + } + else if (desType == EBufC) + { + *((TUint*) (gTraceBuffer+offset)) = desc[1]; + offset+= sizeof(TUint); + if (desLength > 4) + return KErrArgument; + desLength = 0; + continue; + } + else + return KErrArgument; + + TUint len = MIN(KTraceBufferSize - offset, desLength); +#ifdef __DLOGICAL_CHANNEL_BASE__ + XTRAP(r, XT_DEFAULT, kumemget(gTraceBuffer+offset, (const TUint8*) desc[1], len)); +#else + TPtr8 dest(gTraceBuffer+offset, len, len); + r = Kern::ThreadDesRead(iClient, des, dest, 0, KChunkShiftBy0); + if (r != KErrNone) + return r; +#endif + offset+= len; + + } + + BTrace::OutFilteredBig + (BTRACE_HEADER_C(8,args.iCategory, 0), args.iUid, gTraceBuffer, offset); + + r=KErrNone; + break; + } + } + return(r); + } +