From: bangerth Date: Tue, 26 Oct 2010 19:43:59 +0000 (+0000) Subject: Move some template functions into the .cc file. There is a problem that in static... X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1159b946fbdad912fd3d6ce20c187f835a19c259;p=dealii-svn.git Move some template functions into the .cc file. There is a problem that in static lib mode, these functions reference a static member variable that is only defined later (though it is declared earlier) and for whatever reason the variable only gets internal linkage, leading to linker errors with static libs. git-svn-id: https://svn.dealii.org/trunk@22506 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/include/deal.II/lac/vector_memory.h b/deal.II/include/deal.II/lac/vector_memory.h index b30a447ab8..0e3619d906 100644 --- a/deal.II/include/deal.II/lac/vector_memory.h +++ b/deal.II/include/deal.II/lac/vector_memory.h @@ -248,19 +248,6 @@ class PrimitiveVectorMemory : public VectorMemory * since they are reused, this should be of no concern. Additionally, * the destructor of the Pool warns about memory leaks. * - * @note Instantiations for this class are provided for the types - * Vector and BlockVector with number types float, - * double, long double, @@>, - * @@> and @@>. In order to generate additional instances, it is - * sufficient to define the Pool variable somewhere by - * @code - * #include - * - * template GrowingVectorMemory::Pool - * GrowingVectorMemory::pool; - * @endcode - * * @author Guido Kanschat, 1999, 2007 */ template > @@ -354,13 +341,27 @@ class GrowingVectorMemory : public VectorMemory */ struct Pool { -/// Standard constructor creating an empty pool + /** + * Standard constructor + * creating an empty pool + */ Pool(); -/// Destructor. Frees memory and warns about memory leaks + /** + * Destructor. Frees memory + * and warns about memory + * leaks + */ ~Pool(); -/// Create data vector; does nothing after first initialization + /** + * Create data vector; does + * nothing after first + * initialization + */ void initialize(const unsigned int size); -/// Pointer to the storage object + /** + * Pointer to the storage + * object + */ std::vector* data; }; @@ -447,185 +448,6 @@ VECTOR * VectorMemory::Pointer::operator -> () const } -template -inline -GrowingVectorMemory::Pool::Pool() - : - data(0) -{} - - - -template -inline -GrowingVectorMemory::Pool::~Pool() -{ - // Nothing to do if memory was unused. - if (data == 0) return; - - // First, delete all remaining - // vectors. Actually, there should - // be none, if there is no memory - // leak - unsigned int n=0; - for (typename std::vector::iterator i=data->begin(); - i != data->end(); - ++i) - { - if (i->first == true) - ++n; - delete i->second; - } - delete data; -} - - -template -inline -void -GrowingVectorMemory::Pool::initialize(const unsigned int size) -{ - if (data == 0) - { - data = new std::vector(size); - - for (typename std::vector::iterator i= data->begin(); - i != data->end(); - ++i) - { - i->first = false; - i->second = new VECTOR; - } - } -} - - -template -inline -GrowingVectorMemory::GrowingVectorMemory (const unsigned int initial_size, - const bool log_statistics) - - : - total_alloc(0), - current_alloc(0), - log_statistics(log_statistics) -{ - Threads::ThreadMutex::ScopedLock lock(mutex); - pool.initialize(initial_size); -} - - -template -inline -GrowingVectorMemory::~GrowingVectorMemory() -{ - AssertThrow(current_alloc == 0, - StandardExceptions::ExcMemoryLeak(current_alloc)); - if (log_statistics) - { - deallog << "GrowingVectorMemory:Overall allocated vectors: " - << total_alloc << std::endl; - deallog << "GrowingVectorMemory:Maximum allocated vectors: " - << pool.data->size() << std::endl; - } -} - - - -template -inline -VECTOR * -GrowingVectorMemory::alloc () -{ - Threads::ThreadMutex::ScopedLock lock(mutex); - ++total_alloc; - ++current_alloc; - // see if there is a free vector - // available in our list - for (typename std::vector::iterator i=pool.data->begin(); - i != pool.data->end(); ++i) - { - if (i->first == false) - { - i->first = true; - return (i->second); - } - } - - // no free vector found, so let's - // just allocate a new one - const entry_type t (true, new VECTOR); - pool.data->push_back(t); - - return t.second; -} - - - -template -inline -void -GrowingVectorMemory::free(const VECTOR* const v) -{ - Threads::ThreadMutex::ScopedLock lock(mutex); - for (typename std::vector::iterator i=pool.data->begin(); - i != pool.data->end(); ++i) - { - if (v == (i->second)) - { - i->first = false; - --current_alloc; - return; - } - } - Assert(false, typename VectorMemory::ExcNotAllocatedHere()); -} - - - -template -inline -void -GrowingVectorMemory::release_unused_memory () -{ - Threads::ThreadMutex::ScopedLock lock(mutex); - - std::vector new_data; - - if (pool.data != 0) - { - const typename std::vector::const_iterator - end = pool.data->end(); - for (typename std::vector::const_iterator - i = pool.data->begin(); i != end ; ++i) - if (i->first == false) - delete i->second; - else - new_data.push_back (*i); - - *pool.data = new_data; - } -} - - - -template -inline -unsigned int -GrowingVectorMemory::memory_consumption () const -{ - Threads::ThreadMutex::ScopedLock lock(mutex); - - unsigned int result = sizeof (*this); - const typename std::vector::const_iterator - end = pool.data->end(); - for (typename std::vector::const_iterator - i = pool.data->begin(); i != end ; ++i) - result += sizeof (*i) + i->second->memory_consumption(); - - return result; -} - #endif // DOXYGEN DEAL_II_NAMESPACE_CLOSE diff --git a/deal.II/source/lac/vector_memory.cc b/deal.II/source/lac/vector_memory.cc index 0fbbb45406..267dca6fb8 100644 --- a/deal.II/source/lac/vector_memory.cc +++ b/deal.II/source/lac/vector_memory.cc @@ -2,7 +2,7 @@ // $Id$ // Version: $Name$ // -// Copyright (C) 2007, 2008 by the deal.II authors +// Copyright (C) 2007, 2008, 2010 by the deal.II authors // // This file is subject to QPL and may not be distributed // without copyright and license information. Please refer @@ -31,10 +31,190 @@ typename GrowingVectorMemory::Pool GrowingVectorMemory::pool; template Threads::ThreadMutex GrowingVectorMemory::mutex; +template +inline +GrowingVectorMemory::Pool::Pool() + : + data(0) +{} + + + +template +inline +GrowingVectorMemory::Pool::~Pool() +{ + // Nothing to do if memory was unused. + if (data == 0) return; + + // First, delete all remaining + // vectors. Actually, there should + // be none, if there is no memory + // leak + unsigned int n=0; + for (typename std::vector::iterator i=data->begin(); + i != data->end(); + ++i) + { + if (i->first == true) + ++n; + delete i->second; + } + delete data; +} + + +template +inline +void +GrowingVectorMemory::Pool::initialize(const unsigned int size) +{ + if (data == 0) + { + data = new std::vector(size); + + for (typename std::vector::iterator i= data->begin(); + i != data->end(); + ++i) + { + i->first = false; + i->second = new VECTOR; + } + } +} + + +template +inline +GrowingVectorMemory::GrowingVectorMemory (const unsigned int initial_size, + const bool log_statistics) + + : + total_alloc(0), + current_alloc(0), + log_statistics(log_statistics) +{ + Threads::ThreadMutex::ScopedLock lock(mutex); + pool.initialize(initial_size); +} + + +template +inline +GrowingVectorMemory::~GrowingVectorMemory() +{ + AssertThrow(current_alloc == 0, + StandardExceptions::ExcMemoryLeak(current_alloc)); + if (log_statistics) + { + deallog << "GrowingVectorMemory:Overall allocated vectors: " + << total_alloc << std::endl; + deallog << "GrowingVectorMemory:Maximum allocated vectors: " + << pool.data->size() << std::endl; + } +} + + + +template +inline +VECTOR * +GrowingVectorMemory::alloc () +{ + Threads::ThreadMutex::ScopedLock lock(mutex); + ++total_alloc; + ++current_alloc; + // see if there is a free vector + // available in our list + for (typename std::vector::iterator i=pool.data->begin(); + i != pool.data->end(); ++i) + { + if (i->first == false) + { + i->first = true; + return (i->second); + } + } + + // no free vector found, so let's + // just allocate a new one + const entry_type t (true, new VECTOR); + pool.data->push_back(t); + + return t.second; +} + + + +template +inline +void +GrowingVectorMemory::free(const VECTOR* const v) +{ + Threads::ThreadMutex::ScopedLock lock(mutex); + for (typename std::vector::iterator i=pool.data->begin(); + i != pool.data->end(); ++i) + { + if (v == (i->second)) + { + i->first = false; + --current_alloc; + return; + } + } + Assert(false, typename VectorMemory::ExcNotAllocatedHere()); +} + + + +template +inline +void +GrowingVectorMemory::release_unused_memory () +{ + Threads::ThreadMutex::ScopedLock lock(mutex); + + std::vector new_data; + + if (pool.data != 0) + { + const typename std::vector::const_iterator + end = pool.data->end(); + for (typename std::vector::const_iterator + i = pool.data->begin(); i != end ; ++i) + if (i->first == false) + delete i->second; + else + new_data.push_back (*i); + + *pool.data = new_data; + } +} + + + +template +inline +unsigned int +GrowingVectorMemory::memory_consumption () const +{ + Threads::ThreadMutex::ScopedLock lock(mutex); + + unsigned int result = sizeof (*this); + const typename std::vector::const_iterator + end = pool.data->end(); + for (typename std::vector::const_iterator + i = pool.data->begin(); i != end ; ++i) + result += sizeof (*i) + i->second->memory_consumption(); + + return result; +} + // ------------------------------------------------------------- // explicit instantiations + #include "vector_memory.inst" //TODO: Fold this into the list of vectors to be instantiated