# HG changeset patch # User hgs # Date 1281108878 -3600 # Node ID c7a0ce20c48c7c95df4460c37f6125e12fd90441 # Parent 75252ea6123bc17ad80858a54828db1b2d467129 201031_07 diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/drivers/dma/dma2_pil.cpp --- a/kernel/eka/drivers/dma/dma2_pil.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kernel/eka/drivers/dma/dma2_pil.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -1932,9 +1932,7 @@ { iQueued = ETrue; iChannel.iReqQ.Add(&iLink); - // iChannel.iNullPtr points to iChannel.iCurHdr for an empty queue - *iChannel.iNullPtr = iFirstHdr; - iChannel.iNullPtr = &(iLastHdr->iNext); + iChannel.SetNullPtr(*this); if (iIsrCb) { // Since we've made sure that there is no other request in the @@ -1946,7 +1944,7 @@ // possible. __e32_atomic_store_rel32(&iChannel.iIsrCbRequest, ETrue); } - iChannel.DoQueue(const_cast(*this)); + iChannel.DoQueue(*this); r = KErrNone; __DMA_INVARIANT(); iChannel.Signal(); @@ -2124,21 +2122,6 @@ __KTRACE_OPT(KDMA, Kern::Printf("DDmaRequest::TotalNumSrcElementsTransferred")); // Not yet implemented. - - // So far largely bogus code (just to touch some symbols)... - iTotalNumSrcElementsTransferred = 0; - TDmac& c = *(iChannel.iController); - if (c.iCapsHwDes) - { - for (const SDmaDesHdr* pH = iFirstHdr; pH != NULL; pH = pH->iNext) - { - iTotalNumSrcElementsTransferred += c.HwDesNumDstElementsTransferred(*pH); - } - } - else - { - // Do something different for pseudo descriptors... - } return iTotalNumSrcElementsTransferred; } @@ -2433,7 +2416,8 @@ // ISR should not happen after this function returns. iController->StopTransfer(*this); - ResetStateMachine(); + DoCancelAll(); + ResetNullPtr(); // Clean-up the request queue. SDblQueLink* pL; @@ -2707,8 +2691,7 @@ { SDmaDesHdr* pCompletedSrcHdr = NULL; SDmaDesHdr* pCompletedDstHdr = NULL; - DoDfc(const_cast(*pCurReq), - pCompletedSrcHdr, pCompletedDstHdr); + DoDfc(*pCurReq, pCompletedSrcHdr, pCompletedDstHdr); // We don't support asymmetrical ISR notifications and request // completions yet, hence we can do the following assert test // here; also 'complete' is determined equally by either the @@ -2720,7 +2703,7 @@ else { SDmaDesHdr* pCompletedHdr = NULL; - DoDfc(const_cast(*pCurReq), pCompletedHdr); + DoDfc(*pCurReq, pCompletedHdr); complete = (pCompletedHdr == pCurReq->iLastHdr); } // If just completed last fragment from current request, switch to @@ -2731,7 +2714,7 @@ pCurReq->iLink.Deque(); iQueuedRequests--; if (iReqQ.IsEmpty()) - iNullPtr = &iCurHdr; + ResetNullPtr(); pCompletedReq->OnDeque(); } } @@ -2818,17 +2801,6 @@ } -// -// Reset state machine only, request queue is unchanged */ -// -void TDmaChannel::ResetStateMachine() - { - DoCancelAll(); - iCurHdr = NULL; - iNullPtr = &iCurHdr; - } - - void TDmaChannel::DoQueue(const DDmaRequest& /*aReq*/) { // Must be overridden @@ -2865,6 +2837,21 @@ } +void TDmaChannel::SetNullPtr(const DDmaRequest& aReq) + { + // iNullPtr points to iCurHdr for an empty queue + *iNullPtr = aReq.iFirstHdr; + iNullPtr = &(aReq.iLastHdr->iNext); + } + + +void TDmaChannel::ResetNullPtr() + { + iCurHdr = NULL; + iNullPtr = &iCurHdr; + } + + /** PSL may override */ void TDmaChannel::QueuedRequestCountChanged() { @@ -3038,6 +3025,35 @@ ////////////////////////////////////////////////////////////////////////////// // TDmaAsymSgChannel +TDmaAsymSgChannel::TDmaAsymSgChannel() + : iSrcCurHdr(NULL), + iSrcNullPtr(&iSrcCurHdr), + iDstCurHdr(NULL), + iDstNullPtr(&iDstCurHdr) + { + __DMA_INVARIANT(); + } + + +void TDmaAsymSgChannel::SetNullPtr(const DDmaRequest& aReq) + { + // i{Src|Dst}NullPtr points to i{Src|Dst}CurHdr for an empty queue + *iSrcNullPtr = aReq.iSrcFirstHdr; + *iDstNullPtr = aReq.iDstFirstHdr; + iSrcNullPtr = &(aReq.iSrcLastHdr->iNext); + iDstNullPtr = &(aReq.iDstLastHdr->iNext); + } + + +void TDmaAsymSgChannel::ResetNullPtr() + { + iSrcCurHdr = NULL; + iSrcNullPtr = &iSrcCurHdr; + iDstCurHdr = NULL; + iDstNullPtr = &iDstCurHdr; + } + + void TDmaAsymSgChannel::DoQueue(const DDmaRequest& aReq) { if (iState == ETransferring) @@ -3082,3 +3098,34 @@ iState = (iSrcCurHdr != NULL) ? ETransferring : EIdle; } + +#ifdef _DEBUG +void TDmaAsymSgChannel::Invariant() + { + Wait(); + + __DMA_ASSERTD(iReqCount >= 0); + + __DMA_ASSERTD(iSrcCurHdr == NULL || iController->IsValidHdr(iSrcCurHdr)); + __DMA_ASSERTD(iDstCurHdr == NULL || iController->IsValidHdr(iDstCurHdr)); + + // should always point to NULL pointer ending fragment queue + __DMA_ASSERTD(*iSrcNullPtr == NULL); + __DMA_ASSERTD(*iDstNullPtr == NULL); + + __DMA_ASSERTD((0 <= iAvailDesCount) && (iAvailDesCount <= iMaxDesCount)); + + __DMA_ASSERTD((iSrcCurHdr && iDstCurHdr && !IsQueueEmpty()) || + (!iSrcCurHdr && !iDstCurHdr && IsQueueEmpty())); + if (iSrcCurHdr == NULL) + { + __DMA_ASSERTD(iSrcNullPtr == &iSrcCurHdr); + } + if (iDstCurHdr == NULL) + { + __DMA_ASSERTD(iDstNullPtr == &iDstCurHdr); + } + + Signal(); + } +#endif diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/include/drivers/dma_hai.h --- a/kernel/eka/include/drivers/dma_hai.h Mon Jul 26 10:52:56 2010 +0100 +++ b/kernel/eka/include/drivers/dma_hai.h Fri Aug 06 16:34:38 2010 +0100 @@ -896,12 +896,17 @@ */ class TDmaAsymSgChannel : public TDmaChannel { +public: + TDmaAsymSgChannel(); + private: virtual void DoQueue(const DDmaRequest& aReq); virtual void DoCancelAll(); virtual void DoUnlink(SDmaDesHdr& aHdr); virtual void DoDfc(const DDmaRequest& aCurReq, SDmaDesHdr*& aSrcCompletedHdr, SDmaDesHdr*& aDstCompletedHdr); + virtual void SetNullPtr(const DDmaRequest& aReq); + virtual void ResetNullPtr(); protected: SDmaDesHdr* iSrcCurHdr; // source fragment being transferred or NULL @@ -909,6 +914,8 @@ SDmaDesHdr* iDstCurHdr; // destination fragment being transferred or NULL SDmaDesHdr** iDstNullPtr; // Pointer to NULL pointer following last destination fragment enum {EIdle = 0, ETransferring} iState; + + __DMA_DECLARE_VIRTUAL_INVARIANT }; diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/include/drivers/dma_v2.h --- a/kernel/eka/include/drivers/dma_v2.h Mon Jul 26 10:52:56 2010 +0100 +++ b/kernel/eka/include/drivers/dma_v2.h Fri Aug 06 16:34:38 2010 +0100 @@ -42,10 +42,12 @@ #ifdef _DEBUG #define __DMA_CANT_HAPPEN() Kern::Fault(KDmaPanicCat, __LINE__) #define __DMA_DECLARE_INVARIANT public: void Invariant(); +#define __DMA_DECLARE_VIRTUAL_INVARIANT public: virtual void Invariant(); #define __DMA_INVARIANT() Invariant() #else #define __DMA_CANT_HAPPEN() #define __DMA_DECLARE_INVARIANT +#define __DMA_DECLARE_VIRTUAL_INVARIANT #define __DMA_INVARIANT() #endif @@ -1255,17 +1257,18 @@ */ virtual void QueuedRequestCountChanged(); -#if defined(__CPU_ARM) && !defined(__EABI__) - inline virtual ~TDmaChannel() {} // kill really annoying warning -#endif + virtual void SetNullPtr(const DDmaRequest& aReq); + virtual void ResetNullPtr(); + + inline virtual ~TDmaChannel() {} + + inline void Wait(); + inline void Signal(); + inline TBool Flash(); private: static void Dfc(TAny*); void DoDfc(); - inline void Wait(); - inline void Signal(); - inline TBool Flash(); - void ResetStateMachine(); protected: TDmac* iController; // DMAC this channel belongs to (NULL when closed) @@ -1293,7 +1296,7 @@ TBool iRedoRequest; // client ISR callback wants a redo of request TBool iIsrCbRequest; // request on queue using ISR callback - __DMA_DECLARE_INVARIANT + __DMA_DECLARE_VIRTUAL_INVARIANT }; diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/include/e32ver.h --- a/kernel/eka/include/e32ver.h Mon Jul 26 10:52:56 2010 +0100 +++ b/kernel/eka/include/e32ver.h Fri Aug 06 16:34:38 2010 +0100 @@ -28,7 +28,7 @@ const TInt KE32MajorVersionNumber=2; const TInt KE32MinorVersionNumber=0; -const TInt KE32BuildVersionNumber=3109; +const TInt KE32BuildVersionNumber=3110; const TInt KMachineConfigurationMajorVersionNumber=1; const TInt KMachineConfigurationMinorVersionNumber=0; diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/kernel/sutils.cpp --- a/kernel/eka/kernel/sutils.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kernel/eka/kernel/sutils.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -3548,10 +3548,19 @@ void TClientRequest::EndComplete(DThread* aThread) { + // NB: if the callback is successfully queued, the target thread may run and + // process it before we get back from the call to QueueUserModeCallback(). + // In that case, 'iStatus' will be changed; and in general it is not safe to + // look at any element of 'this' once the callback is queued, as it may change + // asynchronously. Therefore, we must cache the value of 'iStatus' beforehand + // and later use this saved copy to decide whether to signal the target thread. + T_UintPtr status = iStatus; TInt r = NKern::QueueUserModeCallback(&aThread->iNThread, this); + if (r == KErrNone) { - if (iStatus != (KClientRequestNullStatus | KClientRequestFlagInUse)) + __NK_ASSERT_DEBUG(status & KClientRequestFlagInUse); + if ((status & ~KClientRequestFlagInUse) != KClientRequestNullStatus) NKern::ThreadRequestSignal(&aThread->iNThread); } else diff -r 75252ea6123b -r c7a0ce20c48c kernel/eka/release.txt --- a/kernel/eka/release.txt Mon Jul 26 10:52:56 2010 +0100 +++ b/kernel/eka/release.txt Fri Aug 06 16:34:38 2010 +0100 @@ -1,4 +1,27 @@ -Version 2.00.3108 +Version 2.00.3110 +================= +(Made by fadhliM 22/07/2010) + +1. davegord + 1. ou1cimx1#488456 (MCL) Kernel signals MTP server unexpectedly and cause it panic + +2. dogunjom + 1. ou1cimx1#413278 MCL:Domain Manager - Correct the usage of RArray::Append() + +3. jcoppear + 1. ou1cimx1#479322 ENV E32TEST T_RAMDEFRAG test failure investigation (t_ramdefrag.cpp:549) + +4. vfebvre + 1. ou1cimx1#460995 ENV E32TEST T_PAGETABLE_LIMIT test failure investigation (t_pagetable_limit.cpp:276) + +5. seolney + 1. ou1cimx1#486893 DEV DMA functions missing test code (pt. 2) + +6. mipetzol + 1. ou1cimx1#479623 DMA V2 framework PIL enhancement required for management of AsymmmetricSgChannel class descriptors + + +Version 2.00.3109 ================= (Made by fadhliM 19/07/2010) diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/defrag/t_ramdefrag.cpp --- a/kerneltest/e32test/defrag/t_ramdefrag.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/defrag/t_ramdefrag.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -543,7 +543,20 @@ Ldd.ResetDriver(); Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC); - if (VerifyMovDisAlloc() != KErrNone) + TInt r; + r = VerifyMovDisAlloc(); + if (r == KErrGeneral) + { + // A rare set of circumstances may cause some of the movable pages to be in + // use during the defrag and thus not be moved to the correct RAM zone. Run + // the defrag once more to give it a chance to move these pages. We ensure + // that there is no pending asynchronous clean up operation before doing so. + UserSvr::HalFunction(EHalGroupKernel, EKernelHalSupervisorBarrier, 0, 0); + Ldd.CallDefrag(DEFRAG_TYPE_GEN, DEFRAG_VER_SYNC); + r = VerifyMovDisAlloc(); + } + + if (r != KErrNone) { CLEANUP(;); TEST_FAIL; diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/dma/d_dma.cpp --- a/kerneltest/e32test/dma/d_dma.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/dma/d_dma.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -260,6 +260,19 @@ r = TDmaChannel::Open(info, iChannel); if (r!= KErrNone) return r; + + // ---> Code coverage of rarely called functions + const TDmac* const c = iChannel->Controller(); + if (!c) + return KErrGeneral; + const TInt mts = iChannel->MaxTransferSize(0, iCookie); + if (mts == 0) + return KErrGeneral; + const TUint mam = iChannel->MemAlignMask(0, iCookie); + if (~mam == 0) + return KErrGeneral; + // <--- Code coverage of rarely called functions + iClient = &Kern::CurrentThread(); for (TInt i=0; i(a1); + TInt r = EnableDstElementCountingByCookie(requestCookie); + return r; + } + case RDmaSession::EEnableSrcElementCounting: + { + TUint requestCookie = reinterpret_cast(a1); + TInt r = EnableSrcElementCountingByCookie(requestCookie); + return r; + } + case RDmaSession::EDisableDstElementCounting: + { + TUint requestCookie = reinterpret_cast(a1); + TInt r = DisableDstElementCountingByCookie(requestCookie); + return r; + } + case RDmaSession::EDisableSrcElementCounting: + { + TUint requestCookie = reinterpret_cast(a1); + TInt r = DisableSrcElementCountingByCookie(requestCookie); + return r; + } + case RDmaSession::ETotalNumDstElementsTransferred: + { + TUint requestCookie = reinterpret_cast(a1); + TInt r = TotalNumDstElementsTransferredByCookie(requestCookie); + return r; + } + case RDmaSession::ETotalNumSrcElementsTransferred: + { + TUint requestCookie = reinterpret_cast(a1); + TInt r = TotalNumSrcElementsTransferredByCookie(requestCookie); + return r; + } case RDmaSession::ERequestOpen: { RDmaSession::TRequestCreateArgs createArgs(0, EFalse, 0); @@ -1054,6 +1101,164 @@ } } +TInt DDmaTestSession::EnableDstElementCountingByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("EnableDstElementCountingByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToRequestIndex(aDriverCookie); + + if(index >= 0) + { + EnableDstElementCountingByIndex(index); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +void DDmaTestSession::EnableDstElementCountingByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("EnableDstElementCountingByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iClientDmaReqs.Count()); +#ifdef DMA_APIV2 + iClientDmaReqs[aIndex]->EnableDstElementCounting(); +#endif + } + +TInt DDmaTestSession::EnableSrcElementCountingByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("EnableSrcElementCountingByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToRequestIndex(aDriverCookie); + + if(index >= 0) + { + EnableSrcElementCountingByIndex(index); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +void DDmaTestSession::EnableSrcElementCountingByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("EnableSrcElementCountingByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iClientDmaReqs.Count()); + +#ifdef DMA_APIV2 + iClientDmaReqs[aIndex]->EnableSrcElementCounting(); +#endif + } + +TInt DDmaTestSession::DisableDstElementCountingByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("DisableDstElementCountingByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToRequestIndex(aDriverCookie); + + if(index >= 0) + { + DisableDstElementCountingByIndex(index); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +void DDmaTestSession::DisableDstElementCountingByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("DisableDstElementCountingByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iClientDmaReqs.Count()); +#ifdef DMA_APIV2 + iClientDmaReqs[aIndex]->DisableDstElementCounting(); +#endif + } + +TInt DDmaTestSession::DisableSrcElementCountingByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("DisableSrcElementCountingByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToRequestIndex(aDriverCookie); + + if(index >= 0) + { + DisableSrcElementCountingByIndex(index); + return KErrNone; + } + else + { + return KErrNotFound; + } + } + +void DDmaTestSession::DisableSrcElementCountingByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("DisableSrcElementCountingByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iClientDmaReqs.Count()); +#ifdef DMA_APIV2 + iClientDmaReqs[aIndex]->DisableSrcElementCounting(); +#endif + } + +TInt DDmaTestSession::TotalNumDstElementsTransferredByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("TotalNumDstElementsTransferredByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToRequestIndex(aDriverCookie); + + if(index >= 0) + { + TInt r = TotalNumDstElementsTransferredByIndex(index); + return r; + } + else + { + return KErrNotFound; + } + } + +TInt DDmaTestSession::TotalNumDstElementsTransferredByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("TotalNumDstElementsTransferredByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iClientDmaReqs.Count()); + +#ifdef DMA_APIV2 + TInt r = iClientDmaReqs[aIndex]->TotalNumDstElementsTransferred(); + return r; +#else + return KErrNotSupported; +#endif + } + +TInt DDmaTestSession::TotalNumSrcElementsTransferredByCookie(TUint aDriverCookie) + { + __KTRACE_OPT(KDMA, Kern::Printf("TotalNumSrcElementsTransferredByCookie: 0x%08x", aDriverCookie)); + const TInt index = CookieToRequestIndex(aDriverCookie); + + if(index >= 0) + { + TInt r = TotalNumSrcElementsTransferredByIndex(index); + return r; + } + else + { + return KErrNotFound; + } + } + +TInt DDmaTestSession::TotalNumSrcElementsTransferredByIndex(TInt aIndex) + { + __KTRACE_OPT(KDMA, Kern::Printf("TotalNumSrcElementsTransferredByIndex: %d", aIndex)); + __NK_ASSERT_DEBUG(aIndex < iClientDmaReqs.Count()); + +#ifdef DMA_APIV2 + TInt r = iClientDmaReqs[aIndex]->TotalNumSrcElementsTransferred(); + return r; +#else + return KErrNotSupported; +#endif + } TInt DDmaTestSession::IsrRedoRequestByCookie(TUint aDriverCookie,TUint32 aSrcAddr,TUint32 aDstAddr,TInt aTransferCount,TUint32 aPslRequestInfo,TBool aIsrCb) { __KTRACE_OPT(KDMA, Kern::Printf("IsrRedoRequestByCookie: 0x%08x", aDriverCookie)); diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/dmav2/d_dma2.h --- a/kerneltest/e32test/dmav2/d_dma2.h Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/dmav2/d_dma2.h Fri Aug 06 16:34:38 2010 +0100 @@ -508,6 +508,36 @@ return DoControl(EFragmentCount, reinterpret_cast(aRequestCookie)); } + TInt RequestEnableDstElementCounting(TUint aRequestCookie) + { + return DoControl(EEnableDstElementCounting, reinterpret_cast(aRequestCookie)); + } + + TInt RequestEnableSrcElementCounting(TUint aRequestCookie) + { + return DoControl(EEnableSrcElementCounting, reinterpret_cast(aRequestCookie)); + } + + TInt RequestDisableDstElementCounting(TUint aRequestCookie) + { + return DoControl(EDisableDstElementCounting, reinterpret_cast(aRequestCookie)); + } + + TInt RequestDisableSrcElementCounting(TUint aRequestCookie) + { + return DoControl(EDisableSrcElementCounting, reinterpret_cast(aRequestCookie)); + } + + TInt RequestTotalNumDstElementsTransferred(TUint aRequestCookie) + { + return DoControl(ETotalNumDstElementsTransferred, reinterpret_cast(aRequestCookie)); + } + + TInt RequestTotalNumSrcElementsTransferred(TUint aRequestCookie) + { + return DoControl(ETotalNumSrcElementsTransferred, reinterpret_cast(aRequestCookie)); + } + /** Will fragment a DMA request using the legacy API */ @@ -614,8 +644,7 @@ TPckgC package(args); return DoControl(ERequestOpen, &package, &aRequestCookie); } - - + struct TRequestCreateArgs { TRequestCreateArgs(TUint aChannelCookie, TBool aNewStyle, TUint aMaxFragmentSize) @@ -690,6 +719,12 @@ EQueueRequestWithReque, ELinkChannel, EUnlinkChannel, + EEnableDstElementCounting, + EEnableSrcElementCounting, + EDisableDstElementCounting, + EDisableSrcElementCounting, + ETotalNumDstElementsTransferred, + ETotalNumSrcElementsTransferred, }; }; #endif // __D_DMA2_H__ diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/dmav2/dma2_sim.cpp --- a/kerneltest/e32test/dmav2/dma2_sim.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/dmav2/dma2_sim.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -31,6 +31,12 @@ static const TInt KMemAlignMask = 0; // memory addresses passed to DMAC must be multiple of 8 static const TInt KDesCount = 160; // Initial DMA descriptor count +#define TEST_RETURN(X) if (!(X))\ + {\ + __KTRACE_OPT(KPANIC, Kern::Printf("Simulated Dma test failure: " __FILE__ " line %d", __LINE__));\ + return KErrAbort;\ + } + class TDmaDesc // // Hardware DMA descriptor @@ -101,10 +107,14 @@ // Simulated channel ////////////////////////////////////////////////////////////////////////////// +/** +An interface class to add simulation specific functionallity to any DMA channel +*/ class MSimChannel { public: - virtual void PreOpen() {} + virtual TInt PreOpen() =0; + virtual TDmaChannel& Channel() =0; }; ////////////////////////////////////////////////////////////////////////////// @@ -168,9 +178,11 @@ void DoCancelAll(); void CallDefaultVirtuals(); + TInt CheckExtensionStubs(); // From MSimChannel - void PreOpen(); + TInt PreOpen(); + TDmaChannel& Channel() {return *this;} }; void TEmptyChannel::DoCancelAll() @@ -192,9 +204,23 @@ QueuedRequestCountChanged(); } -void TEmptyChannel::PreOpen() +TInt TEmptyChannel::CheckExtensionStubs() + { + DMA_PSL_TRACE("Calling extension stubs"); + + TInt r = Extension(0, NULL); + TEST_RETURN(r == KErrNotSupported) + + r = StaticExtension(0, NULL); + TEST_RETURN(r == KErrNotSupported) + + return KErrNone; + } + +TInt TEmptyChannel::PreOpen() { CallDefaultVirtuals(); + return CheckExtensionStubs(); } ////////////////////////////////////////////////////////////////////////////// @@ -258,8 +284,6 @@ // : TDmac(aInfo) { - // TODO remove this once DMAC can be created and destroyed from test LDD entry - // point TInt r = Create(aInfo); __NK_ASSERT_ALWAYS(r == KErrNone); @@ -554,8 +578,6 @@ // : TDmac(KInfo) { - // TODO remove this once DMAC can be created and destroyed from test LDD entry - // point TInt r = Create(); __NK_ASSERT_ALWAYS(r == KErrNone); } @@ -654,15 +676,15 @@ struct TChanEntry { - TChanEntry(TDmac& aController, TDmaChannel& aChannel, const SDmacCaps& aCaps) + TChanEntry(TDmac& aController, MSimChannel& aChannel, const SDmacCaps& aCaps) : iController(aController), - iChannel(aChannel), + iSimChannel(aChannel), iCaps(aCaps) {} TDmac& iController; - TDmaChannel& iChannel; + MSimChannel& iSimChannel; const SDmacCaps& iCaps; }; @@ -686,7 +708,7 @@ __DMA_ASSERTA(aOpenId < static_cast(KChannelCount)); const TChanEntry& entry = ChannelTable[aOpenId]; - TDmaChannel* pC = &entry.iChannel; + TDmaChannel* pC = &entry.iSimChannel.Channel(); if (pC->IsOpened()) { pC = NULL; @@ -702,9 +724,19 @@ // as taken Signal(); - static_cast(pC)->PreOpen(); + TInt r = entry.iSimChannel.PreOpen(); Wait(); + + // If there was an error + // Close channel after retaking mutex + if(r != KErrNone) + { + pC->iController = NULL; + pC = NULL; + } + + } return pC; } diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/dmav2/t_dma2.cpp --- a/kerneltest/e32test/dmav2/t_dma2.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/dmav2/t_dma2.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -131,7 +131,10 @@ if(iDmaSession.Handle() == KNullHandle) { TInt r = iDmaSession.Open(); - RDebug::Printf("CDmaTest::OpenDmaSession = %d\n", r); + if(KErrNone != r) + { + RDebug::Printf("CDmaTest::OpenDmaSession = %d\n", r); + } TEST_ASSERT(r == KErrNone); r = iDmaSession.OpenSharedChunk(iChunk); TEST_ASSERT(r == KErrNone); @@ -782,6 +785,78 @@ } ////////////////////////////////////////////////////////////////////// +// CElementCountingTest +// +// -Open DMA Channel +// -Create Request +// -Fragment and Make calls to Element Counting APIs +// -Check that TotalNumDstElementsTransferred() and TotalNumSrcElementsTransferred() +// return non zero values +// -Check that KErrNone(from test driver) returned for other API calls +// -Queue Request +// -Close DMA Channel +////////////////////////////////////////////////////////////////////// +CElementCountingTest::~CElementCountingTest() + { + } + +void CElementCountingTest::RunTest() + { + OpenDmaSession(); + PreTransferSetup(); + + //Open a single DMA channel for a transfer + OpenChannel(); + + //Setup a DMA request and Fragment the request. + RDebug::Printf("Create and Fragment DMA Request"); + CreateDmaRequest(); + Fragment(); + + //Enable src/dst counting + RDebug::Printf("Enable DstElementCounting"); + TInt r = iDmaSession.RequestEnableDstElementCounting(iRequestSessionCookie); + TEST_ASSERT(KErrNone == r); + + RDebug::Printf("Enable SrcElementCounting"); + r = iDmaSession.RequestEnableSrcElementCounting(iRequestSessionCookie); + TEST_ASSERT(KErrNone == r); + + //Queue request + RDebug::Printf("Queue DMA Request"); + Queue(); + + //Disable src/dst counting + RDebug::Printf("Disable DstElementCounting"); + r = iDmaSession.RequestDisableDstElementCounting(iRequestSessionCookie); + TEST_ASSERT(KErrNone == r); + + RDebug::Printf("Disable SrcElementCounting"); + r = iDmaSession.RequestDisableSrcElementCounting(iRequestSessionCookie); + TEST_ASSERT(KErrNone == r); + + //check total src/dst elements transferred + RDebug::Printf("Get Total Number of DstElementsTransferred"); + r = iDmaSession.RequestTotalNumDstElementsTransferred(iRequestSessionCookie); + TEST_ASSERT(r >= 0); + + RDebug::Printf("Get Total Number of SrcElementsTransferred"); + r = iDmaSession.RequestTotalNumSrcElementsTransferred(iRequestSessionCookie); + TEST_ASSERT(r >= 0); + + FreeRequest(); + CloseChannel(); + + PostTransferCheck(); + CloseDmaSession(); + } + +void CElementCountingTest::PrintTestType() const + { + RDebug::RawPrint(_L("Element Counting Tests")); + } + +////////////////////////////////////////////////////////////////////// // COpenCloseTest ////////////////////////////////////////////////////////////////////// COpenCloseTest::~COpenCloseTest() diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/dmav2/t_dma2.h --- a/kerneltest/e32test/dmav2/t_dma2.h Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/dmav2/t_dma2.h Fri Aug 06 16:34:38 2010 +0100 @@ -621,6 +621,33 @@ inline CPauseResumeNegTest& UseNewDmaApi(TBool aFlag) {CSingleTransferTest::UseNewDmaApi(aFlag); return *this;} }; + +/** +Used for testing element counting + +Extends CSingle transfer by adding the capability to test +Element Counting APIs +*/ +class CElementCountingTest : public CSingleTransferTest + { +public: + CElementCountingTest(const TDesC& aName, TInt aIterations, const TDmaTransferArgs& aArgs, const TResultSet& aExpected) + :CSingleTransferTest(aName, aIterations, aArgs, aExpected) + {} + + ~CElementCountingTest(); + + virtual void RunTest(); + virtual void PrintTestType() const; + + virtual CTest* Clone() const {return new CElementCountingTest(*this);} + + // The methods below is a setters ie. The Named Parameter Idiom + // @see http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.18 + inline CElementCountingTest& UseNewDmaApi(TBool aFlag) {CSingleTransferTest::UseNewDmaApi(aFlag); return *this;} + }; + + /** Used for testing Linking of DMA Channels ( Negative Testing) diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/dmav2/test_cases.cpp --- a/kerneltest/e32test/dmav2/test_cases.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/dmav2/test_cases.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -1183,6 +1183,40 @@ TTestCase testCaseChannelLinking(&testChannelLinking , EFalse, capAboveV1,LinkingNotWanted); } +//-------------------------------------------------------------------------------------------- +//! TestCaseID KBASE-DMA-2574 +//! TestType CIT +//! PREQ REQ +//! TestCaseDesc This test verifies that the DMA Element Counting APIs can be called. The calls +//! to these functions are meant to be used to meet a code coverage requirement.These APIs +//! are not yet supported so the functionality of the APIs are not currently tested. +//! +//! TestActions +//! 1. Open a DMA channel for a transfer. +//! 2. Make calls to Element Counting APIs +//! 3. Close DMA channel. +//! +//! +//! TestExpectedResults 1. DMA channel opens and KErrNone returned. +//! 2. Element Counting APIs are called without crashing the framework +//! 3. DMA channel closes and KErrNone returned. +//! +//! TestPriority High +//! TestStatus Implemented +//---------------------------------------------------------------------------------------------- +namespace ElementCountingTest + { + const TInt srcAddr = 0; + const TInt desAddr = 2 * KMega; + const TInt transferSize = 1 * KMega; + + TDmaTransferArgs transferArgs(srcAddr, desAddr, transferSize, KDmaMemAddr); + + const TResultSet expectedResults(threadCallback); + CElementCountingTest testElementCounting(_L("DMA Element Counting Test"), 1, transferArgs, expectedResults); + TTestCase testCaseElementCounting(&testElementCounting, EFalse, capAboveV1); + } + static TTestCase* StaticSimpleTestArray[] = { &Simple_1::testCase, &Simple_1::testCaseConcurrent, @@ -1341,6 +1375,7 @@ &CancelAllTest::testCase, &IsQueueEmptyTest::testCase, &ChannelLinkingTest::testCaseChannelLinking, + &ElementCountingTest::testCaseElementCounting, }; RPointerArray TestArray(StaticTestArray, ARRAY_LENGTH(StaticTestArray)); diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/mmu/t_alias_remove.cpp --- a/kerneltest/e32test/mmu/t_alias_remove.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/mmu/t_alias_remove.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -207,7 +207,7 @@ if ((fillValue & 0xf) == 1) test.Printf(_L(".")); - PRINTF(T_PRINTF(_L("Process ID %d start slave fill value %d\n"), aProcessId, fillValue)); + test.Printf(_L("Process ID %d start slave fill value %d\n"), aProcessId, fillValue); RServer2 masterServer; r = masterServer.CreateGlobal(MasterServerName); test_KErrNone(r); @@ -269,7 +269,7 @@ } } - PRINTF(T_PRINTF(_L("Process ID %d Wait for alias to complete\n"), aProcessId)); + test.Printf(_L("Process ID %d Wait for alias to complete\n"), aProcessId); masterMessage.Complete(KErrNone); User::WaitForRequest(threadStatus); TInt statusInt = threadStatus.Int(); @@ -280,7 +280,7 @@ test_Equal(EExitKill, readThread.ExitType()); readThread.Close(); - PRINTF(T_PRINTF(_L("Process ID %d Wait for slave to complete\n"), aProcessId)); + test.Printf(_L("Process ID %d Wait for slave to complete\n"), aProcessId); User::WaitForRequest(slaveStatus); test_Equal(EExitKill, slaveProcess.ExitType()); test_Equal(KErrNone, slaveProcess.ExitReason()); diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/e32test/power/t_domain.cpp --- a/kerneltest/e32test/power/t_domain.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/e32test/power/t_domain.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2002-2010 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" @@ -806,7 +806,9 @@ void Perform(); void Release(); TInt TransitionNotification(MDmDomainMember& aDomainMember); - void TransitionRequestComplete(); + void TransitionRequestComplete(); + void RunTestOnGetTransitionFailures(RArray& aTransitionFailure); + CDmTest5(TDmDomainId aPowerId, TDmDomainId aTestId, TDmDomainState aPowerState, TDmDomainState aTestState) : CActive(CActive::EPriorityStandard), iPowerDomainId(aPowerId), iTestDomainId(aTestId), iPowerState(aPowerState), iTestState(aTestState) {} @@ -846,7 +848,28 @@ TInt iTransitionsExpected; }; - +void CDmTest5::RunTestOnGetTransitionFailures(RArray& aTransitionFailure) + { + //************************************************* + // Test - OOM Testing on GetTransitionFailures() + // Simulates heap failure in GetTransitionFailures() + //************************************************* + TInt error = 0; + TInt count = 0; + do + { + __UHEAP_SETFAIL(RHeap::EFailNext, ++count); + error = iTestDomainManager.GetTransitionFailures(aTransitionFailure); + test.Printf( _L( "CDmTest5::RunTestOnGetTransitionFailures, simulating heap failure on GetTransitionFailures(), Error=%d, Run=%d\n" ), error, count ); + }while(error == KErrNoMemory); + + __UHEAP_RESET; + + //Actual count of heap failure as the final iteration which terminates the loop would not return KErrNoMemory + --count; + test(count > 0); + test.Printf( _L( "Out of memory tests on GetTransitionFailures() succeeded at heap failure rate of %i\n" ), count ); + } //! @SYMTestCaseID PBASE-T_DOMAIN-5 //! @SYMTestType CT @@ -1106,6 +1129,18 @@ testFailureCount = iTestDomainManager.GetTransitionFailureCount(); test (testFailureCount == 1); +#ifdef _DEBUG + //*************************************************************** + // OOM Testing: Simulates heap failure in GetTransitionFailures() + //*************************************************************** + __UHEAP_MARK; + RArray oomTestFailures; + RunTestOnGetTransitionFailures(oomTestFailures); + test(oomTestFailures.Count()==1); + oomTestFailures.Close(); + __UHEAP_MARKEND; +#endif + r = iTestDomainManager.GetTransitionFailures(testFailures); test(r == KErrNone); test(testFailureCount == testFailures.Count()); @@ -2210,7 +2245,6 @@ { MDmTest* tests[] = { - new CDmTest1(KDmIdRoot, EPwStandby), new CDmTest1(KDmIdRoot, EPwOff), new CDmTest1(KDmIdRoot, EPwActive), diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/f32test/fileutils/inc/tf32testtimer.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kerneltest/f32test/fileutils/inc/tf32testtimer.h Fri Aug 06 16:34:38 2010 +0100 @@ -0,0 +1,154 @@ +// Copyright (c) 2010 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: +// @file +// +// +// + + +class TF32TestTimer +{ +public: + TF32TestTimer(); + + void Start(); + void Stop(); + + TInt64 TimeTaken() const; + TTimeIntervalMicroSeconds Time() const; + TTimeIntervalMicroSeconds32 Time32() const; + int TimeInMicroSeconds() const; + int TimeInMilliSeconds() const; + + static TInt TimeInMilliSeconds(TTimeIntervalMicroSeconds aTime); + static TInt TimeInMilliSeconds(TTimeIntervalMicroSeconds32 aTime); + +protected: + TInt64 Diff(TUint32 aTicks) const; + +protected: + TInt iFastCounterFreq; + TUint32 startTicks; + TUint32 endTicks; +}; + + +class TF32TestTimer2: public TF32TestTimer +{ +public: + void Stop2(); + + TInt64 TimeTaken2() const; + TTimeIntervalMicroSeconds32 Time2() const; + int Time2InMicroSeconds() const; + +private: + TUint32 endTicks2; +}; + +inline TF32TestTimer::TF32TestTimer() +{ + TInt r = HAL::Get(HAL::EFastCounterFrequency, iFastCounterFreq); + test_KErrNone(r); +} + +inline void TF32TestTimer::Start() +{ + startTicks = User::FastCounter(); +} + +inline void TF32TestTimer::Stop() +{ + endTicks = User::FastCounter();; +} + +inline void TF32TestTimer2::Stop2() +{ + endTicks2 = User::FastCounter();; +} + +inline TInt64 TF32TestTimer::Diff(TUint32 aTicks) const +{ + if (aTicks == startTicks) + { + test.Printf(_L("Warning: tick not advanced")); + } + + TInt64 diff; + if (aTicks > startTicks) + { + diff = static_cast(aTicks) - static_cast(startTicks); + } + else + { + // handle counter rollover + diff = ((static_cast(KMaxTUint32) + 1 + aTicks) - static_cast(startTicks)); + } + //RDebug::Printf("%x %x %ld", aTicks, startTicks, diff); + diff *= TInt64(1000000); + diff /= TInt64(iFastCounterFreq); + + return diff; +} + +inline TInt64 TF32TestTimer::TimeTaken() const +{ + return Diff(endTicks); +} + +inline TInt64 TF32TestTimer2::TimeTaken2() const +{ + return Diff(endTicks2); +} + +inline int TF32TestTimer::TimeInMicroSeconds() const +{ + return static_cast (TimeTaken()); +} + +inline int TF32TestTimer2::Time2InMicroSeconds() const +{ + return static_cast (TimeTaken2()); +} + +inline TTimeIntervalMicroSeconds TF32TestTimer::Time() const +{ + return TimeTaken(); +} + +inline TTimeIntervalMicroSeconds32 TF32TestTimer2::Time2() const +{ + return static_cast (TimeTaken2()); +} + +inline TTimeIntervalMicroSeconds32 TF32TestTimer::Time32() const +{ + return static_cast (TimeTaken()); +} + +inline int TF32TestTimer::TimeInMilliSeconds() const +{ + return static_cast (TimeTaken() / 1000); +} + +TInt TF32TestTimer::TimeInMilliSeconds(TTimeIntervalMicroSeconds aTime) +{ + return static_cast (aTime.Int64()/static_cast(1000)); +} + +TInt TF32TestTimer::TimeInMilliSeconds(TTimeIntervalMicroSeconds32 aTime) +{ + return static_cast (aTime.Int()/1000); +} + diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/f32test/group/t_wcache.mmp --- a/kerneltest/f32test/group/t_wcache.mmp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/f32test/group/t_wcache.mmp Fri Aug 06 16:34:38 2010 +0100 @@ -23,6 +23,7 @@ LIBRARY euser.lib efsrv.lib hal.lib OS_LAYER_SYSTEMINCLUDE_SYMBIAN +USERINCLUDE ../fileutils/inc EPOCSTACKSIZE 0x10000 CAPABILITY TCB DISKADMIN ALLFILES diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/f32test/server/t_fsched.cpp --- a/kerneltest/f32test/server/t_fsched.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/f32test/server/t_fsched.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -29,9 +29,11 @@ #include "t_server.h" #include #include +#include +#include "tf32testtimer.h" #include "f32_test_utils.h" +using namespace F32_Test_Utils; -using namespace F32_Test_Utils; //---------------------------------------------------------------------------------------------- //! @SYMTestCaseID PBASE-T_FSCHED-0191 @@ -117,7 +119,6 @@ HBufC8* gBufSec = NULL; TPtr8 gBufWritePtr(NULL, 0); -const TInt KuStomS = 1000; const TInt KOneK = 1024; const TInt KOneMeg = KOneK * 1024; const TInt KBigBlockSize = KOneMeg ; @@ -134,8 +135,8 @@ TTimeIntervalMicroSeconds32 gTimeTakenBigBlock(0); TBuf16<45> gSmallFile, gBigFile; TInt gNextFile=0; -TTime gTime1; -TTime gTime2; + +TF32TestTimer gTestTimer; RSemaphore gSync; @@ -154,6 +155,9 @@ ENoThreads }; + + + /** Generates a file name of the form FFFFF*.TXT (aLong.3) @param aBuffer The filename will be returned here @@ -613,32 +617,30 @@ } - /** Measure the time taken for a big block to be written synchronously */ void TimeTakenToWriteBigBlock() { - TTime startTime; - TTime endTime; RFile fileWrite; TInt r = fileWrite.Replace(TheFs,gBigFile,EFileShareAny|EFileWrite|EFileWriteDirectIO); TESTERROR(r); // Calculate how long it takes to write a big block to be able to issue at the right time the concurrent writes - startTime.HomeTime(); + TF32TestTimer timer; + timer.Start(); r = fileWrite.Write(gBufWritePtr, KBigBlockSize); - - endTime.HomeTime(); - + + timer.Stop(); + fileWrite.Close(); TESTERROR(r); - gTimeTakenBigBlock = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()/3); - - test.Printf(_L("\nTime spent to write the big block in isolation: %d ms\n"), gTimeTakenBigBlock.Int() / KuStomS); + gTimeTakenBigBlock = timer.TimeInMicroSeconds()/3; + + test.Printf(_L("\nTime spent to write the big block in isolation: %d ms\n"), TF32TestTimer::TimeInMilliSeconds(gTimeTakenBigBlock)); } @@ -646,51 +648,44 @@ */ void TimeTakenToWriteBigFile(TInt aPos) { - TTime startTime; - TTime endTime; - test((aPos >= 0) && (aPos <= 1)); - startTime.HomeTime(); - + TF32TestTimer timer; + timer.Start(); + WriteFile(TheFs,gBigFile, gBigFileSize, KBigBlockSize, ENoThreads); - endTime.HomeTime(); + timer.Stop(); - gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); + gTimeTakenBigFile = timer.Time32(); + + test.Printf(_L("\nTime spent to write the big file in isolation: %d ms\n"), TF32TestTimer::TimeInMilliSeconds(gTimeTakenBigFile)); - - test.Printf(_L("\nTime spent to write the big file in isolation: %d ms\n"), gTimeTakenBigFile.Int() / KuStomS); - - gTotalTimeSync[aPos] = Max((gTimeTakenBigFile.Int()/KuStomS), gTotalTimeSync[aPos]) ; + gTotalTimeSync[aPos] = Max(TF32TestTimer::TimeInMilliSeconds(gTimeTakenBigFile), gTotalTimeSync[aPos]) ; } /** Measure the time taken for this file to be written asynchronously */ void TimeTakenToWriteBigFileAsync(TInt aPos) { - TTime startTime; - TTime endTime; - TTime endTime2; TRequestStatus status[KWaitRequestsTableSize]; RFile bigFile; test((aPos >= 0) && (aPos <= 1)); - - startTime.HomeTime(); + + TF32TestTimer2 timer; + timer.Start(); WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize,KBigBlockSize,status); - endTime.HomeTime(); - + timer.Stop(); WaitForAll(status, gBigFileSize, KBigBlockSize); + timer.Stop2(); - endTime2.HomeTime(); - - gTimeTakenBigFile=I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); + gTimeTakenBigFile = timer.Time32(); bigFile.Close(); - test.Printf(_L("\nTime to queue the blocks in isolation asynchronously: %d ms, "), gTimeTakenBigFile.Int() / KuStomS); - gTimeTakenBigFile=I64LOW(endTime2.MicroSecondsFrom(startTime).Int64()); - test.Printf(_L("to actually write it: %d ms\n"),gTimeTakenBigFile.Int() / KuStomS); - gTotalTimeAsync[aPos] = Max((gTimeTakenBigFile.Int() / KuStomS), gTotalTimeAsync[aPos]) ; + test.Printf(_L("\nTime to queue the blocks in isolation asynchronously: %d ms, "), timer.TimeInMilliSeconds()); + gTimeTakenBigFile = timer.Time2(); + test.Printf(_L("to actually write it: %d ms\n"), TF32TestTimer::TimeInMilliSeconds(gTimeTakenBigFile)); + gTotalTimeAsync[aPos] = Max(TF32TestTimer::TimeInMilliSeconds(gTimeTakenBigFile), gTotalTimeAsync[aPos]) ; } /** Delete content of directory @@ -728,7 +723,7 @@ TESTERROR(r); ReadFile(fs,gSmallFile,KBlockSize, EThreadWait); - gTime2.HomeTime(); + gTestTimer.Start(); client.Signal(); @@ -753,7 +748,7 @@ TESTERROR(r); ReadFile(fs,gBigFile,KBlockSize, EThreadWait); - gTime2.HomeTime(); + gTestTimer.Stop(); client.Signal(); @@ -778,7 +773,7 @@ TESTERROR(r); WriteFile(fs,gSmallFile,gSmallFileSize, KBlockSize, EThreadWait); - gTime2.HomeTime(); + gTestTimer.Start(); client.Signal(); @@ -803,7 +798,7 @@ TESTERROR(r); WriteFile(fs, gBigFile, gBigFileSize, KBigBlockSize, EThreadSignal); - gTime1.HomeTime(); + gTestTimer.Stop(); client.Signal(); @@ -828,7 +823,7 @@ TESTERROR(r); WriteFile(fs, gSmallFile, gBigFileSize, KBigBlockSize, EThreadWait); - gTime2.HomeTime(); + gTestTimer.Stop(); client.Signal(); @@ -900,19 +895,13 @@ */ void TestReadingWhileWriting() -{ - TInt r = 0; - TTime time1; - TTime time2; - - time1.HomeTime(); - +{ // Write the small file and take the appropriate measures WriteFile(TheFs,gSmallFile,KBlockSize, KBlockSize, ENoThreads); // Sync test TBuf<20> buf=_L("Big Write"); - r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL); + TInt r = gBig.Create(buf, WriteBigFile, KDefaultStackSize, KHeapSize, KMaxHeapSize, NULL); TEST(r == KErrNone); buf = _L("Small Read"); @@ -928,15 +917,13 @@ gBig.Close(); gSmall.Close(); - - TTimeIntervalMicroSeconds timeTaken = gTime1.MicroSecondsFrom(gTime2); - test.Printf(_L("\nSync read done %d ms before the write ended\n"),I64LOW(timeTaken.Int64() / KuStomS)); - TReal time=I64LOW(timeTaken.Int64() / KuStomS); + TTimeIntervalMicroSeconds timeTaken = gTestTimer.Time(); + test.Printf(_L("\nSync read done %d ms before the write ended\n"), TF32TestTimer::TimeInMilliSeconds(timeTaken)); #if !defined(__WINS__) - // If this condition fails, it means that writing the sync file while fairscheduling a small sync read takes too long - test.Printf(_L("time: %f\n"), time); - // test((time > 0) && (((gTotalTimeSync[0]-time)>0) || ((gTotalTimeSync[1]-time)>0)) ); - test(time > 0); + // If this condition fails, it means that writing the sync file while + // fairscheduling a small sync read takes too long. Reading small file + // should complete first. + test(timeTaken > 0); #endif // Async test @@ -948,27 +935,26 @@ ReadFileAsync(TheFs, smallFile, gSmallFile, KBlockSize, status2 ); WaitForAll(status2,KBlockSize , KBlockSize ); - time1.HomeTime(); + + TF32TestTimer timer; + timer.Start(); WaitForAll(status,gBigFileSize, KBigBlockSize); - time2.HomeTime(); + timer.Stop(); bigFile.Close(); smallFile.Close(); - timeTaken = time2.MicroSecondsFrom(time1); + timeTaken = timer.Time(); - test.Printf(_L("\nAsync read done %d ms before the write ended\n"),I64LOW(timeTaken.Int64() / KuStomS)); - time = I64LOW(timeTaken.Int64() / KuStomS); + test.Printf(_L("\nAsync read done %d ms before the write ended\n"), timer.TimeInMilliSeconds()); #if !defined(__WINS__) if (!Is_HVFS(TheFs, gDrive)) { // If this condition fails, it means that writing the async file while fairscheduling a small async read takes too long - test.Printf(_L("time: %f\n"), time); test.Printf(_L("gTotalTimeAsync[0] = %d , gTotalTimeAsync[1] = %d\n"),gTotalTimeAsync[0],gTotalTimeAsync[1] ); - // test((time > 0) && (((gTotalTimeAsync[0]-time)>0) || ((gTotalTimeAsync[1]-time)>0)) ); - test(time > 0); + test(timeTaken > 0); } #endif } @@ -979,8 +965,6 @@ void TestWritingWhileWriting() { TInt r = 0; - TTime time1; - TTime time2; // Sync test TBuf<20> buf = _L("Big Write II"); @@ -1000,14 +984,12 @@ gBig.Close(); gSmall.Close(); - TTimeIntervalMicroSeconds timeTaken = gTime1.MicroSecondsFrom(gTime2); - test.Printf(_L("\nSync write done %d ms before the big write ended\n"),I64LOW(timeTaken.Int64() / KuStomS)); - TReal time=I64LOW(timeTaken.Int64() / KuStomS); + TTimeIntervalMicroSeconds timeTaken = gTestTimer.Time(); + test.Printf(_L("\nSync write done %d ms before the big write ended\n"), gTestTimer.TimeInMilliSeconds()); #if !defined(__WINS__) - // If this condition fails, it means that writing the sync file while fairscheduling a small sync write takes too long - test.Printf(_L("time: %f\n"), time); - // test((time > 0) && (((gTotalTimeSync[0]-time)>0) || ((gTotalTimeSync[1]-time)>0)) ); - test(time > 0); + // If this condition fails, it means that writing the sync file while + // fairscheduling a small sync write takes too long + test(timeTaken > 0); #endif // Async test @@ -1018,21 +1000,19 @@ WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize, KBigBlockSize, status); WriteFileAsync(TheFs,smallFile, gSmallFile,gSmallFileSize,KBlockSize,status2); WaitForAll(status2,gSmallFileSize, KBlockSize); - time1.HomeTime(); + TF32TestTimer timer; + timer.Start(); WaitForAll(status, gBigFileSize, KBigBlockSize); - time2.HomeTime(); + timer.Stop(); - timeTaken = time2.MicroSecondsFrom(time1); - test.Printf(_L("\nAsync write done %d ms before the big write ended\n"),I64LOW(timeTaken.Int64() / KuStomS)); - time=I64LOW(timeTaken.Int64() / KuStomS); + timeTaken = timer.Time(); + test.Printf(_L("\nAsync write done %d ms before the big write ended\n"),timer.TimeInMilliSeconds()); #if !defined(__WINS__) if (!Is_HVFS(TheFs, gDrive)) { // If this condition fails, it means that writing the async file while fairscheduling a small async write takes too long - test.Printf(_L("time: %f\n"), time); test.Printf(_L("gTotalTimeAsync[0] = %d , gTotalTimeAsync[1] = %d\n"),gTotalTimeAsync[0],gTotalTimeAsync[1] ); - // test((time > 0) && (((gTotalTimeAsync[0]-time)>0) || ((gTotalTimeAsync[1]-time)>0)) ); - test(time > 0); + test(timeTaken > 0); } #endif bigFile.Close(); @@ -1045,8 +1025,6 @@ void TestTwoBigOnes() { TInt r = 0; - TTime time1; - TTime time2; // Sync test TBuf<20> buf = _L("Big Write IIII"); @@ -1066,8 +1044,8 @@ gBig.Close(); gSmall.Close(); - TTimeIntervalMicroSeconds timeTaken = gTime2.MicroSecondsFrom(gTime1); - test.Printf(_L("\nSync first write ended %d ms before the second write ended (same file size)\n"),I64LOW(timeTaken.Int64() / KuStomS)); + TTimeIntervalMicroSeconds timeTaken = gTestTimer.Time(); + test.Printf(_L("\nSync first write ended %d ms before the second write ended (same file size)\n"),TF32TestTimer::TimeInMilliSeconds(timeTaken)); // Async test TRequestStatus status[KWaitRequestsTableSize]; @@ -1077,12 +1055,13 @@ WriteFileAsync(TheFs, bigFile, gBigFile, gBigFileSize, KBigBlockSize, status); WriteFileAsync(TheFs, bigFile2, gSmallFile, gBigFileSize, KBigBlockSize, status2); WaitForAll(status, gBigFileSize, KBigBlockSize); - time1.HomeTime(); + TF32TestTimer timer; + timer.Start(); WaitForAll(status2, gBigFileSize, KBigBlockSize); - time2.HomeTime(); + timer.Stop(); - timeTaken = time2.MicroSecondsFrom(time1); - test.Printf(_L("\nAsync first write ended %d ms before the second write ended (same file size)\n"),I64LOW(timeTaken.Int64() / KuStomS)); + timeTaken = timer.Time(); + test.Printf(_L("\nAsync first write ended %d ms before the second write ended (same file size)\n"),TF32TestTimer::TimeInMilliSeconds(timeTaken)); bigFile.Close(); bigFile2.Close(); } @@ -1093,9 +1072,9 @@ void TestReadingWhileWritingSameFile() { TInt r = 0; - TTime time1; + TF32TestTimer timer; - time1.HomeTime(); + timer.Start(); // Sync test TBuf<20> buf = _L("Big Write IV"); @@ -1115,8 +1094,8 @@ CLOSE_AND_WAIT(gBig); CLOSE_AND_WAIT(gSmall); - TTimeIntervalMicroSeconds timeTaken = gTime2.MicroSecondsFrom(gTime1); - test.Printf(_L("\nSync write finished %d ms before the read ended\n"),I64LOW(timeTaken.Int64() / KuStomS)); + TTimeIntervalMicroSeconds timeTaken = gTestTimer.Time(); + test.Printf(_L("\nSync write finished %d ms before the read ended\n"),TF32TestTimer::TimeInMilliSeconds(timeTaken)); } diff -r 75252ea6123b -r c7a0ce20c48c kerneltest/f32test/server/t_wcache.cpp --- a/kerneltest/f32test/server/t_wcache.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/kerneltest/f32test/server/t_wcache.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -28,6 +28,8 @@ #include #include "t_server.h" #include +#include +#include "tf32testtimer.h" const TInt KTotalCacheSize = 32 * 1024 * 1024; const TInt KDefaultCacheSize = (128 + 12) * 1024; // This size is the default configuration size @@ -89,7 +91,6 @@ const TInt KOneMeg = KOneK * 1024; const TInt KBlockSize = KOneK; const TInt KWaitRequestsTableSize = 256; -const TInt KMs = 1000; TInt gSecondFileSize = 0; TInt gFirstFileSize = 0; @@ -102,9 +103,6 @@ TBuf16<25> gCurrentFile; TInt gNextFile = 0; -TTime gTime1; -TTime gTime2; - // Concurrent Threads RThread gThread1; @@ -513,25 +511,22 @@ @return time taken to perform the operation in uS */ -TInt WriteTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) +TTimeIntervalMicroSeconds WriteTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) { RTest test(_L("T_WCACHE")); - TTime startTime; - TTime endTime; TInt r = 0; - - startTime.HomeTime(); + + TF32TestTimer timer; + timer.Start(); r = WriteFile(gTheFs,aFile, aFileName , aSize * KOneK, aBlockSize, gBufWritePtr, aMode); test_KErrNone(r); - - endTime.HomeTime(); - - gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); - + + timer.Stop(); + gTimeTakenBigFile = timer.Time(); test.Close(); - return I64LOW(gTimeTakenBigFile.Int64()); + return timer.Time(); } /** Measure the time taken for this file to be read synchronously @@ -545,18 +540,16 @@ @return time taken to perform the operation in uS */ -TInt ReadTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) +TTimeIntervalMicroSeconds ReadTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aBlockSize, TInt aMode) { - TTime startTime; - TTime endTime; + TF32TestTimer timer; + timer.Start(); + ReadFile(gTheFs,aFile, aFileName, aSize * KOneK, aBlockSize, aMode); + timer.Stop(); - startTime.HomeTime(); - ReadFile(gTheFs,aFile, aFileName, aSize * KOneK, aBlockSize, aMode); - endTime.HomeTime(); - - gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); - - return I64LOW(gTimeTakenBigFile.Int64()) ; + gTimeTakenBigFile = timer.Time(); + + return timer.Time(); } /** Read asynchronously the test file from the disc @@ -569,22 +562,19 @@ @return time taken to perform the operation in uS */ -TInt ReadAsyncTestFile(RFile& file, TDes16& aFile, TInt aSize, TInt aBlockSize, TInt aMode) +TTimeIntervalMicroSeconds ReadAsyncTestFile(RFile& file, TDes16& aFile, TInt aSize, TInt aBlockSize, TInt aMode) { - TTime startTime; - TTime endTime; TRequestStatus status[KWaitRequestsTableSize]; - - startTime.HomeTime(); + TF32TestTimer timer; + timer.Start(); ReadFileAsync(gTheFs, file, aFile, aSize * KOneK, aBlockSize, status, aMode); WaitForAll(status, (aSize * KOneK)/KBlockSize); - - endTime.HomeTime(); + timer.Stop(); + + gTimeTakenBigFile = timer.Time(); - gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); - - return I64LOW(gTimeTakenBigFile.Int64()); + return timer.Time(); } /** Read asynchronously the test file from the disc @@ -596,22 +586,19 @@ @return time taken to perform the operation in uS */ -TInt WriteAsyncTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aMode) +TTimeIntervalMicroSeconds WriteAsyncTestFile(RFile& aFile, TDes16& aFileName, TInt aSize, TInt aMode) { - TTime startTime; - TTime endTime; TRequestStatus status[KWaitRequestsTableSize]; - - startTime.HomeTime(); + TF32TestTimer timer; + timer.Start(); WriteFileAsync(gTheFs, aFile, aFileName, aSize * KOneK, aMode, status ); WaitForAll(status, (aSize * KOneK)/KBlockSize); - - endTime.HomeTime(); + timer.Stop(); - gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); + gTimeTakenBigFile = timer.Time(); - return I64LOW(gTimeTakenBigFile.Int64()); + return timer.Time(); } /** Test Boundaries @@ -621,9 +608,9 @@ void TestBoundaries() { TInt r = 0; - TInt time = 0; - TInt rtime = 0; - TInt tcreate = 0; + TTimeIntervalMicroSeconds time = 0; + TTimeIntervalMicroSeconds rtime = 0; + TTimeIntervalMicroSeconds tcreate = 0; RFile fileWriter; RFile fileWriter2; RFile fileReader; @@ -641,21 +628,22 @@ test.Printf(_L("\nSync: Write from 1 K to %d K \n"), i); tcreate = WriteTestFile(fileWriter, gSecondFile, i, KBlockSize, EFileShareAny|EFileWrite|EFileWriteDirectIO); - test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, tcreate/KMs); + test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, TF32TestTimer::TimeInMilliSeconds(tcreate)); fileWriter.Close(); time = WriteTestFile(fileWriter2, gFirstFile, i, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); - test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, time/KMs); + test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, TF32TestTimer::TimeInMilliSeconds(time)); rtime = ReadTestFile(fileReader, gFirstFile, i, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); - test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, rtime/KMs); - + test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, TF32TestTimer::TimeInMilliSeconds(rtime)); fileReader.Close(); fileWriter2.Close(); #if !defined(__WINS__) - test((tcreate > time) || (tcreate > rtime)); + test(tcreate > TTimeIntervalMicroSeconds(0)); // test measured time is correct + test(tcreate > time); + test(tcreate > rtime); #endif r = gTheFs.Delete(gFirstFile); @@ -676,21 +664,23 @@ test.Printf(_L("\nAsync: Write from 1 K to %d K \n"), i); tcreate = WriteAsyncTestFile(fileWriter, gSecondFile, i, EFileShareAny|EFileWrite|EFileWriteDirectIO); - test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, tcreate/KMs); + test.Printf(_L("Time to write %d K without caching: %d mS\n"), i, TF32TestTimer::TimeInMilliSeconds(tcreate)); fileWriter.Close(); time = WriteAsyncTestFile(fileWriter2, gFirstFile, i,EFileShareAny|EFileWrite|EFileWriteBuffered); - test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, time/KMs); + test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), i, TF32TestTimer::TimeInMilliSeconds(time)); rtime = ReadAsyncTestFile(fileReader, gFirstFile, i, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); - test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, rtime/KMs); + test.Printf(_L("Time to read %d K from the cache: %d mS\n"), i, TF32TestTimer::TimeInMilliSeconds(rtime)); fileReader.Close(); fileWriter2.Close(); #if !defined(__WINS__) - test((tcreate > time) || (tcreate > rtime)); + test(tcreate > TTimeIntervalMicroSeconds(0)); // test measured time is correct + test(tcreate > time); + test(tcreate > rtime); #endif r = gTheFs.Delete(gFirstFile); @@ -749,17 +739,16 @@ @return returns the time that took to do the verification in mS, fails if the file is not corrupted/modified */ -TInt ReadTestFileVerif(TDes16& aFile) +TTimeIntervalMicroSeconds ReadTestFileVerif(TDes16& aFile) { - TTime startTime; - TTime endTime; TInt r = 0; TInt size = 0; RFile fileRead; TInt corrupt = 0; TBool isFat=IsFSFAT(gTheFs,gDrive); - - startTime.HomeTime(); + + TF32TestTimer timer; + timer.Start(); r = fileRead.Open(gTheFs,aFile,EFileShareAny|EFileRead|EFileReadBuffered|EFileReadAheadOff); test_KErrNone(r); @@ -791,12 +780,11 @@ fileRead.Close(); test(corrupt>0); // Ensure the cache returns the changed content - - endTime.HomeTime(); + timer.Stop(); - gTimeTakenBigFile = I64LOW(endTime.MicroSecondsFrom(startTime).Int64()); + gTimeTakenBigFile = timer.Time(); - return I64LOW(gTimeTakenBigFile.Int64()) / KMs; + return timer.Time(); } /** Modifies the second file @@ -840,8 +828,8 @@ LOCAL_C void TestIntegrity() { TInt r = 0; - TInt time; - TInt tcreate = 0; + TTimeIntervalMicroSeconds time; + TTimeIntervalMicroSeconds tcreate = 0; RFile file; // Modify file in some position @@ -850,14 +838,14 @@ test.Printf(_L("\nSync: Write from 1 K to %d K \n"), 255); tcreate = WriteTestFile(file, gSecondFile, 255, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); - test.Printf(_L("Time to write %d K with caching: %d mS\n"), 255, tcreate/KMs); + test.Printf(_L("Time to write %d K with caching: %d mS\n"), 255, TF32TestTimer::TimeInMilliSeconds(tcreate)); file.Close(); test.Printf(_L("Mess the content that is still in the cache\n")); CorruptSecondFile(); time = ReadTestFileVerif(gSecondFile); - test.Printf(_L("Time taken to verify: %d\n"),time); + test.Printf(_L("Time taken to verify: %ld\n"),time.Int64()); test.Printf(_L("Integrity verified\n")); @@ -1178,7 +1166,7 @@ */ void TestRemoval() { - TInt time = 0, rtime = 0; + TTimeIntervalMicroSeconds time = 0, rtime = 0; RFile file1, file2; @@ -1227,7 +1215,7 @@ test.Printf(_L("\nSync: Write from 1 K to 254 K \n")); time = WriteTestFile(file1, gSecondFile, KMinSize, KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); - test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize, time/KMs); + test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize, TF32TestTimer::TimeInMilliSeconds(time)); test.Printf(_L("Remove MMC card,! and then press a key\n")); test.Getch(); @@ -1235,7 +1223,7 @@ test.Getch(); rtime = ReadTestFile(file2, gSecondFile, KMinSize, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); - test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize, rtime/KMs); + test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize, TF32TestTimer::TimeInMilliSeconds(rtime)); test.Printf(_L("Remove MMC card! and then press a key\n")); test.Getch(); @@ -1247,7 +1235,7 @@ test.Printf(_L("\nSync: Write from 1 K to 255 K \n")); time = WriteTestFile(file1, gFirstFile, KMinSize + 1 , KBlockSize, EFileShareAny|EFileWrite|EFileWriteBuffered); - test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize + 1, time/KMs); + test.Printf(_L("Time to write %d K WITH caching: %d mS\n"), KMinSize + 1, TF32TestTimer::TimeInMilliSeconds(time)); test.Printf(_L("Remove MMC card and delete the file //F32-TST//FFFFFFF0.TXT and then press a key\n")); test.Getch(); @@ -1255,7 +1243,7 @@ test.Getch(); rtime = ReadTestFile(file2, gFirstFile, KMinSize + 1, KBlockSize, EFileShareAny|EFileRead|EFileReadBuffered); - test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize + 1, rtime/KMs); + test.Printf(_L("Time to read %d K from the cache: %d mS\n"), KMinSize + 1, TF32TestTimer::TimeInMilliSeconds(rtime)); test.Printf(_L("Remove MMC card! and then press a key\n")); test.Getch(); diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/domainmgr/src/domaincli.cpp --- a/userlibandfileserver/domainmgr/src/domaincli.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/domainmgr/src/domaincli.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -1,4 +1,4 @@ -// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// Copyright (c) 2002-2010 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" @@ -19,6 +19,7 @@ #include #include + #include #include #include "domainobserver.h" @@ -380,26 +381,43 @@ { __DM_ASSERT(Handle() != KNullHandle); + aTransitionFailures.Reset(); TInt err = KErrNone; - + TInt failureCount = GetTransitionFailureCount(); if (failureCount <= 0) return failureCount; - + + // Pre-allocate array with a known size which for this case is the value in failureCount + // in order to guarantee that future append operations to the array aTransitionFailures would + // not fail. This is assuming that the pre-allocated size is not exceeded. + err=aTransitionFailures.Reserve(failureCount); + if (err != KErrNone) + return err; + TTransitionFailure* failures = new TTransitionFailure[failureCount]; if(failures == NULL) + { + aTransitionFailures.Reset(); return(KErrNoMemory); + } + TPtr8 dataPtr(reinterpret_cast(failures), failureCount * sizeof(TTransitionFailure)); TIpcArgs a(&dataPtr); err = RSessionBase::SendReceive(EDmGetTransitionFailures, a); - + if (err == KErrNone) { - for (TInt i=0; i(trans), count * sizeof(TTransInfo)); TIpcArgs a(&dataPtr); - TInt ret=RSessionBase::SendReceive(EDmObserverGetEvent, a); + ret=RSessionBase::SendReceive(EDmObserverGetEvent, a); if(ret==KErrNone) { for (TInt i=0; iIsRegistered(EFsDirReadOne) || plugin->IsRegistered(EFsDirReadPacked) || @@ -129,6 +130,7 @@ break; } } + FsPluginManager::UnlockChain(); TPtrC8 pH((TUint8*)&h,sizeof(TInt)); TRAP(r,aRequest->WriteL(KMsgPtr3,pH)) diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfile/sf_ops.h --- a/userlibandfileserver/fileserver/sfile/sf_ops.h Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_ops.h Fri Aug 06 16:34:38 2010 +0100 @@ -135,7 +135,7 @@ { EFsAddPlugin, ESync, &TFsAddPlugin::Initialise, NULL, &TFsAddPlugin::DoRequestL }, { EFsRemovePlugin, ESync, &TFsRemovePlugin::Initialise, NULL, &TFsRemovePlugin::DoRequestL }, { EFsMountPlugin, ESync, &TFsMountPlugin::Initialise, NULL, &TFsMountPlugin::DoRequestL }, - { EFsDismountPlugin, 0, &TFsDismountPlugin::Initialise, NULL, &TFsDismountPlugin::DoRequestL }, + { EFsDismountPlugin, 0, /*PluginThrdContxt*/ &TFsDismountPlugin::Initialise, NULL, &TFsDismountPlugin::DoRequestL }, { EFsPluginName, ESync, &TFsPluginName::Initialise, NULL, &TFsPluginName::DoRequestL }, { EFsPluginOpen, ESync | EParseSrc, &TFsPluginOpen::Initialise, NULL, &TFsPluginOpen::DoRequestL }, { EFsPluginSubClose, ESync, &TFsSubClose::Initialise, NULL, &TFsSubClose::DoRequestL }, diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfile/sf_plugin.cpp --- a/userlibandfileserver/fileserver/sfile/sf_plugin.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_plugin.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -247,9 +247,9 @@ } /** - Return ETrue if the calling thread is the plugin thread + Return ETrue if the request originated from this plugin */ -TBool CFsPlugin::IsPluginThread(CFsRequest& aRequest) +TBool CFsPlugin::OriginatedFromPlugin(CFsRequest& aRequest) { if(aRequest.iOwnerPlugin == this) return ETrue; @@ -361,9 +361,11 @@ CFsPlugin* plugin = this; - FsPluginManager::NextPlugin(plugin, &msgRequest,(TBool)ETrue); + FsPluginManager::ReadLockChain(); + FsPluginManager::NextPlugin(plugin, &msgRequest); msgRequest.iCurrentPlugin = plugin; msgRequest.Dispatch(); + FsPluginManager::UnlockChain(); iThreadP->OperationLockWait(); aDes.SetLength(len); diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfile/sf_plugin.h --- a/userlibandfileserver/fileserver/sfile/sf_plugin.h Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_plugin.h Fri Aug 06 16:34:38 2010 +0100 @@ -60,8 +60,8 @@ static TInt InstallPluginFactory(CFsPluginFactory* aFactory,RLibrary aLib); static CFsPluginFactory* GetPluginFactory(const TDesC& aName); - static TInt NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aLock, TBool aCheckCurrentOperation=ETrue); - static TInt PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aLock); + static TInt NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aCheckCurrentOperation=ETrue); + static TInt PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest); static TInt InsertInPluginStack(CFsPlugin*& aPlugin,TInt aPos); static TInt IsInChain(TInt aUPos, TInt aPos,TInt aDrive, CFsPluginFactory* aPluginFactory); static CFsPlugin* FindByUniquePosition(TInt aPos); @@ -72,7 +72,8 @@ static TInt ChainCount(); static TInt Plugin(CFsPlugin*& aPlugin, TInt aPos); - static void LockChain(); + static void ReadLockChain(); + static void WriteLockChain(); static void UnlockChain(); static CFsPluginConn* CreatePluginConnL(TInt aUniquePosition, TUint aClientId); @@ -91,7 +92,7 @@ static CFsObjectCon* iPluginConns; static RPointerArray iPluginChain; - static RFastLock iChainLock; + static RReadWriteLock iChainLock; static CFsSyncMessageScheduler* iScheduler; diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp --- a/userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_plugin_man.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -21,7 +21,7 @@ CFsObjectCon* FsPluginManager::iPluginFactories = NULL; CFsObjectCon* FsPluginManager::iPluginConns = NULL; -RFastLock FsPluginManager::iChainLock; +RReadWriteLock FsPluginManager::iChainLock; RPointerArray FsPluginManager::iPluginChain; CFsSyncMessageScheduler* FsPluginManager::iScheduler = NULL; @@ -153,7 +153,7 @@ return err; } - LockChain(); + WriteLockChain(); err = InsertInPluginStack(pP,aPos); UnlockChain(); if(err != KErrNone) @@ -235,7 +235,7 @@ Transfer any outstanding requests to next/previous plugin depending on if it is post filter or not -Must be called with the plugin chain locked. +Must be called with the plugin chain write-locked. Attains plugin-thread's listlock. */ void FsPluginManager::TransferRequests(CPluginThread* aPluginThread) @@ -315,12 +315,12 @@ if(pR->IsPostOperation()) { //[set the plugin to] pass the request backwards in the chain - PrevPlugin(pR->iCurrentPlugin, &mR, EFalse); + PrevPlugin(pR->iCurrentPlugin, &mR); } else //IsPreOperations { //[set the plugin to] pass the request forwards in the chain - NextPlugin(pR->iCurrentPlugin, &mR, EFalse); + NextPlugin(pR->iCurrentPlugin, &mR); } if(pR->iCurrentPlugin) @@ -386,19 +386,18 @@ /** Find the next plugin that supports the operation +Must be called with the plugin chain (at least read-) locked. + @param aPlugin - On calling the function this may contain either NULL or the current plugin. If it is called with NULL, then we start to look for plugins from the beginning of the chain. If is is called with a plugin then we start to look after that plugin for the next one. On return, aPlugin shall contain either a plugin or NULL. -@param aLock - If this is set to ETRUE, then the function shall lock the plugin chain. - If this is set to EFALSE, then the caller of the function MUST already hold the lock. - @param aCheckCurrentOperation - Optional, if false, will return the next plugin, whether the plugin is currently registered for the current function or not. (so long as mounted on the current drive) */ -TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest,TBool aLock, TBool aCheckCurrentOperation) +TInt FsPluginManager::NextPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aCheckCurrentOperation) { if(aMsgRequest->DirectToDrive()) { @@ -410,9 +409,6 @@ TInt function = aMsgRequest->Operation()->Function(); TInt drive = aMsgRequest->DriveNumber(); - if(aLock) - LockChain(); - //the plugin chain lock must be held by this point. TInt count = iPluginChain.Count(); @@ -431,25 +427,22 @@ { aPlugin = iPluginChain[i]; - if(aLock) - UnlockChain(); return KErrNone; } } } } aPlugin = NULL; - if(aLock) - UnlockChain(); return KErrNotFound; } /** Find the next plugin that supports the operation +Must be called with the plugin chain (at least read-) locked. @see FsPluginManager::NextPlugin */ -TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest, TBool aLock) +TInt FsPluginManager::PrevPlugin(CFsPlugin*& aPlugin, CFsMessageRequest* aMsgRequest) { if(aMsgRequest->DirectToDrive() && (aMsgRequest->CurrentOperationPtr() != NULL)) { @@ -460,9 +453,6 @@ TInt start; TInt function = aMsgRequest->Operation()->Function(); TInt drive = aMsgRequest->DriveNumber(); - - if(aLock) - LockChain(); //the plugin chain lock must be held by this point. TInt count= iPluginChain.Count(); @@ -486,16 +476,12 @@ { aPlugin = iPluginChain[i]; - if(aLock) - UnlockChain(); return KErrNone; } } } } aPlugin = NULL; - if(aLock) - UnlockChain(); return KErrNotFound; } /** @@ -584,7 +570,7 @@ */ CFsPlugin* FsPluginManager::FindByUniquePosition(TInt aUniquePosition) { - LockChain(); + ReadLockChain(); CFsPlugin* plugin = NULL; TInt count= iPluginChain.Count(); for(TInt i=0;iSet(CancelPluginOp, aSession); - FsPluginManager::LockChain(); + FsPluginManager::ReadLockChain(); TInt count = FsPluginManager::ChainCount(); TInt oldCount = count; TInt i; @@ -759,7 +753,7 @@ //so hopefully this wont take too long. FsPluginManager::UnlockChain(); User::WaitForRequest(aRequest->Status()); - FsPluginManager::LockChain(); + FsPluginManager::ReadLockChain(); __ASSERT_ALWAYS(aRequest->Status().Int()==KErrNone||aRequest->Status().Int()==KErrCancel,Fault(ESessionDisconnectThread2)); count = FsPluginManager::ChainCount(); //If a plugin was removed whilst the chain was unlocked we need to make sure we don't skip any plugins diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfile/sf_plugin_ops.cpp --- a/userlibandfileserver/fileserver/sfile/sf_plugin_ops.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_plugin_ops.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -153,7 +153,7 @@ if(pF->IsDriveSupported(drive) == EFalse) return KErrNotSupported; - FsPluginManager::LockChain(); + FsPluginManager::ReadLockChain(); err = FsPluginManager::IsInChain(pF->UniquePosition(),aRequest->Message().Int2(),aRequest->Message().Int1(), pF); // plugin might have been mounted in different pos and drive. Find the right one @@ -209,7 +209,7 @@ TInt drive = aRequest->Message().Int1(); - FsPluginManager::LockChain(); + FsPluginManager::WriteLockChain(); TInt err = FsPluginManager::IsInChain(pF->UniquePosition(),aRequest->Message().Int2(),drive, pF); if(err >= 0) @@ -219,11 +219,8 @@ err = FsPluginManager::Plugin(plugin, pos); if(err == KErrNone) { - if(aRequest->iCurrentPlugin == plugin) - { - FsPluginManager::DismountPlugin(*pF,pos); - aRequest->SetScratchValue(0); - } + FsPluginManager::DismountPlugin(*pF,pos); + aRequest->SetScratchValue(0); } } FsPluginManager::UnlockChain(); @@ -250,7 +247,7 @@ TInt TFsPluginName::DoRequestL(CFsRequest* aRequest) { CFsPlugin* plugin=NULL; - FsPluginManager::LockChain(); + FsPluginManager::ReadLockChain(); TInt err = FsPluginManager::Plugin(plugin, aRequest->Message().Int2()); if(err != KErrNone) //should be ok but just in case { diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfile/sf_request.cpp --- a/userlibandfileserver/fileserver/sfile/sf_request.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfile/sf_request.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -974,7 +974,7 @@ // { TInt err = KErrNone; - if(!iCurrentPlugin->IsPluginThread(*this)) + if(!iCurrentPlugin->OriginatedFromPlugin(*this)) { // The request hasn't come from this plugin so it's safe to dispatch TFsPluginRequest request(this); @@ -997,14 +997,17 @@ // Find the previous plugin in the chain and dispatch // - If no more plugins are interested in this message, then complete - FsPluginManager::PrevPlugin(iCurrentPlugin, this, ETrue); + FsPluginManager::ReadLockChain(); + FsPluginManager::PrevPlugin(iCurrentPlugin, this); if(iCurrentPlugin == NULL) { + FsPluginManager::UnlockChain(); Complete(GetError()); return; } Dispatch(); + FsPluginManager::UnlockChain(); return; } @@ -1015,7 +1018,7 @@ // { TInt err = KErrNone; - if(!iCurrentPlugin->IsPluginThread(*this)) + if(!iCurrentPlugin->OriginatedFromPlugin(*this)) { // The request hasn't come from this plugin so it's safe to dispatch TFsPluginRequest request(this); @@ -1024,7 +1027,7 @@ if((iOperation->Function() == EFsDismountPlugin) && (err != KErrPermissionDenied)) { - TRAP(leaveValue, err = iOperation->DoRequestL(this)); + err = KErrNone; } if(leaveValue != KErrNone) @@ -1042,10 +1045,12 @@ // Find the next plugin in the chain and dispatch // - If no more plugins are interested in this message, // then Dispatch() will process the request in drive/main thread context. - FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue); + FsPluginManager::ReadLockChain(); + FsPluginManager::NextPlugin(iCurrentPlugin, this); if(iCurrentPlugin && IsPostOperation()) SetPostOperation(EFalse); Dispatch(); + FsPluginManager::UnlockChain(); return; } // KErrCompletion may be returned by the plugin to @@ -1054,18 +1059,21 @@ { // Find the previous plugin in the chain and dispatch // - If no more plugins are interested in this message, then complete - FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue); + FsPluginManager::ReadLockChain(); + FsPluginManager::PrevPlugin(iCurrentPlugin, this); if(iCurrentPlugin != NULL) { SetPostOperation(ETrue); err = KErrNone; Dispatch(); + FsPluginManager::UnlockChain(); return; } else { err = KErrNone; } + FsPluginManager::UnlockChain(); } Complete(err); @@ -1124,13 +1132,18 @@ iCurrentPlugin = NULL; if (PostInterceptEnabled()) { - FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue); - if(iCurrentPlugin && !iCurrentPlugin->IsPluginThread(*this)) + FsPluginManager::ReadLockChain(); + FsPluginManager::PrevPlugin(iCurrentPlugin, this); + if(iCurrentPlugin && !iCurrentPlugin->OriginatedFromPlugin(*this)) { SetPostOperation(ETrue); if (DispatchToPlugin()) + { + FsPluginManager::UnlockChain(); return; + } } + FsPluginManager::UnlockChain(); } Complete(GetError()); @@ -1409,13 +1422,16 @@ iCurrentPlugin = NULL; if (PostInterceptEnabled()) { - FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue); - if(iCurrentPlugin && !iCurrentPlugin->IsPluginThread(*this)) + FsPluginManager::ReadLockChain(); + FsPluginManager::PrevPlugin(iCurrentPlugin, this); + if(iCurrentPlugin && !iCurrentPlugin->OriginatedFromPlugin(*this)) { SetPostOperation(ETrue); Dispatch(); + FsPluginManager::UnlockChain(); return r; // EReqActionComplete } + FsPluginManager::UnlockChain(); } Complete(KErrNone); @@ -1443,6 +1459,7 @@ __THRD_PRINT1(_L("CFsMessageRequest::Dispatch() req %08x"), this); TInt r = KErrNone; + TBool pluginChainLocked = EFalse; if (iReqState == EReqStateInitialise && aInitialise) { @@ -1462,16 +1479,18 @@ } if(!IsPluginSpecific() && (iOwnerPlugin == NULL)) { + FsPluginManager::ReadLockChain(); // Unlocked in DispatchToPlugin + pluginChainLocked = ETrue; iCurrentPlugin = NULL; iClientThreadId = 0; - FsPluginManager::NextPlugin(iCurrentPlugin, this, (TBool)ETrue); + FsPluginManager::NextPlugin(iCurrentPlugin, this); // find out whether there is a plugin registered to post intercept this message CFsPlugin* postInterceptPlugin = NULL; if (iCurrentPlugin == NULL) - FsPluginManager::PrevPlugin(postInterceptPlugin, this, (TBool)ETrue); + FsPluginManager::PrevPlugin(postInterceptPlugin, this); - // Save the client's thread Id for subsequent testing by CFsPlugin::IsPluginThread() - doing so on the fly + // Save the client's thread Id for subsequent testing by CFsPlugin::OriginatedFromPlugin() - doing so on the fly // is risky because some messages are completed early in which case Message().Client() will result in a panic if ((iCurrentPlugin || postInterceptPlugin) && Message().Handle() != NULL && Message().Handle() != KLocalMessageHandle) { @@ -1490,16 +1509,23 @@ __PLUGIN_PRINT1(_L("PLUGIN: CFsMessageRequest %x dispatched to plugin (async)"), this); // The request has been delivered to the plugin thread // - leave the main thread now and await asynchronous completion + if(pluginChainLocked) + FsPluginManager::UnlockChain(); return; } + //DispatchToPlugin didn't (deliver then unlock) so make sure we unlock here. + if(pluginChainLocked) + FsPluginManager::UnlockChain(); // Is there a PostInitialise function ? if (iReqState == EReqStatePostInitialise && aInitialise && r == KErrNone) { TInt r = PostInitialise(); if (r == EReqActionComplete) + { return; + } else if (r == EReqActionBusy) // request postponed ? SetState(EReqStatePostInitialise); // reinitialize when request is next processed } @@ -1559,6 +1585,7 @@ // // Common route: Receive -> Process -> Dispatch -> DispatchToPlugin // +// (Is called with FsPluginManager ReadLocked) { TInt drivenumber = DriveNumber(); if(iCurrentPlugin) @@ -1572,16 +1599,16 @@ iCurrentPlugin = NULL; } - while(iCurrentPlugin && iCurrentPlugin->IsPluginThread(*this)) + while(iCurrentPlugin && iCurrentPlugin->OriginatedFromPlugin(*this)) { // Skip the current plugin if the request originated from the plugin if(IsPostOperation()) { - FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue); + FsPluginManager::PrevPlugin(iCurrentPlugin, this); } else { - FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue); + FsPluginManager::NextPlugin(iCurrentPlugin, this); } } @@ -1611,7 +1638,7 @@ // - Pass the message on to the next plugin if(FsFunction() != EFsPluginOpen) { - FsPluginManager::NextPlugin(iCurrentPlugin, this,(TBool)ETrue); + FsPluginManager::NextPlugin(iCurrentPlugin, this); continue; } else // FsFunction == EFsPluginOpen @@ -1619,7 +1646,6 @@ /* * PluginOpen requests should not be passed down the plugin stack. * - */ iCurrentPlugin = NULL; continue; @@ -1630,7 +1656,7 @@ // The plugin has processed synchronously (case 2) // - Pass the message back up the stack SetPostOperation(ETrue); - FsPluginManager::PrevPlugin(iCurrentPlugin, this,(TBool)ETrue); + FsPluginManager::PrevPlugin(iCurrentPlugin, this); continue; } _LIT(KPanic,"Panic: F32-BAD-PLUGIN-ERROR"); @@ -1652,13 +1678,17 @@ } } + /* + * Special case- DismountPlugin runs in the context of the plugin thread + */ if(iOperation->Function() == EFsDismountPlugin) { // Don't pass plugin dismounts to the drive thread + FsPluginManager::UnlockChain(); Process(); + FsPluginManager::ReadLockChain(); //inverted unlock/lock to get around dismount plugin being a special case return(ETrue); } - return EFalse; } diff -r 75252ea6123b -r c7a0ce20c48c userlibandfileserver/fileserver/sfsrv/cl_scan.cpp --- a/userlibandfileserver/fileserver/sfsrv/cl_scan.cpp Mon Jul 26 10:52:56 2010 +0100 +++ b/userlibandfileserver/fileserver/sfsrv/cl_scan.cpp Fri Aug 06 16:34:38 2010 +0100 @@ -411,7 +411,7 @@ TInt r; aDirEntries=NULL; - if(iStack && iStack->IsEmpty()) + if(iStack->IsEmpty()) return; CDirList* list=iStack->Peek();