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 ...@@ -73,16 +73,13 @@ class Pool
// Constructor // Constructor
Pool(const unsigned _blockSize = 128) Pool(const unsigned _blockSize = 128)
: tailBlock(0), tailElement(0), blockSize(_blockSize) : tailBlock(0), tailElement(0), blockSize(_blockSize), numUsedElement(0)
{ } { }
// Destructor // Destructor
~Pool(){ ~Pool()
while(tailBlock) { {
Block<T> *const block = tailBlock; delete_all_blocks();
tailBlock = block->prev;
delete block;
}
} }
// Get an element // Get an element
...@@ -91,6 +88,7 @@ class Pool ...@@ -91,6 +88,7 @@ class Pool
if(!tailElement) create_block(); if(!tailElement) create_block();
void *const rval = tailElement; void *const rval = tailElement;
tailElement = static_cast<T*>(tailElement->get_pool_prev()); tailElement = static_cast<T*>(tailElement->get_pool_prev());
++numUsedElement;
return rval; return rval;
} }
...@@ -99,6 +97,13 @@ class Pool ...@@ -99,6 +97,13 @@ class Pool
{ {
elem->set_pool_prev(tailElement); elem->set_pool_prev(tailElement);
tailElement = elem; tailElement = elem;
--numUsedElement;
}
// Free memory used by the pool
void free_memory()
{
if(numUsedElement == 0) delete_all_blocks();
} }
private: private:
...@@ -107,6 +112,7 @@ class Pool ...@@ -107,6 +112,7 @@ class Pool
Block<T> *tailBlock; Block<T> *tailBlock;
T *tailElement; T *tailElement;
unsigned blockSize; unsigned blockSize;
unsigned numUsedElement;
// Create a new block // Create a new block
void create_block() void create_block()
...@@ -121,6 +127,16 @@ class Pool ...@@ -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 // Copy and assignment are not permitted
Pool(const Pool&); Pool(const Pool&);
Pool &operator=(const Pool&); Pool &operator=(const Pool&);
...@@ -200,6 +216,7 @@ class Block ...@@ -200,6 +216,7 @@ class Block
* - No per-object data is stored as per normal requirements for allocators. * - No per-object data is stored as per normal requirements for allocators.
* Critical OpenMP sections are defined since multiple threads can access * Critical OpenMP sections are defined since multiple threads can access
* the allocator. * the allocator.
* - If set_offsets is to be used, T must have a default constructor.
* *
*============================================================================*/ *============================================================================*/
...@@ -292,6 +309,15 @@ class FaceAllocator ...@@ -292,6 +309,15 @@ class FaceAllocator
offset16 = f16.get_offset(); 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 // Allocate the array
void allocate(const unsigned short nCapacity, T *&faces) void allocate(const unsigned short nCapacity, T *&faces)
{ {
...@@ -503,6 +529,10 @@ ptrdiff_t FaceAllocator<T>::offset16 = 0; ...@@ -503,6 +529,10 @@ ptrdiff_t FaceAllocator<T>::offset16 = 0;
* - The only way to add elements is by 'push_back' * - The only way to add elements is by 'push_back'
* - Erasing may reorder the elements. * - Erasing may reorder the elements.
* - T must only contain primitive types * - 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> ...@@ -551,9 +581,17 @@ class FaceVector : public FaceAllocator<T>
// Vector size and capacity // Vector size and capacity
unsigned size() const { return _size; } unsigned size() const { return _size; }
unsigned capacity() const { return _capacity; } 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: private:
// Data // Data
......
...@@ -278,12 +278,16 @@ int GModel::writeCGNS(const std::string &name, const int zoneDefinition, ...@@ -278,12 +278,16 @@ int GModel::writeCGNS(const std::string &name, const int zoneDefinition,
switch(meshDim) { switch(meshDim) {
case 2: case 2:
MZone<2>::preInit();
write_CGNS_zones<2>(*this, zoneDefinition, options, scalingFactor, write_CGNS_zones<2>(*this, zoneDefinition, options, scalingFactor,
vectorDim, groups[face], cgIndexFile, cgIndexBase); vectorDim, groups[face], cgIndexFile, cgIndexBase);
MZone<2>::postDestroy();
break; break;
case 3: case 3:
MZone<3>::preInit();
write_CGNS_zones<3>(*this, zoneDefinition, options, scalingFactor, write_CGNS_zones<3>(*this, zoneDefinition, options, scalingFactor,
vectorDim, groups[region], cgIndexFile, cgIndexBase); vectorDim, groups[region], cgIndexFile, cgIndexBase);
MZone<3>::postDestroy();
break; break;
} }
......
...@@ -310,6 +310,9 @@ template <> struct FaceTr<MFace> { ...@@ -310,6 +310,9 @@ template <> struct FaceTr<MFace> {
* ===== * =====
* *
* - explicitly instantiated in 'MZone.cpp' * - 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.
* *
******************************************************************************/ ******************************************************************************/
...@@ -410,7 +413,17 @@ class MZone ...@@ -410,7 +413,17 @@ class MZone
if(zoneElemConn[iElemType].numElem > 0) ++numElemType; if(zoneElemConn[iElemType].numElem > 0) ++numElemType;
return numElemType; 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 * Member data
......
...@@ -892,6 +892,29 @@ int MZoneBoundary<DIM>::exteriorBoundaryVertices ...@@ -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 * Explicit instantiations of class MZoneBoundary
......
...@@ -167,6 +167,9 @@ struct ZoneBoVecSort ...@@ -167,6 +167,9 @@ struct ZoneBoVecSort
* ===== * =====
* *
* - explicitly instantiated in 'MZoneBoundary.cpp' * - 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 ...@@ -203,6 +206,11 @@ class MZoneBoundary
parentFace(bFMapIt->second.parentFace), parentFace(bFMapIt->second.parentFace),
faceIndex(bFMapIt->second.faceIndex), zoneIndex(_zoneIndex) 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 struct ZoneData
{ {
...@@ -211,6 +219,11 @@ class MZoneBoundary ...@@ -211,6 +219,11 @@ class MZoneBoundary
ZoneData(const int _vertexIndex, const int _zoneIndex) ZoneData(const int _vertexIndex, const int _zoneIndex)
: vertexIndex(_vertexIndex), zoneIndex(_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<FaceDataB> faces;
CCon::FaceVector<ZoneData> zoneData; CCon::FaceVector<ZoneData> zoneData;
...@@ -249,6 +262,22 @@ class MZoneBoundary ...@@ -249,6 +262,22 @@ class MZoneBoundary
int exteriorBoundaryVertices(ZoneBoVec &zoneBoVec); 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 * Member data
...@@ -263,4 +292,5 @@ private: ...@@ -263,4 +292,5 @@ private:
}; };
#endif #endif
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment