From 6fd810bfdca6f2a47cecac008c24cccf6281d292 Mon Sep 17 00:00:00 2001 From: Wolfgang Bangerth Date: Fri, 30 Mar 2001 08:19:01 +0000 Subject: [PATCH] Make GrowingVectorMemory thread-safe. git-svn-id: https://svn.dealii.org/trunk@4347 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/lac/include/lac/vector_memory.h | 42 +++++++++++++++++++++---- 1 file changed, 36 insertions(+), 6 deletions(-) diff --git a/deal.II/lac/include/lac/vector_memory.h b/deal.II/lac/include/lac/vector_memory.h index 787ce13ce9..a70c7a7290 100644 --- a/deal.II/lac/include/lac/vector_memory.h +++ b/deal.II/lac/include/lac/vector_memory.h @@ -16,6 +16,7 @@ #include #include +#include #include #include @@ -109,7 +110,6 @@ class PrimitiveVectorMemory : public VectorMemory * * @author Guido Kanschat, 1999 */ -//TODO:[GK,WB] GrowingVectorMemory is not thread-safe. use a mutex to synchronise template > class GrowingVectorMemory : public VectorMemory { @@ -120,7 +120,7 @@ class GrowingVectorMemory : public VectorMemory * preallocate a certain number * of vectors. */ - GrowingVectorMemory(unsigned int initial_size = 0); + GrowingVectorMemory (const unsigned int initial_size = 0); /** * Destructor. @@ -144,7 +144,8 @@ class GrowingVectorMemory : public VectorMemory * Return a vector into the pool * for later use. */ - virtual void free(const Vector*); + virtual void free (const Vector*); + private: /** * Type to enter into the @@ -153,7 +154,7 @@ class GrowingVectorMemory : public VectorMemory * vector is used, second the * vector itself. */ - typedef typename std::pair entry_type; + typedef typename std::pair entry_type; /** * Array of allocated vectors. @@ -164,9 +165,17 @@ class GrowingVectorMemory : public VectorMemory * Overall number of allocations. */ unsigned int n_alloc; + + /** + * Mutex to synchronise access to + * internal data of this object + * from multiple threads. + */ + Threads::ThreadMutex mutex; }; + /* --------------------- inline functions ---------------------- */ @@ -174,14 +183,18 @@ template GrowingVectorMemory::GrowingVectorMemory(const unsigned int initial_size) : pool(initial_size) { + mutex.acquire (); for (typename std::vector::iterator i=pool.begin(); i != pool.end(); ++i) { i->first = false; i->second = new Vector; - } + }; + + // no vectors yet claimed n_alloc = 0; + mutex.release (); } @@ -189,6 +202,11 @@ GrowingVectorMemory::GrowingVectorMemory(const unsigned int initial_size template GrowingVectorMemory::~GrowingVectorMemory() { + mutex.acquire (); + + // deallocate all vectors and count + // number of vectors that is still + // claimed by other users unsigned int n = 0; for (typename std::vector::iterator i=pool.begin(); i != pool.end(); @@ -202,9 +220,13 @@ GrowingVectorMemory::~GrowingVectorMemory() << n_alloc << std::endl; deallog << "GrowingVectorMemory:Maximum allocated vectors: " << pool.size() << std::endl; + pool.clear (); + mutex.release (); + + // write out warning if memory leak if (n!=0) deallog << "GrowingVectorMemory:Vectors not deallocated: " - << n << " Memory leak!" << std::endl; + << n << ". Memory leak!" << std::endl; } @@ -213,6 +235,7 @@ template Vector* GrowingVectorMemory::alloc() { + mutex.acquire (); ++n_alloc; for (typename std::vector::iterator i=pool.begin(); i != pool.end(); @@ -221,6 +244,7 @@ GrowingVectorMemory::alloc() if (i->first == false) { i->first = true; + mutex.release (); return (i->second); } } @@ -228,6 +252,8 @@ GrowingVectorMemory::alloc() t.first = true; t.second = new Vector; pool.push_back(t); + mutex.release (); + return t.second; } @@ -237,14 +263,18 @@ template void GrowingVectorMemory::free(const Vector* const v) { + mutex.acquire (); for (typename std::vector::iterator i=pool.begin();i != pool.end() ;++i) { if (v == (i->second)) { i->first = false; + mutex.release (); return; } } + mutex.release (); + Assert(false, typename VectorMemory::ExcNotAllocatedHere()); } -- 2.39.5