commsfwsupport/commselements/meshmachine/src/mm_activities.cpp
changeset 30 df67dc5d759e
parent 22 592244873960
child 32 d2396c80c344
--- 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<TInt SIZE>
+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<TInt SIZE>
+TBitmap<SIZE>::TBitmap()
+{
+    for (TInt i = 0 ; i < iCount ; ++i)
+        {
+        iBits[i] = 0;
+        }
+}
+
+template<TInt SIZE>
+void TBitmap<SIZE>::SetBit(TUint aBitNum)
+    {
+    const TInt index = aBitNum / iSize;
+	__ASSERT_ALWAYS(index < iCount,User::Panic(KMMActivityPanic,EPanicOutOfBounds));
+
+    iBits[index] |= 1 << (aBitNum & iSizeMask);
+    }
+
+template<TInt SIZE>
+TInt TBitmap<SIZE>::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<CNodeActivityBase>& activities = aNode.Activities();
-	RArray<TInt> 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;
 	}