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

Memory fix

parent 592008ee
Branches
Tags
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