]> https://gitweb.dealii.org/ - dealii-svn.git/commitdiff
Use tbb's thread local storage for logstream. This resolves a space leak with the...
authormaier <maier@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 17 Apr 2013 22:51:50 +0000 (22:51 +0000)
committermaier <maier@0785d39b-7218-0410-832d-ea1e28bc413d>
Wed, 17 Apr 2013 22:51:50 +0000 (22:51 +0000)
git-svn-id: https://svn.dealii.org/trunk@29321 0785d39b-7218-0410-832d-ea1e28bc413d

deal.II/include/deal.II/base/logstream.h
deal.II/source/base/logstream.cc

index 2ef7be3fdad427adbed0b361e8148f580c721a2f..d697ac038651a97ee30df425f13fc639261415f7 100644 (file)
 #define __deal2__logstream_h
 
 #include <deal.II/base/config.h>
-#include <deal.II/base/smartpointer.h>
 #include <deal.II/base/exceptions.h>
+#include <deal.II/base/smartpointer.h>
 #include <deal.II/base/std_cxx1x/shared_ptr.h>
+#include <deal.II/base/thread_local_storage.h>
 
 #include <string>
 #include <stack>
@@ -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 <tt>LogStream::Prefix p("loopname");</tt>.
- * 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 <tt>&lt;&lt;</tt> operator,
  * <tt> deallog << "This is a log notice";</tt> 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<unsigned int, std_cxx1x::shared_ptr<std::ostringstream> > 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<std::ostringstream> outstreams;
 
 };
 
index 0a1cf46faabdf48db70b49c07feee6b02264e9c6..bdd3bfe782d96f207dbae93de014aaeddfb1eaaf 100644 (file)
@@ -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)
 {

In the beginning the Universe was created. This has made a lot of people very angry and has been widely regarded as a bad move.

Douglas Adams


Typeset in Trocchi and Trocchi Bold Sans Serif.