From c2e928c4a74ab252a42ceddb5a5aaab27bd97bea Mon Sep 17 00:00:00 2001 From: maier Date: Wed, 17 Apr 2013 22:51:50 +0000 Subject: [PATCH] Use tbb's thread local storage for logstream. This resolves a space leak with the stored ostringstreams git-svn-id: https://svn.dealii.org/trunk@29321 0785d39b-7218-0410-832d-ea1e28bc413d --- deal.II/include/deal.II/base/logstream.h | 24 ++++++++------- deal.II/source/base/logstream.cc | 39 ++---------------------- 2 files changed, 15 insertions(+), 48 deletions(-) diff --git a/deal.II/include/deal.II/base/logstream.h b/deal.II/include/deal.II/base/logstream.h index 2ef7be3fda..d697ac0386 100644 --- a/deal.II/include/deal.II/base/logstream.h +++ b/deal.II/include/deal.II/base/logstream.h @@ -13,9 +13,10 @@ #define __deal2__logstream_h #include -#include #include +#include #include +#include #include #include @@ -32,6 +33,7 @@ struct tms }; #endif + DEAL_II_NAMESPACE_OPEN /** @@ -53,7 +55,7 @@ DEAL_II_NAMESPACE_OPEN * * Before entering a new phase of your program, e.g. a new loop, * a new prefix can be set via LogStream::Prefix p("loopname");. - * The destructor of the prefix will pop the prefix text from the stack. + * The destructor of the prefix will pop the prefix text from the stack. * * Writes via the << operator, * deallog << "This is a log notice"; will be buffered thread @@ -123,7 +125,7 @@ public: * the variable is destroyed. */ Prefix(const std::string &text, - LogStream &stream); + LogStream &stream); /** * Remove the prefix associated with this variable. @@ -488,17 +490,17 @@ private: * function will return the correct internal ostringstream buffer for * operater<<. */ - std::ostringstream &get_stream(); - - /** - * Type of the stream map - */ - typedef std::map > stream_map_type; + std::ostringstream &get_stream() + { + outstreams.get().setf(std::ios::showpoint | std::ios::left); + return outstreams.get(); + } /** - * We generate a stringstream for every process that sends log messages. + * We use tbb's thread local storage facility to generate a stringstream + * for every thread that sends log messages. */ - stream_map_type outstreams; + Threads::ThreadLocalStorage outstreams; }; diff --git a/deal.II/source/base/logstream.cc b/deal.II/source/base/logstream.cc index 0a1cf46faa..bdd3bfe782 100644 --- a/deal.II/source/base/logstream.cc +++ b/deal.II/source/base/logstream.cc @@ -56,6 +56,7 @@ LogStream::LogStream() #if defined(HAVE_UNISTD_H) && defined(HAVE_TIMES) reference_time_val = 1./sysconf(_SC_CLK_TCK) * times(&reference_tms); #endif + } @@ -64,12 +65,7 @@ LogStream::~LogStream() // if there was anything left in the stream that is current to this // thread, make sure we flush it before it gets lost { - const unsigned int id = Threads::this_thread_id(); - if ((outstreams.find(id) != outstreams.end()) - && - (*outstreams[id] != 0) - && - (outstreams[id]->str().length() > 0)) + if (get_stream().str().length() > 0) { // except the situation is not quite that simple. if this object is // the 'deallog' object, then it is destroyed upon exit of the @@ -100,20 +96,6 @@ LogStream::~LogStream() if (old_cerr) std::cerr.rdbuf(old_cerr); - - // on some systems, destroying the outstreams objects of deallog triggers - // some sort of memory corruption, in particular when we also link with - // Trilinos; since this happens at the very end of the program, we take - // the liberty to simply not do it by putting that object into a - // deliberate memory leak and instead destroying an empty object -#ifdef DEAL_II_WITH_TRILINOS - if (this == &deallog) - { - stream_map_type *dummy = new stream_map_type(); - dummy->swap (outstreams); - delete dummy; - } -#endif } @@ -176,23 +158,6 @@ LogStream::operator<< (std::ostream& (*p) (std::ostream &)) } -std::ostringstream & -LogStream::get_stream() -{ -//TODO: use a ThreadLocalStorage object here - Threads::Mutex::ScopedLock lock(log_lock); - const unsigned int id = Threads::this_thread_id(); - - // if necessary allocate a stream object - if (outstreams.find (id) == outstreams.end()) - { - outstreams[id].reset (new std::ostringstream()); - outstreams[id]->setf(std::ios::showpoint | std::ios::left); - } - return *outstreams[id]; -} - - void LogStream::attach(std::ostream &o) { -- 2.39.5