Skip to content
Snippets Groups Projects
Commit 769f0fb2 authored by Stefen Guzik's avatar Stefen Guzik
Browse files

Memory fix

parent 592008ee
No related branches found
No related tags found
No related merge requests found
......@@ -73,16 +73,13 @@ class Pool
// Constructor
Pool(const unsigned _blockSize = 128)
: tailBlock(0), tailElement(0), blockSize(_blockSize)
: tailBlock(0), tailElement(0), blockSize(_blockSize), numUsedElement(0)
{ }
// Destructor
~Pool(){
while(tailBlock) {
Block<T> *const block = tailBlock;
tailBlock = block->prev;
delete block;
}
~Pool()
{
delete_all_blocks();
}
// Get an element
......@@ -91,6 +88,7 @@ class Pool
if(!tailElement) create_block();
void *const rval = tailElement;
tailElement = static_cast<T*>(tailElement->get_pool_prev());
++numUsedElement;
return rval;
}
......@@ -99,6 +97,13 @@ class Pool
{
elem->set_pool_prev(tailElement);
tailElement = elem;
--numUsedElement;
}
// Free memory used by the pool
void free_memory()
{
if(numUsedElement == 0) delete_all_blocks();
}
private:
......@@ -107,6 +112,7 @@ class Pool
Block<T> *tailBlock;
T *tailElement;
unsigned blockSize;
unsigned numUsedElement;
// Create a new block
void create_block()
......@@ -121,6 +127,16 @@ class Pool
}
}
// Delete all blocks
void delete_all_blocks()
{
while(tailBlock) {
Block<T> *const block = tailBlock;
tailBlock = block->prev;
delete block;
}
}
// Copy and assignment are not permitted
Pool(const Pool&);
Pool &operator=(const Pool&);
......@@ -200,6 +216,7 @@ class Block
* - No per-object data is stored as per normal requirements for allocators.
* Critical OpenMP sections are defined since multiple threads can access
* the allocator.
* - If set_offsets is to be used, T must have a default constructor.
*
*============================================================================*/
......@@ -292,6 +309,15 @@ class FaceAllocator
offset16 = f16.get_offset();
}
// Release memory used by the pools
static void free_pool_memory()
{
face2Pool.free_memory();
face6Pool.free_memory();
face8Pool.free_memory();
face16Pool.free_memory();
}
// Allocate the array
void allocate(const unsigned short nCapacity, T *&faces)
{
......@@ -503,6 +529,10 @@ ptrdiff_t FaceAllocator<T>::offset16 = 0;
* - The only way to add elements is by 'push_back'
* - Erasing may reorder the elements.
* - T must only contain primitive types
* - init_memory() should be called before constructing any class
* FaceVector<T> and release_memory() should be called after all classes
* FaceVector<T> have been destroyed. These routines explictly manage
* memory used by pools in the allocator.
*
*============================================================================*/
......@@ -551,9 +581,17 @@ class FaceVector : public FaceAllocator<T>
// Vector size and capacity
unsigned size() const { return _size; }
unsigned capacity() const { return _capacity; }
// Memory managment
// Init sets offsets to ensure pointers can be recovered. It should be called
// once before using FaceVector<T>
static void init_memory() { FaceAllocator<T>::set_offsets(); }
// This releases memory used by the pools if no pool elements are in use. It
// should be called after use of FaceVector<T> is finished and all
// FaceVector<T> classes have been destroyed.
static void release_memory() { FaceAllocator<T>::free_pool_memory(); }
private:
// Data
......
......@@ -278,12 +278,16 @@ int GModel::writeCGNS(const std::string &name, const int zoneDefinition,
switch(meshDim) {
case 2:
MZone<2>::preInit();
write_CGNS_zones<2>(*this, zoneDefinition, options, scalingFactor,
vectorDim, groups[face], cgIndexFile, cgIndexBase);
MZone<2>::postDestroy();
break;
case 3:
MZone<3>::preInit();
write_CGNS_zones<3>(*this, zoneDefinition, options, scalingFactor,
vectorDim, groups[region], cgIndexFile, cgIndexBase);
MZone<3>::postDestroy();
break;
}
......
......@@ -310,6 +310,9 @@ template <> struct FaceTr<MFace> {
* =====
*
* - explicitly instantiated in 'MZone.cpp'
* - this class uses some explicit memory management. Call preInit() before
* constructing any class MZone and postDestroy() after all MZone classes
* have been destroyed.
*
******************************************************************************/
......@@ -411,6 +414,16 @@ class MZone
return numElemType;
}
//--Memory management
static void preInit()
{
CCon::FaceVector<typename BoFaceMap::const_iterator>::init_memory();
}
static void postDestroy()
{
CCon::FaceVector<typename BoFaceMap::const_iterator>::release_memory();
}
/*==============================================================================
* Member data
......
......@@ -892,6 +892,29 @@ int MZoneBoundary<DIM>::exteriorBoundaryVertices
}
/*******************************************************************************
*
* Specialization of constructor
* MZoneBoundary<DIM>::GlobalVertexData<FaceT>::FaceDataB::FaceDataB()
* - Note that these dummy constructors are only required by
* FaceAllocator<T>::set_offsets()
* [with T = MZoneBoundary<DIM>::GlobalVertexData<FaceT>::FaceDataB]
*
******************************************************************************/
template<>
template<>
MZoneBoundary<2>::GlobalVertexData<MEdge>::FaceDataB::FaceDataB()
: face(0, 0)
{ }
template<>
template<>
MZoneBoundary<3>::GlobalVertexData<MFace>::FaceDataB::FaceDataB()
: face(0, 0, 0)
{ }
/*******************************************************************************
*
* Explicit instantiations of class MZoneBoundary
......
......@@ -167,6 +167,9 @@ struct ZoneBoVecSort
* =====
*
* - explicitly instantiated in 'MZoneBoundary.cpp'
* - this class uses some explicit memory management. Call preInit() before
* constructing any class MZoneBoundary and postDestroy() after all
* MZoneBoundary classes have been destroyed.
*
******************************************************************************/
......@@ -203,6 +206,11 @@ class MZoneBoundary
parentFace(bFMapIt->second.parentFace),
faceIndex(bFMapIt->second.faceIndex), zoneIndex(_zoneIndex)
{ }
private:
// The default constructor is required by 'set_offsets()' in
// class 'FaceAllocator'. This is invoked by preInit() below.
FaceDataB();
friend class CCon::FaceAllocator<FaceDataB>;
};
struct ZoneData
{
......@@ -211,6 +219,11 @@ class MZoneBoundary
ZoneData(const int _vertexIndex, const int _zoneIndex)
: vertexIndex(_vertexIndex), zoneIndex(_zoneIndex)
{ }
private:
// The default constructor is required by 'set_offsets()' in
// class 'FaceAllocator'. This is invoked by preInit() below.
ZoneData() { };
friend class CCon::FaceAllocator<ZoneData>;
};
CCon::FaceVector<FaceDataB> faces;
CCon::FaceVector<ZoneData> zoneData;
......@@ -249,6 +262,22 @@ class MZoneBoundary
int exteriorBoundaryVertices(ZoneBoVec &zoneBoVec);
//--Memory management
static void preInit()
{
CCon::FaceVector<typename GlobalVertexData<FaceT>::FaceDataB>
::init_memory();
CCon::FaceVector<typename GlobalVertexData<FaceT>::ZoneData>::init_memory();
}
static void postDestroy()
{
CCon::FaceVector<typename GlobalVertexData<FaceT>::FaceDataB>
::release_memory();
CCon::FaceVector<typename GlobalVertexData<FaceT>::ZoneData>
::release_memory();
}
/*==============================================================================
* Member data
......@@ -263,4 +292,5 @@ private:
};
#endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment