diff -r e53adc4c49de -r df67dc5d759e commsfwsupport/commselements/meshmachine/src/mm_activities.cpp --- a/commsfwsupport/commselements/meshmachine/src/mm_activities.cpp Mon May 03 13:39:24 2010 +0300 +++ b/commsfwsupport/commselements/meshmachine/src/mm_activities.cpp Fri May 14 14:12:43 2010 +0100 @@ -45,7 +45,9 @@ enum { EPanicCorruptedContext = 1, - EPanicNoPreallocatedSpace = 2 + EPanicNoPreallocatedSpace = 2, + EPanicOutOfActivities = 3, + EPanicOutOfBounds }; //-========================================================= @@ -352,8 +354,8 @@ if (PostToOriginator(iOriginators[n], aMessage)) { ++msgSendCount; - iOriginators[n].Peer().SetFlags(aFlagsToSet); - iOriginators[n].Peer().ClearFlags(aFlagsToClear); + iOriginators[n].SetFlags(aFlagsToSet); + iOriginators[n].ClearFlags(aFlagsToClear); }; } return msgSendCount; @@ -461,20 +463,80 @@ aInterface = this; } +// BitMap utility used only by CNodeParallelActivityBase::GetNextActivityCount +template +class TBitmap { +public: + static const TInt iSize = sizeof(TUint32) * 8; + static const TUint32 iSizeMask = iSize - 1; + static const TUint32 iFull = ~0; + static const TInt iCount = (SIZE + iSizeMask) / iSize; + TBitmap(); + void SetBit(TUint aBitNum); + TInt GetFreeBit() const; + +private: + TUint32 iBits[iCount]; +}; + +template +TBitmap::TBitmap() +{ + for (TInt i = 0 ; i < iCount ; ++i) + { + iBits[i] = 0; + } +} + +template +void TBitmap::SetBit(TUint aBitNum) + { + const TInt index = aBitNum / iSize; + __ASSERT_ALWAYS(index < iCount,User::Panic(KMMActivityPanic,EPanicOutOfBounds)); + + iBits[index] |= 1 << (aBitNum & iSizeMask); + } + +template +TInt TBitmap::GetFreeBit() const + { + for (TInt i = 0 ; i < iCount ; ++i) + { + const TUint32 bits = iBits[i]; + if (bits != iFull) + { + // Bitmap represents list of activity IDs. Activity ID 1 is a reserved value. + // In order to mirror this fact the first bit of the bitmap is also always reserved + TUint32 mask = 2; + for (TInt bitIndex = 1 ; bitIndex < iSize ; ++bitIndex) + { + if ((bits & mask) == 0) + { + return (i * iSize) + bitIndex; + } + mask <<= 1; + } + } + } + return KErrNotFound; + } + + //-========================================================= // //CNodeParallelActivityBase // //-========================================================= -// For custom activities to implement NewL -EXPORT_C TUint CNodeParallelActivityBase::GetNextActivityCountL( const TNodeActivity& aActivitySig, const AMMNodeBase& aNode ) + + +// For custom activities to implement New +EXPORT_C TUint CNodeParallelActivityBase::GetNextActivityCount( const TNodeActivity& aActivitySig, const AMMNodeBase& aNode ) { - TInt c = 1, i = 0; + TInt c = 1; const RPointerArray& activities = aNode.Activities(); - RArray activityids; - CleanupClosePushL(activityids); - + + TBitmap<256> activityids; // collect the currently used ids for (TInt i = 0; i < activities.Count(); i++) { @@ -482,23 +544,12 @@ if ((id&0xff) == aActivitySig.iId) { TInt8 uniqueid = id >> 8; - activityids.InsertInOrderL(uniqueid); + activityids.SetBit(uniqueid); } } - - // find first available. - while (i < activityids.Count() - && activityids[i] == c) - { - ++i; - ++c; - } - CleanupStack::PopAndDestroy(&activityids); - - if(c > KActivityParallelRangeMax>>8) - { - User::Leave(KErrInUse); - } + c = activityids.GetFreeBit(); + + __ASSERT_ALWAYS(c>=0,User::Panic(KMMActivityPanic,EPanicOutOfActivities)); return c; }