commsfwsupport/commselements/meshmachine/src/mm_node.cpp
changeset 71 c5f26e3de961
parent 65 41cc8e7ff496
child 79 cf589eb1e31e
equal deleted inserted replaced
65:41cc8e7ff496 71:c5f26e3de961
    34 
    34 
    35 using namespace Messages;
    35 using namespace Messages;
    36 using namespace MeshMachine;
    36 using namespace MeshMachine;
    37 using namespace NetStateMachine;
    37 using namespace NetStateMachine;
    38 
    38 
    39 //By default we reserve the space generously, to fit even a synchronised activity preallocating space for up to 4 originators.
       
    40 //Any node, hosting specific activities that may need the preallocation mechanism can choose a more optimal amounts.
       
    41 //For efficiency reasons it is strongly recommended that any node (or family of nodes) is revisited and an optimal
       
    42 //amount of space is specified (could be specified in the base class for those nodes or in every type of node separatelly).
       
    43 static const TUint KDefaultMaxPreallocatedActivityCount = 1;
       
    44 static const TUint KMaxPreallocatedActivitySize = sizeof(CNodeRetryParallelActivity) + sizeof(APreallocatedOriginators<4>);
       
    45 static const TUint KDefaultPreallocatedActivityBufferSize = KDefaultMaxPreallocatedActivityCount * KMaxPreallocatedActivitySize;
       
    46 
       
    47 //-=========================================================
    39 //-=========================================================
    48 //
    40 //
    49 //Panics
    41 //Panics
    50 //
    42 //
    51 //-=========================================================
    43 //-=========================================================
   122     //Preallocate space for preallocated activities
   114     //Preallocate space for preallocated activities
   123     if (aSize==KUseDefaultPreallocatedSize)
   115     if (aSize==KUseDefaultPreallocatedSize)
   124     	{
   116     	{
   125     	//Nodes will usually use the default parameter (-1) and rely on KDefaultPreallocatedActivityBufferSize.
   117     	//Nodes will usually use the default parameter (-1) and rely on KDefaultPreallocatedActivityBufferSize.
   126     	//We do not use KDefaultPreallocatedActivityBufferSize as the default argument to avoid publishing of
   118     	//We do not use KDefaultPreallocatedActivityBufferSize as the default argument to avoid publishing of
   127     	//this constant or KDefaultMaxPreallocatedActivityCount/KMaxPreallocatedActivitySize (either can be
   119     	//this constant or KDefaultMaxPreallocatedActivityCount/KDefaultMaxPreallocatedActivitySize (either can be
   128     	//freely changed at any time).
   120     	//freely changed at any time).
   129     	aSize = KDefaultPreallocatedActivityBufferSize;
   121     	aSize = KDefaultPreallocatedActivityBufferSize;
   130     	}
   122     	}
   131 
   123 
   132     if (aSize>0)
   124     if (aSize>0)
   673 	__ASSERT_DEBUG(aSize>0, User::Panic(KSpecAssert_ElemMeshMachNodC, 4));
   665 	__ASSERT_DEBUG(aSize>0, User::Panic(KSpecAssert_ElemMeshMachNodC, 4));
   674 	// Reserve extra space for the maximum number of preallocated activities supported by this node
   666 	// Reserve extra space for the maximum number of preallocated activities supported by this node
   675 	// to ensure they can be added to the activities list while the system is out of memory.  We also
   667 	// to ensure they can be added to the activities list while the system is out of memory.  We also
   676 	// add enough space for extra data strucures to store the free list - the caller cannot reserve this
   668 	// add enough space for extra data strucures to store the free list - the caller cannot reserve this
   677 	// space without knowledge of the preallocation implementation so we do this ourselves.
   669 	// space without knowledge of the preallocation implementation so we do this ourselves.
   678 	TUint maxPreallocatedActivities = aSize / KMaxPreallocatedActivitySize;
   670 	TUint maxPreallocatedActivities = aSize / KDefaultMaxPreallocatedActivitySize;
   679 	iActivities.ReserveL(iActivities.Count() + maxPreallocatedActivities);
   671 	iActivities.ReserveL(iActivities.Count() + maxPreallocatedActivities);
   680 	__ASSERT_DEBUG(iPreallocatedSpace==NULL, User::Panic(KSpecAssert_ElemMeshMachNodC, 5));
   672 	__ASSERT_DEBUG(iPreallocatedSpace==NULL, User::Panic(KSpecAssert_ElemMeshMachNodC, 5));
   681     iPreallocatedSpace = User::AllocZL(aSize + sizeof(TUint) + maxPreallocatedActivities * sizeof(TAny*));
   673     iPreallocatedSpace = User::AllocZL(aSize + sizeof(TUint) + maxPreallocatedActivities * sizeof(TAny*));
   682     *reinterpret_cast<TUint*>(iPreallocatedSpace) = maxPreallocatedActivities;
   674     *reinterpret_cast<TUint*>(iPreallocatedSpace) = maxPreallocatedActivities;
   683 	}
   675 	}
   695 TAny* AMMNodeBase::GetPreallocatedCell(TUint aIndex) const
   687 TAny* AMMNodeBase::GetPreallocatedCell(TUint aIndex) const
   696 	{
   688 	{
   697 	// Calculate the offset of the start of the preallocated space after the free list.
   689 	// Calculate the offset of the start of the preallocated space after the free list.
   698 	TUint8* bufferStart = reinterpret_cast<TUint8*>(iPreallocatedSpace) + sizeof(TUint*) + MaxPreallocatedActivityCount() * sizeof(TAny*);
   690 	TUint8* bufferStart = reinterpret_cast<TUint8*>(iPreallocatedSpace) + sizeof(TUint*) + MaxPreallocatedActivityCount() * sizeof(TAny*);
   699 
   691 
   700 	return bufferStart + aIndex * KMaxPreallocatedActivitySize;
   692 	return bufferStart + aIndex * KDefaultMaxPreallocatedActivitySize;
   701 	}
   693 	}
   702 
   694 
   703 TAny* AMMNodeBase::BorrowPreallocatedSpace(TUint aSize)
   695 TAny* AMMNodeBase::BorrowPreallocatedSpace(TUint aSize)
   704 	{
   696 	{
   705 	MESH_LOG((KMeshMachineSubTag, _L8("AMMNodeBase %08x:\tBorrowPreallocatedSpace (%d)"),this,aSize));
   697 	MESH_LOG((KMeshMachineSubTag, _L8("AMMNodeBase %08x:\tBorrowPreallocatedSpace (%d)"),this,aSize));
   706 
   698 
   707 	__ASSERT_ALWAYS(iPreallocatedSpace, User::Panic(KMMNodePanic, EPanicPreallocatedSpaceAlreadyTaken));
   699 	__ASSERT_ALWAYS(iPreallocatedSpace, User::Panic(KMMNodePanic, EPanicPreallocatedSpaceAlreadyTaken));
   708 	__ASSERT_ALWAYS(aSize <= KMaxPreallocatedActivitySize, User::Panic(KMMNodePanic, EPanicPreallocatedSpaceAlreadyTaken));
   700 	__ASSERT_ALWAYS(aSize <= KDefaultMaxPreallocatedActivitySize, User::Panic(KMMNodePanic, EPanicPreallocatedSpaceAlreadyTaken));
   709 
   701 
   710 	#ifdef SYMBIAN_TRACE_ENABLE
   702 	#ifdef SYMBIAN_TRACE_ENABLE
   711 		if(!iPreallocatedSpace)
   703 		if(!iPreallocatedSpace)
   712 			{
   704 			{
   713 			MESH_LOG((KMeshMachineSubTag, _L8("ERROR AMMNodeBase %08x:\tBorrowPreallocatedSpace - Preallocated space has not been allocated!"), this));
   705 			MESH_LOG((KMeshMachineSubTag, _L8("ERROR AMMNodeBase %08x:\tBorrowPreallocatedSpace - Preallocated space has not been allocated!"), this));
   714 			}
   706 			}
   715 		if(aSize>KMaxPreallocatedActivitySize)
   707 		if(aSize>KDefaultMaxPreallocatedActivitySize)
   716 			{
   708 			{
   717 			MESH_LOG((KMeshMachineSubTag, _L8("ERROR AMMNodeBase %08x:\tBorrowPreallocatedSpace - Size exceeds maximum limit for a single allocation (%d was requested but only %d is available)!"), this, aSize, KMaxPreallocatedActivitySize));
   709 			MESH_LOG((KMeshMachineSubTag, _L8("ERROR AMMNodeBase %08x:\tBorrowPreallocatedSpace - Size exceeds maximum limit for a single allocation (%d was requested but only %d is available)!"), this, aSize, KDefaultMaxPreallocatedActivitySize));
   718 			}
   710 			}
   719 	#endif
   711 	#endif
   720 
   712 
   721 	TAny* ptr = NULL;
   713 	TAny* ptr = NULL;
   722 	TUint maxPreallocatedActivities = MaxPreallocatedActivityCount();
   714 	TUint maxPreallocatedActivities = MaxPreallocatedActivityCount();
   730 			{
   722 			{
   731 			// This cell is now allocated to the calling activity.
   723 			// This cell is now allocated to the calling activity.
   732 			ptr = freeList[index] = GetPreallocatedCell(index);
   724 			ptr = freeList[index] = GetPreallocatedCell(index);
   733 
   725 
   734 			// Zero the cell so that any object allocated will have the expected initial zero fill.
   726 			// Zero the cell so that any object allocated will have the expected initial zero fill.
   735 			memset(ptr, 0, KMaxPreallocatedActivitySize);
   727 			memset(ptr, 0, KDefaultMaxPreallocatedActivitySize);
   736 
   728 
   737 			break;
   729 			break;
   738 			}
   730 			}
   739 		}
   731 		}
   740 
   732