From 769f0fb209eea1e8331e1c7bcd19cf92065eee20 Mon Sep 17 00:00:00 2001 From: Stefen Guzik <guzik2@llnl.gov> Date: Sat, 26 Jul 2008 01:28:23 +0000 Subject: [PATCH] Memory fix --- Geo/CustomContainer.h | 54 ++++++++++++++++++++++++++++++++++++------- Geo/GModelIO_CGNS.cpp | 4 ++++ Geo/MZone.h | 13 +++++++++++ Geo/MZoneBoundary.cpp | 23 ++++++++++++++++++ Geo/MZoneBoundary.h | 30 ++++++++++++++++++++++++ 5 files changed, 116 insertions(+), 8 deletions(-) diff --git a/Geo/CustomContainer.h b/Geo/CustomContainer.h index c1553069fe..5f6ac7d606 100644 --- a/Geo/CustomContainer.h +++ b/Geo/CustomContainer.h @@ -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 diff --git a/Geo/GModelIO_CGNS.cpp b/Geo/GModelIO_CGNS.cpp index 35a8e39510..a17d7113f0 100644 --- a/Geo/GModelIO_CGNS.cpp +++ b/Geo/GModelIO_CGNS.cpp @@ -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; } diff --git a/Geo/MZone.h b/Geo/MZone.h index 0c241057f1..71005908f7 100644 --- a/Geo/MZone.h +++ b/Geo/MZone.h @@ -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. * ******************************************************************************/ @@ -410,7 +413,17 @@ class MZone if(zoneElemConn[iElemType].numElem > 0) ++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 diff --git a/Geo/MZoneBoundary.cpp b/Geo/MZoneBoundary.cpp index 7027f31917..c84a4a2829 100644 --- a/Geo/MZoneBoundary.cpp +++ b/Geo/MZoneBoundary.cpp @@ -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 diff --git a/Geo/MZoneBoundary.h b/Geo/MZoneBoundary.h index 9cdf8ba223..cfc6e737a1 100644 --- a/Geo/MZoneBoundary.h +++ b/Geo/MZoneBoundary.h @@ -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 -- GitLab