diff -r a365cb779476 -r cf589eb1e31e commsfwsupport/commselements/commsfw/src/cftransport.cpp --- a/commsfwsupport/commselements/commsfw/src/cftransport.cpp Fri Sep 17 08:36:26 2010 +0300 +++ b/commsfwsupport/commselements/commsfw/src/cftransport.cpp Mon Oct 04 02:21:43 2010 +0300 @@ -225,9 +225,9 @@ public: enum { - KSelfSenderInitialQueueLength = 40, /** Initial size of self-sender queue (double what testing has observed) */ - KSelfSenderQueueGrowthStep = 40, /** Increment of self-sender queue size when full. PostMessage() functions panic if growth - required and fails; to minimise this risk ensure initial size adequate for all likely cases */ + KSelfSenderInitialQueueLength = 20, /** Initial size of self-sender queue */ + KSelfSenderQueuePreAllocationGrowthStep = 20, /** Additionl space to reserve each time we pre-allocate some queue space to avoind too much re-allocation */ + KSelfSenderQueueGrowthStep = 20 /** Increment of self-sender queue size when full. PostMessage() functions panic if growth required and fails */ }; static CTransportSelfSender* NewL(MMessageDispatcher& aDispatcher, TWorkerId aSelfId); @@ -264,6 +264,8 @@ { return EFalse; } + + void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages); ~CTransportSelfSender(); protected: @@ -277,7 +279,7 @@ TInt DoPostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage); TInt ProcessMessage(TCFMessage2& aMessage, TInt aFirstDispatchLeaveReason); void MaybeTriggerReceipt(); - TInt ResizeQueue(TInt aAdditionalChips); + void ResizeQueueL(TInt aAdditionalChips); private: TChipReceiver iReceiver; CCirBuf* iBuf; @@ -311,29 +313,43 @@ CleanupStack::Pop(self); return self; } +/* + * Preemptively allocate self sender queue length, given by aMinUndeliveredMessages. + * Note the current logic for queue enlargement is rather coarse, preferring linear growth by a fixed amount. + * A better approach would have been to implement a logarithmic increase for the queue length, which would have saved a bit more memory when the + */ +void CTransportSelfSender::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages) + { + TInt currentLength = iBuf->Length(); + if (aMinUndeliveredMessages > currentLength) + { + TInt resizeBy = aMinUndeliveredMessages - currentLength; + __CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::PreallocateQueueSpaceL(%d) Trying to enlarge queue from %d to %d chips"), aMinUndeliveredMessages, currentLength, currentLength + resizeBy + KSelfSenderQueuePreAllocationGrowthStep )); + ResizeQueueL(resizeBy + KSelfSenderQueuePreAllocationGrowthStep); + __CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::PreallocateQueueSpaceL queue enlargement successful") )); + } + } -TInt CTransportSelfSender::ResizeQueue(TInt aAdditionalChips) +void CTransportSelfSender::ResizeQueueL(TInt aAdditionalChips) { + __CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("CTransportSelfSender::ResizeQueueL(%d)"), aAdditionalChips )); + TInt newLen = iBuf->Length() + aAdditionalChips; __ASSERT_ALWAYS(newLen > iBuf->Count(), Panic(ECFInvalidQueueSize)); + + if (iBuf->Count() == 0) + { + iBuf->SetLengthL(newLen); + return; + } // Create a new queue of the requisite size, copy the elements, and swap for the original // (there's no safe way to resize in-place). - CCirBuf* newBuf = new CCirBuf; - if(newBuf == NULL) - { - __CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("ERROR: CTransportSelfSender::ResizeQueue() unable to enlarge queue from %d chips to %d chips because error -4 occured"), iBuf->Length(), newLen )); - - return KErrNoMemory; - } - - TRAPD(ret, newBuf->SetLengthL(newLen)); - if(ret != KErrNone) - { - __CFLOG_VAR(( KLogCommsFw, KLogFwTransport, _L8("ERROR: CTransportSelfSender::ResizeQueue() unable to enlarge queue from %d chips to %d chips because error %d occured"), iBuf->Length(), newLen, ret )); - - return ret; - } + CCirBuf* newBuf = new (ELeave) CCirBuf; + CleanupStack::PushL(newBuf); + newBuf->SetLengthL(newLen); + CleanupStack::Pop(newBuf); + TCFMessage entry; while(iBuf->Remove(&entry)) { @@ -341,7 +357,6 @@ } delete iBuf; iBuf = newBuf; - return KErrNone; } void CTransportSelfSender::PostMessage(const TCFMessage& aMessage) @@ -349,21 +364,10 @@ TInt ret = DoPostMessage(aMessage); if(ret != KErrNone) { - ResizeQueue(KSelfSenderQueueGrowthStep); + TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep)); ret = DoPostMessage(aMessage); - //For the benefit of OOM testing as we currently do it (only the sequential failure model) - //we attempt to resize the queue for the second time. - //In real scenarios this approach has very limited or no value as the OOM conditions do rarely - //resemble the ones of our sequential failure OOM testing. - //Therefore it would probably make sense to configure out the code for UREL and only keep - //it for _DEBUG. - if(ret != KErrNone) - { - ResizeQueue(KSelfSenderQueueGrowthStep); - ret = DoPostMessage(aMessage); - __ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure)); // true, even though peer is us... - } } + __ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure)); // true, even though peer is us... } void CTransportSelfSender::PostMessage(const TRuntimeCtxId& aPostFrom, const TRuntimeCtxId& aPostTo, const TDesC8& aMessage) @@ -372,21 +376,10 @@ TInt ret = DoPostMessage(aPostFrom, aPostTo, aMessage); if(ret != KErrNone) { - ResizeQueue(KSelfSenderQueueGrowthStep); + TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep)); ret = DoPostMessage(aPostFrom, aPostTo, aMessage); - //For the benefit of OOM testing as we currently do it (only the sequential failure model) - //we attempt to resize the queue for the second time. - //In real scenarios this approach has very limited or no value as the OOM conditions do rarely - //resemble the ones of our sequential failure OOM testing. - //Therefore it would probably make sense to configure out the code for UREL and only keep - //it for _DEBUG. - if(ret != KErrNone) - { - ResizeQueue(KSelfSenderQueueGrowthStep); - ret = DoPostMessage(aPostFrom, aPostTo, aMessage); - __ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure)); // true, even though peer is us... - } } + __ASSERT_ALWAYS(ret == KErrNone, Panic(ECFTransPeerDrainFailure)); // true, even though peer is us... } @@ -453,7 +446,7 @@ } else { - ResizeQueue(KSelfSenderQueueGrowthStep); + TRAP_IGNORE(ResizeQueueL(KSelfSenderQueueGrowthStep)); err = DoPostMessage(*msgPtr); if(err != KErrNone) { @@ -961,6 +954,8 @@ { return GetSenderMandatory(aPeerId)->IsDropTransportPending(); } + + void PreallocateQueueSpaceL(TInt aMinUndeliveredMessages); void RunL(); // for deleting chippers posted to death row private: @@ -1410,6 +1405,15 @@ } } +void CCommsTransportImpl::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages) + { +#ifndef SYMBIAN_NETWORKING_INTERTHREAD_TRANSPORT_ONLY + iSelfSender->PreallocateQueueSpaceL(aMinUndeliveredMessages); +#else + (void)aSize; // Do nothing +#endif + } + // EXPORT_C CCommsTransport* CCommsTransport::NewL(MWorkerThreadRegister& aThreadRegister, const CMetaDataVirtualCtorInPlace* aVirtCtor, CCFTransportHooks* /*aHooksWalker*/) @@ -1538,6 +1542,10 @@ return iImpl->IsDropTransportPending(aPeerId); } +EXPORT_C void CCommsTransport::PreallocateQueueSpaceL(TInt aMinUndeliveredMessages) + { + iImpl->PreallocateQueueSpaceL(aMinUndeliveredMessages); + } //