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 |